From 8f27e65bddd7d4b8515ce620fb485fdd78fcdf89 Mon Sep 17 00:00:00 2001 From: Constantin Jucovschi Date: Fri, 24 Apr 2009 07:20:22 -0400 Subject: Initial commit --- rasdl/Makefile.am | 70 ++++ rasdl/alloca.cc | 530 +++++++++++++++++++++++++ rasdl/lex.ll | 240 ++++++++++++ rasdl/odl.yy | 631 ++++++++++++++++++++++++++++++ rasdl/parse.cc | 996 +++++++++++++++++++++++++++++++++++++++++++++++ rasdl/parse.hh | 748 +++++++++++++++++++++++++++++++++++ rasdl/rasdl.awk | 11 + rasdl/rasdl.cc | 724 ++++++++++++++++++++++++++++++++++ rasdl/rasdl_error.cc | 124 ++++++ rasdl/rasdl_error.hh | 77 ++++ rasdl/rasdlgrammar.html | 27 ++ rasdl/symbtbl.cc | 305 +++++++++++++++ rasdl/symbtbl.hh | 196 ++++++++++ rasdl/template_inst.hh | 83 ++++ rasdl/test/Makefile | 78 ++++ rasdl/test/basictypes.dl | 157 ++++++++ rasdl/test/rasdl_test.sh | 103 +++++ rasdl/test/test_rasdl.cc | 80 ++++ rasdl/yparse.hh | 59 +++ 19 files changed, 5239 insertions(+) create mode 100644 rasdl/Makefile.am create mode 100644 rasdl/alloca.cc create mode 100644 rasdl/lex.ll create mode 100644 rasdl/odl.yy create mode 100644 rasdl/parse.cc create mode 100644 rasdl/parse.hh create mode 100644 rasdl/rasdl.awk create mode 100644 rasdl/rasdl.cc create mode 100644 rasdl/rasdl_error.cc create mode 100644 rasdl/rasdl_error.hh create mode 100644 rasdl/rasdlgrammar.html create mode 100644 rasdl/symbtbl.cc create mode 100644 rasdl/symbtbl.hh create mode 100644 rasdl/template_inst.hh create mode 100644 rasdl/test/Makefile create mode 100644 rasdl/test/basictypes.dl create mode 100644 rasdl/test/rasdl_test.sh create mode 100644 rasdl/test/test_rasdl.cc create mode 100644 rasdl/yparse.hh (limited to 'rasdl') diff --git a/rasdl/Makefile.am b/rasdl/Makefile.am new file mode 100644 index 0000000..87f26a2 --- /dev/null +++ b/rasdl/Makefile.am @@ -0,0 +1,70 @@ +# -*-Makefile-*- (for Emacs) +# +# This file is part of rasdaman community. +# +# Rasdaman community is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Rasdaman community is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with rasdaman community. If not, see . +# +# Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann / +# rasdaman GmbH. +# +# For more information please see +# or contact Peter Baumann via . +# +# MAKEFILE FOR: +# module rasdl +# +# COMMENTS: +# For static linking you have to do first: setenv STATIC_LIBS=true +# +################################################################## + +AM_LFLAGS=-I +YACC = bison +AM_YFLAGS=-d -y +AM_CXXFLAGS=@BASEDBCXXFLAGS@ +AM_LDFLAGS=@BASEDBLDFLAGS@ + +bin_PROGRAMS=rasdl +rasdl_SOURCES=lex.ll odl.yy parse.cc parse.hh symbtbl.cc symbtbl.hh \ + alloca.cc rasdl.cc rasdl_error.cc rasdl_error.hh \ + template_inst.hh yparse.hh \ + ../mymalloc/mymalloc.h ../mymalloc/mymalloc_svc.cc +rasdl_LDADD = ../reladminif/libreladminif.a ../relmddif/librelmddif.a \ + ../relstorageif/librelstorageif.a ../relindexif/librelindexif.a \ + ../relcatalogif/librelcatalogif.a ../relblobif/librelblobif.a \ + ../indexmgr/libindexmgr.a ../catalogmgr/libcatalogmgr.a \ + ../storagemgr/libstoragemgr.a ../tilemgr/libtilemgr.a \ + ../compression/libcompression.a ../commline/libcommline.a ../raslib/libraslib.a \ + ../conversion/libconversion.a + +BUILT_SOURCES=lex.cc odl.cc odl.h +CLEANFILES=lex.cc odl.cc odl.h + +SUBDIRS=../reladminif ../relmddif ../relstorageif ../relindexif ../relcatalogif \ + ../relblobif ../indexmgr ../catalogmgr ../storagemgr ../tilemgr \ + ../compression ../raslib ../conversion ../commline + +$(RECURSIVE_CLEAN_TARGETS): + @$(MAKE) $(AM_MAKEFLAGS) `echo $@ | sed s/-recursive/-am/` + +#.PHONY : doc +#doc: +# -rm $(DOCDIR)/* +# gawk -f rasdl.awk odl.y > odl.grammar +# head -n 16 rasdlgrammar.html > $(DOCDIR)/rasdlgrammar.html +# cat odl.grammar >> $(DOCDIR)/rasdlgrammar.html +# tail -n 8 rasdlgrammar.html >> $(DOCDIR)/rasdlgrammar.html +# $(DOCXX) -d $(DOCDIR) *.hh +# chmod 664 $(DOCDIR)/* $(DOCDIR)/.??* + diff --git a/rasdl/alloca.cc b/rasdl/alloca.cc new file mode 100644 index 0000000..e6fb8fa --- /dev/null +++ b/rasdl/alloca.cc @@ -0,0 +1,530 @@ +/* +* This file is part of rasdaman community. +* +* Rasdaman community is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* Rasdaman community is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with rasdaman community. If not, see . +* +* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann / +rasdaman GmbH. +* +* For more information please see +* or contact Peter Baumann via . +*/ +#include "mymalloc/mymalloc.h" +/* alloca.c -- allocate automatically reclaimed memory + (Mostly) portable public-domain implementation -- D A Gwyn + + This implementation of the PWB library alloca function, + which is used to allocate space off the run-time stack so + that it is automatically reclaimed upon procedure exit, + was inspired by discussions with J. Q. Johnson of Cornell. + J.Otto Tennant contributed the Cray support. + + There are some preprocessor constants that can + be defined when compiling for your specific system, for + improved efficiency; however, the defaults should be okay. + + The general concept of this implementation is to keep + track of all alloca-allocated blocks, and reclaim any + that are found to be deeper in the stack than the current + invocation. This heuristic does not reclaim storage as + soon as it becomes invalid, but it will do so eventually. + + As a special case, alloca(0) reclaims storage without + allocating any. It is a good idea to use alloca(0) in + your main control loop, etc. to force garbage collection. */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifdef HAVE_STRING_H +#include +#endif +#ifdef HAVE_STDLIB_H +#include +#endif + +#ifdef emacs +#include "blockinput.h" +#endif + +/* If compiling with GCC 2, this file's not needed. */ +#if !defined (__GNUC__) || __GNUC__ < 2 +#ifndef SOLARIS +/* If someone has defined alloca as a macro, + there must be some other way alloca is supposed to work. */ +#ifndef alloca + +#ifdef emacs +#ifdef static +/* actually, only want this if static is defined as "" + -- this is for usg, in which emacs must undefine static + in order to make unexec workable + */ +#ifndef STACK_DIRECTION +you +lose +-- must know STACK_DIRECTION at compile-time +#endif /* STACK_DIRECTION undefined */ +#endif /* static */ +#endif /* emacs */ + +/* If your stack is a linked list of frames, you have to + provide an "address metric" ADDRESS_FUNCTION macro. */ + +#if defined (CRAY) && defined (CRAY_STACKSEG_END) +long i00afunc (); +#define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg)) +#else +#define ADDRESS_FUNCTION(arg) &(arg) +#endif + +#if __STDC__ +typedef void *pointer; +#else +typedef char *pointer; +#endif + +#ifndef NULL +#define NULL 0 +#endif + +/* Different portions of Emacs need to call different versions of + malloc. The Emacs executable needs alloca to call xmalloc, because + ordinary malloc isn't protected from input signals. On the other + hand, the utilities in lib-src need alloca to call malloc; some of + them are very simple, and don't have an xmalloc routine. + + Non-Emacs programs expect this to call use xmalloc. + + Callers below should use malloc. */ + +/* +#ifndef emacs +#define malloc xmalloc +#endif +*/ +extern pointer mymalloc (); + +/* Define STACK_DIRECTION if you know the direction of stack + growth for your system; otherwise it will be automatically + deduced at run-time. + + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown */ + +#ifndef STACK_DIRECTION +#define STACK_DIRECTION 0 /* Direction unknown. */ +#endif + +#if STACK_DIRECTION != 0 + +#define STACK_DIR STACK_DIRECTION /* Known at compile-time. */ + +#else /* STACK_DIRECTION == 0; need run-time code. */ + +static int stack_dir; /* 1 or -1 once known. */ +#define STACK_DIR stack_dir + +static void +find_stack_direction () +{ + static char *addr = NULL; /* Address of first `dummy', once known. */ + auto char dummy; /* To get stack address. */ + + if (addr == NULL) + { /* Initial entry. */ + addr = ADDRESS_FUNCTION (dummy); + + find_stack_direction (); /* Recurse once. */ + } + else + { + /* Second entry. */ + if (ADDRESS_FUNCTION (dummy) > addr) + stack_dir = 1; /* Stack grew upward. */ + else + stack_dir = -1; /* Stack grew downward. */ + } +} + +#endif /* STACK_DIRECTION == 0 */ + +/* An "alloca header" is used to: + (a) chain together all alloca'ed blocks; + (b) keep track of stack depth. + + It is very important that sizeof(header) agree with malloc + alignment chunk size. The following default should work okay. */ + +#ifndef ALIGN_SIZE +#define ALIGN_SIZE sizeof(double) +#endif + +typedef union hdr +{ + char align[ALIGN_SIZE]; /* To force sizeof(header). */ + struct + { + union hdr *next; /* For chaining headers. */ + char *deep; /* For stack depth measure. */ + } h; +} header; + +static header *last_alloca_header = NULL; /* -> last alloca header. */ + +/* Return a pointer to at least SIZE bytes of storage, + which will be automatically reclaimed upon exit from + the procedure that called alloca. Originally, this space + was supposed to be taken from the current stack frame of the + caller, but that method cannot be made to work for some + implementations of C, for example under Gould's UTX/32. */ + +pointer +alloca (size) + unsigned size; +{ + auto char probe; /* Probes stack depth: */ + register char *depth = ADDRESS_FUNCTION (probe); + +#if STACK_DIRECTION == 0 + if (STACK_DIR == 0) /* Unknown growth direction. */ + find_stack_direction (); +#endif + + /* Reclaim garbage, defined as all alloca'd storage that + was allocated from deeper in the stack than currently. */ + + { + register header *hp; /* Traverses linked list. */ + +#ifdef emacs + BLOCK_INPUT; +#endif + + for (hp = last_alloca_header; hp != NULL;) + if ((STACK_DIR > 0 && hp->h.deep > depth) + || (STACK_DIR < 0 && hp->h.deep < depth)) + { + register header *np = hp->h.next; + + free ((pointer) hp); /* Collect garbage. */ + + hp = np; /* -> next header. */ + } + else + break; /* Rest are not deeper. */ + + last_alloca_header = hp; /* -> last valid storage. */ + +#ifdef emacs + UNBLOCK_INPUT; +#endif + } + + if (size == 0) + return NULL; /* No allocation required. */ + + /* Allocate combined header + user data storage. */ + + { + register pointer new = mymalloc (sizeof (header) + size); + /* Address of header. */ + + if (new == 0) + abort(); + + ((header *) new)->h.next = last_alloca_header; + ((header *) new)->h.deep = depth; + + last_alloca_header = (header *) new; + + /* User storage begins just after header. */ + + return (pointer) ((char *) new + sizeof (header)); + } +} + +#if defined (CRAY) && defined (CRAY_STACKSEG_END) + +#ifdef DEBUG_I00AFUNC +#include +#endif + +#ifndef CRAY_STACK +#define CRAY_STACK +#ifndef CRAY2 +/* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */ +struct stack_control_header + { + long shgrow:32; /* Number of times stack has grown. */ + long shaseg:32; /* Size of increments to stack. */ + long shhwm:32; /* High water mark of stack. */ + long shsize:32; /* Current size of stack (all segments). */ + }; + +/* The stack segment linkage control information occurs at + the high-address end of a stack segment. (The stack + grows from low addresses to high addresses.) The initial + part of the stack segment linkage control information is + 0200 (octal) words. This provides for register storage + for the routine which overflows the stack. */ + +struct stack_segment_linkage + { + long ss[0200]; /* 0200 overflow words. */ + long sssize:32; /* Number of words in this segment. */ + long ssbase:32; /* Offset to stack base. */ + long:32; + long sspseg:32; /* Offset to linkage control of previous + segment of stack. */ + long:32; + long sstcpt:32; /* Pointer to task common address block. */ + long sscsnm; /* Private control structure number for + microtasking. */ + long ssusr1; /* Reserved for user. */ + long ssusr2; /* Reserved for user. */ + long sstpid; /* Process ID for pid based multi-tasking. */ + long ssgvup; /* Pointer to multitasking thread giveup. */ + long sscray[7]; /* Reserved for Cray Research. */ + long ssa0; + long ssa1; + long ssa2; + long ssa3; + long ssa4; + long ssa5; + long ssa6; + long ssa7; + long sss0; + long sss1; + long sss2; + long sss3; + long sss4; + long sss5; + long sss6; + long sss7; + }; + +#else /* CRAY2 */ +/* The following structure defines the vector of words + returned by the STKSTAT library routine. */ +struct stk_stat + { + long now; /* Current total stack size. */ + long maxc; /* Amount of contiguous space which would + be required to satisfy the maximum + stack demand to date. */ + long high_water; /* Stack high-water mark. */ + long overflows; /* Number of stack overflow ($STKOFEN) calls. */ + long hits; /* Number of internal buffer hits. */ + long extends; /* Number of block extensions. */ + long stko_mallocs; /* Block allocations by $STKOFEN. */ + long underflows; /* Number of stack underflow calls ($STKRETN). */ + long stko_free; /* Number of deallocations by $STKRETN. */ + long stkm_free; /* Number of deallocations by $STKMRET. */ + long segments; /* Current number of stack segments. */ + long maxs; /* Maximum number of stack segments so far. */ + long pad_size; /* Stack pad size. */ + long current_address; /* Current stack segment address. */ + long current_size; /* Current stack segment size. This + number is actually corrupted by STKSTAT to + include the fifteen word trailer area. */ + long initial_address; /* Address of initial segment. */ + long initial_size; /* Size of initial segment. */ + }; + +/* The following structure describes the data structure which trails + any stack segment. I think that the description in 'asdef' is + out of date. I only describe the parts that I am sure about. */ + +struct stk_trailer + { + long this_address; /* Address of this block. */ + long this_size; /* Size of this block (does not include + this trailer). */ + long unknown2; + long unknown3; + long link; /* Address of trailer block of previous + segment. */ + long unknown5; + long unknown6; + long unknown7; + long unknown8; + long unknown9; + long unknown10; + long unknown11; + long unknown12; + long unknown13; + long unknown14; + }; + +#endif /* CRAY2 */ +#endif /* not CRAY_STACK */ + +#ifdef CRAY2 +/* Determine a "stack measure" for an arbitrary ADDRESS. + I doubt that "lint" will like this much. */ + +static long +i00afunc (long *address) +{ + struct stk_stat status; + struct stk_trailer *trailer; + long *block, size; + long result = 0; + + /* We want to iterate through all of the segments. The first + step is to get the stack status structure. We could do this + more quickly and more directly, perhaps, by referencing the + $LM00 common block, but I know that this works. */ + + STKSTAT (&status); + + /* Set up the iteration. */ + + trailer = (struct stk_trailer *) (status.current_address + + status.current_size + - 15); + + /* There must be at least one stack segment. Therefore it is + a fatal error if "trailer" is null. */ + + if (trailer == 0) + abort (); + + /* Discard segments that do not contain our argument address. */ + + while (trailer != 0) + { + block = (long *) trailer->this_address; + size = trailer->this_size; + if (block == 0 || size == 0) + abort (); + trailer = (struct stk_trailer *) trailer->link; + if ((block <= address) && (address < (block + size))) + break; + } + + /* Set the result to the offset in this segment and add the sizes + of all predecessor segments. */ + + result = address - block; + + if (trailer == 0) + { + return result; + } + + do + { + if (trailer->this_size <= 0) + abort (); + result += trailer->this_size; + trailer = (struct stk_trailer *) trailer->link; + } + while (trailer != 0); + + /* We are done. Note that if you present a bogus address (one + not in any segment), you will get a different number back, formed + from subtracting the address of the first block. This is probably + not what you want. */ + + return (result); +} + +#else /* not CRAY2 */ +/* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP. + Determine the number of the cell within the stack, + given the address of the cell. The purpose of this + routine is to linearize, in some sense, stack addresses + for alloca. */ + +static long +i00afunc (long address) +{ + long stkl = 0; + + long size, pseg, this_segment, stack; + long result = 0; + + struct stack_segment_linkage *ssptr; + + /* Register B67 contains the address of the end of the + current stack segment. If you (as a subprogram) store + your registers on the stack and find that you are past + the contents of B67, you have overflowed the segment. + + B67 also points to the stack segment linkage control + area, which is what we are really interested in. */ + + stkl = CRAY_STACKSEG_END (); + ssptr = (struct stack_segment_linkage *) stkl; + + /* If one subtracts 'size' from the end of the segment, + one has the address of the first word of the segment. + + If this is not the first segment, 'pseg' will be + nonzero. */ + + pseg = ssptr->sspseg; + size = ssptr->sssize; + + this_segment = stkl - size; + + /* It is possible that calling this routine itself caused + a stack overflow. Discard stack segments which do not + contain the target address. */ + + while (!(this_segment <= address && address <= stkl)) + { +#ifdef DEBUG_I00AFUNC + fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl); +#endif + if (pseg == 0) + break; + stkl = stkl - pseg; + ssptr = (struct stack_segment_linkage *) stkl; + size = ssptr->sssize; + pseg = ssptr->sspseg; + this_segment = stkl - size; + } + + result = address - this_segment; + + /* If you subtract pseg from the current end of the stack, + you get the address of the previous stack segment's end. + This seems a little convoluted to me, but I'll bet you save + a cycle somewhere. */ + + while (pseg != 0) + { +#ifdef DEBUG_I00AFUNC + fprintf (stderr, "%011o %011o\n", pseg, size); +#endif + stkl = stkl - pseg; + ssptr = (struct stack_segment_linkage *) stkl; + size = ssptr->sssize; + pseg = ssptr->sspseg; + result += size; + } + return (result); +} + +#endif /* not CRAY2 */ +#endif /* CRAY */ + +#endif /* no alloca */ +#endif /*SOLARIS*/ +#endif /* not GCC version 2 */ diff --git a/rasdl/lex.ll b/rasdl/lex.ll new file mode 100644 index 0000000..ddf36e4 --- /dev/null +++ b/rasdl/lex.ll @@ -0,0 +1,240 @@ +%a 3000 +%p 2700 +%o 5000 + +%{ + +/* +* This file is part of rasdaman community. +* +* Rasdaman community is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* Rasdaman community is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with rasdaman community. If not, see . +* +* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann / +rasdaman GmbH. +* +* For more information please see +* or contact Peter Baumann via . +*/ +//============================================================================== +// +// NAME: ODL.lex +// +// +// DESCRIPTION : Pattern description for lexical analyzer generators. +// +//============================================================================== + +#include +#include + +#include "parse.hh" +#include "yparse.hh" + +#include "odl.h" + +/* for error output */ +long lineNumber = 1; /* number of line in current file */ +int columnNumber= 1; /* number of column in current line */ +int commentLevel= 0; /* Level of nested Comments */ + +int TAB_SIZE = 3; /* TAB size is always set to 3 */ + +#define ID(token,length)\ +{\ + columnNumber+=length;\ + return(token);\ +}\ + +#define SET_WHERE(WHERE) \ +{ \ + WHERE.line =lineNumber; \ + WHERE.column=columnNumber; \ + WHERE.file ="main file"; \ +} + +#define COMMAND(token,length) \ +{ \ + SET_WHERE(yylval.Command.where); \ + \ + yylval.Command.command=token; \ + \ + columnNumber+=length; \ + return(token); \ +} + +%} +%option noyywrap +%x Comment + +%% + +"/*" { + if(commentLevel++<1) + BEGIN(Comment); + + columnNumber+=2; + } +"*/" { + if(--commentLevel==0) + BEGIN(INITIAL); + + columnNumber+=2; + } +\n { + lineNumber++; + columnNumber=1; + } +. { + columnNumber++; + } // skip any character and count + +"//".* ; + +";" COMMAND(SEMI,1) +"{" COMMAND(LPAR,1) +"}" COMMAND(RPAR,1) +":" COMMAND(COLON,1) +"," COMMAND(COMMA,1) +"*" COMMAND(TIMES,1) +"typedef" COMMAND(TYPEDEF,7) +"float" COMMAND(PFLOAT,5) +"double" COMMAND(PDOUBLE,6) +"long" COMMAND(PLONG,4) +"short" COMMAND(PSHORT,5) +"unsigned" COMMAND(PUNSIGNED,8) +"char" COMMAND(PCHAR,4) +"boolean" COMMAND(PBOOLEAN,7) +"octet" COMMAND(POCTET,5) +"complexd" COMMAND(PCOMPLEX2,8) +"complex" COMMAND(PCOMPLEX1,7) +"struct" COMMAND(PSTRUCT,6) +"<" COMMAND(LEFT,1) +">" COMMAND(RIGHT,1) +"[" COMMAND(LEPAR,1) +"]" COMMAND(REPAR,1) +"set" COMMAND(SET,3) +"marray" COMMAND(MARRAY,6)/* FORWISS */ + +%{ +/* +"module" COMMAND(MODULE,6) +"::" COMMAND(DOUBLE_COLON,2) +"persistent" COMMAND(PERSISTENT,10) +"transient" COMMAND(TRANSIENT,9) +"interface" COMMAND(INTERFACE,9) +"(" COMMAND(LRPAR,1) +")" COMMAND(RRPAR,1) +"extent" COMMAND(EXTENT,6) +"key" COMMAND(KEY,3) +"keys" COMMAND(KEYS,4) +"const" COMMAND(CONST,5) +"=" COMMAND(EQUAL,1) +"|" COMMAND(VERT,1) +"^" COMMAND(HAT,1) +"&" COMMAND(AMPER,1) +">>" COMMAND(DOUBLE_RIGHT,1) +"<<" COMMAND(DOUBLE_LEFT,1) +"+" COMMAND(PLUS,1) +"-" COMMAND(MINUS,1) +"/" COMMAND(SLASH,1) +"%" COMMAND(PERCENT,1) +"~" COMMAND(TILDE,1) +"TRUE" COMMAND(TRUE,4) +"FALSE" COMMAND(FALSE,5) +"any" COMMAND(ANY,3) +"union" COMMAND(UNION,5) +"switch" COMMAND(SWITCH,6) +"case" COMMAND(CASE,4) +"default" COMMAND(DEFAULT,7) +"enum" COMMAND(ENUM,4) +"Array" COMMAND(ARRAY,5) +"Sequence" COMMAND(SEQUENCE,8) +"String" COMMAND(STRING,6) +"readonly" COMMAND(READONLY,8) +"attribute" COMMAND(ATTRIBUTE,9) +"List" COMMAND(LIST,4) +"Bag" COMMAND(BAG,3) +"inverse" COMMAND(INVERSE,7) +"relationship" COMMAND(RELATIONSHIP,12) +"order_by" COMMAND(ORDER_BY,8) +"exception" COMMAND(EXCEPTION,9) +"oneway" COMMAND(ONEWAY,6) +"void" COMMAND(VOID,4) +"in" COMMAND(IN,2) +"out" COMMAND(OUT,3) +"inout" COMMAND(INOUT,5) +"raises" COMMAND(RAISES,6) +"context" COMMAND(CONTEXT,7) +*/ +%} + +[0-9]+ { + yylval.LEX_integer.value=atol(yytext); + + SET_WHERE(yylval.LEX_integer.where); + + ID(IntegerLiteral,yyleng); + } + +%{ +/* +[0-9]+"."[0-9]+ { + yylval.Real.value=atof(yytext); + + SET_WHERE(yylval.Real.where); + + ID(FloatingPtLiteral,yyleng); + } + +\"([^"]|\\["\n])*\" { + yylval.String.string=(const char*)malloc(yyleng+1-2); + strcpy((char*)yylval.String.string,yytext); + + SET_WHERE(yylval.String.where); + + ID(StringLiteral,yyleng); + } + +"'"[^']"'" { + yylval.Character.character=yytext[1]; + + SET_WHERE(yylval.Character.where); + + ID(CharacterLiteral,3); + } +*/ +%} + +[a-zA-Z_][a-zA-Z0-9_]* { + yylval.Entry.name =(const char*)malloc(yyleng+1); + + SET_WHERE(yylval.Entry.where); + + strcpy((char*)yylval.Entry.name,yytext); + + ID(Identifier,yyleng); + } + +\n { + lineNumber++; + columnNumber=1; + } + +\t { + columnNumber=((columnNumber-1)/TAB_SIZE+1)*TAB_SIZE+1; + } + +" " { + columnNumber++; + } diff --git a/rasdl/odl.yy b/rasdl/odl.yy new file mode 100644 index 0000000..9194d11 --- /dev/null +++ b/rasdl/odl.yy @@ -0,0 +1,631 @@ +%{ +/* +* This file is part of rasdaman community. +* +* Rasdaman community is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* Rasdaman community is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with rasdaman community. If not, see . +* +* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann / +rasdaman GmbH. +* +* For more information please see +* or contact Peter Baumann via . +*/ +//============================================================================== +// +// +// +// DESCRIPTION : Grammar description used to parse ODL files. +// +//============================================================================== + +#include +#include +#include + +#include "parse.hh" +#include "yparse.hh" +#include "symbtbl.hh" + +#include "raslib/minterval.hh" + +int yyparse(); + +extern int yylex(); +extern long lineNumber; +extern int columnNumber; + +YSymbolTable *Symbols=new YSymbolTable(); +YSymbol *unique_symbol(const char*name,const YWhere&); + +// error handling +void yyerror(const char* s); +extern const YWhere *error_where; // associatted place in source code with error is NULL if no available +extern const YWhere *error_source; // place where source of error +extern const char *error_token; + +// outputs an error with an argument like "...%s.." or "...%i.." +#define error_arg(OUTPUT,ARGUMENT,WHERE) \ +{ \ + char buffer[1024]; \ + sprintf(buffer,OUTPUT,ARGUMENT); \ + \ + error_where =WHERE; \ + yyerror(buffer); \ +}; + +%} + +%union{ + // types for LEX + struct + { + YWhere where; + const char *name; + } Entry; + + struct + { + YWhere where; + int command; + } Command; + + struct + { + YWhere where; + long value; + } LEX_integer; + + struct + { + YWhere where; + double value; + } Real; + + struct + { + YWhere where; + char character; + } Character; + + struct + { + YWhere where; + const char *string; + } String; + + // types for YACC + YSymbol* Symbol; + + Parse_type* Type; + Parse_interface* Interface; + Parse_composite::Element* element; + Parse_interface::Base_class* Base_Classes; + + Parse_interface::Lifetime Persistence; + Parse_enum::Enumerator* enumerator; + bool Boolean; + rINT_list* INT_list; + YLiteral Literal; + YDeclarator* Declarator; + + // spatial domain + r_Sinterval* dimension; + + struct + { + r_Minterval* domain; + unsigned long dimensionality; + } domainSpec; + + r_Minterval* domain; + + int dummyValue; + } + +%token Identifier +%token IntegerLiteral + +%token SEMI + LPAR + RPAR + COLON + COMMA + TIMES + TYPEDEF + PFLOAT + PDOUBLE + PLONG + PSHORT + PUNSIGNED + PCHAR + PBOOLEAN + POCTET + PCOMPLEX1 + PCOMPLEX2 + PSTRUCT + LEFT + RIGHT + LEPAR + REPAR + SET + MARRAY + +/* types of nonterminals */ +%type model,specification,definition; +%type literal,primary_expr +%type member,member_list +%type scoped_name +// enum_name +%type type_spec,simple_type_spec,type_declarator, + floating_pt_type,integer_type,signed_int,signed_long_int, + signed_short_int,unsigned_int,unsigned_long_int, + unsigned_short_int,char_type,boolean_type,octet_type,complex1_type,complex2_type, + struct_type,marray_type, type_dcl,constr_type_spec, + opt_marray_base,collection_type,base_type_spec, + template_type_spec +%type declarator,declarators,simple_declarator + +%type dimension_spec +%type opt_spatial_domain +%type spatial_domain,dimension_spec_list + +%% + +/*(0)*/ +model : { Symbols->push_scope(NULL); } + specification + { Symbols->pop_scope(); } + +/*(1)*/ +specification : definition + | definition specification + +/*(2)*/ +definition : type_dcl SEMI { $$ = NULL; } + +/*(11)*/ +/**/ +scoped_name : Identifier + { + if(!Symbols->search_scopes($1.name,$$)) + error_arg("undefined symbol[%s]",$1.name,&$1.where); + } + +/*(23)*/ +/**/ +primary_expr : literal { $$ = $1; } + +/*(24)*/ +/**/ +literal : IntegerLiteral + { + $$.Integer =$1.value; + $$.type =YLiteral::dLinteger; + } + +/*(27)*/ +type_dcl : TYPEDEF type_declarator { $$ = $2; } + | struct_type + +/*(28)*/ +type_declarator : type_spec declarators + { + // for each declarator there exists a symbol + // therefore generate only aliases + for(YDeclarator*scan=$2;scan!=NULL;scan=scan->next) + { + Parse_alias *alias=new Parse_alias; + + alias->type=$1; + alias->name=scan->symbol->get_name(); + alias->symbol=scan->symbol; + + scan->symbol->Type =alias; + scan->symbol->type =YSymbol::dParse_Type; + scan->symbol->owned_by_symbol =false; // never owned by symbol + }; + } + +/*(29)*/ +/**/ +type_spec : simple_type_spec + | constr_type_spec + { + Parse_typereference *reference=new Parse_typereference; + reference->type=$1; + reference->setParseInfo( $1->getParseInfo() ); + + $$=reference; + } + +/*(30)*/ +/**/ +simple_type_spec : base_type_spec + | template_type_spec + | scoped_name + { + Parse_typereference *reference=new Parse_typereference; + reference->type=$1->Type; + reference->setParseInfo( Parse_info( $1->where, $1->get_name() ) ); + + $$=reference; + } + +/*(31)*/ +/**/ +base_type_spec : floating_pt_type + | integer_type + | char_type + | boolean_type + | octet_type + | complex1_type + | complex2_type + +/*(32)*/ +/**/ +template_type_spec : collection_type + | marray_type + +/*(32a)*/ +/**/ +collection_type : SET LEFT simple_type_spec RIGHT + { + $$=new Parse_set; + $$->setParseInfo( Parse_info( $1.where, "Set" ) ); + ((Parse_set*)$$)->base_type=$3; + }; + +/*(33)*/ +/**/ +constr_type_spec : struct_type + +/*(34)*/ +/**/ +declarators : declarator + | declarator COMMA declarators + { + $1->next =$3; + $$ =$1; + }; + +/*(35)*/ +/**/ +declarator : simple_declarator + +/*(36)*/ +/**/ +simple_declarator : Identifier + { + YSymbol *symbol=unique_symbol($1.name,$1.where); + + $$=new YDeclarator; + $$->next =NULL; + $$->symbol =symbol; + $$->array_size =NULL; + } + +/*(38)*/ +/**/ +floating_pt_type : PFLOAT + { + Parse_float *real=new Parse_float; + real->accurance=Parse_float::Single; + real->setParseInfo( Parse_info( $1.where, "float") ); + + $$=real; + } + | PDOUBLE + { + Parse_float *real=new Parse_float; + real->accurance=Parse_float::Double; + real->setParseInfo( Parse_info( $1.where, "double") ); + + $$=real; + } + +/*(39)*/ +/**/ +integer_type : signed_int + | unsigned_int + +/*(40)*/ +/**/ +signed_int : signed_long_int + | signed_short_int + +/*(41)*/ +/**/ +signed_long_int : PLONG + { + Parse_int *integer=new Parse_int; + + integer->width =Parse_int::Long; + integer->sign =Parse_int::Signed; + integer->setParseInfo( Parse_info( $1.where, "long") ); + + $$=integer; + } + +/*(42)*/ +/**/ +signed_short_int : PSHORT + { + Parse_int *integer=new Parse_int; + + integer->width =Parse_int::Short; + integer->sign =Parse_int::Signed; + integer->setParseInfo( Parse_info( $1.where, "short") ); + + $$=integer; + } + +/*(43)*/ +/**/ +unsigned_int : unsigned_long_int + | unsigned_short_int + +/*(44)*/ +/**/ +unsigned_long_int : PUNSIGNED PLONG + { + Parse_int *integer=new Parse_int; + + integer->width =Parse_int::Long; + integer->sign =Parse_int::Unsigned; + integer->setParseInfo( Parse_info( $1.where, "unsigned long") ); + + $$=integer; + } + +/*(45)*/ +/**/ +unsigned_short_int : PUNSIGNED PSHORT + { + Parse_int *integer=new Parse_int; + + integer->width =Parse_int::Short; + integer->sign =Parse_int::Unsigned; + integer->setParseInfo( Parse_info( $1.where, "unsigned short") ); + + $$=integer; + } + +/*(46)*/ +/**/ +char_type : PCHAR + { + $$=new Parse_char; + $$->setParseInfo( Parse_info( $1.where, "char") ); + } + +/*(47)*/ +/**/ +boolean_type : PBOOLEAN + { + $$=new Parse_boolean; + $$->setParseInfo( Parse_info( $1.where, "boolean") ); + } + +/*(48)*/ +/**/ +octet_type : POCTET + { + $$=new Parse_octet; + $$->setParseInfo( Parse_info( $1.where, "octet") ); + } + +/*(48a)*/ +/**/ +complex1_type : PCOMPLEX1 + { + $$=new Parse_complex1; + $$->setParseInfo( Parse_info( $1.where, "complex") ); + } + + +/*(48b)*/ +/**/ +complex2_type : PCOMPLEX2 + { + $$=new Parse_complex2; + $$->setParseInfo( Parse_info( $1.where, "complexd") ); + } + +/*(50)*/ +/**/ +struct_type : PSTRUCT Identifier + { + YSymbol *symbol=unique_symbol($2.name,$1.where); + + symbol->type =YSymbol::dParse_Type; + symbol->Type =new Parse_struct; + symbol->Type->symbol =symbol; + symbol->owned_by_symbol =false; // never owned by a symbol + + symbol->Type->setParseInfo( Parse_info( $1.where, "struct") ); + + Symbols->push_scope(symbol); + } + LPAR member_list RPAR + { + const YSymbol *symbol=Symbols->pop_scope(); + + $$=symbol->Type; + + $$->name =symbol->get_name(); + ((Parse_struct*)$$)->elements =$5; + } + +/*(51)*/ +/**/ +member_list : member + | member member_list + { + Parse_composite::Element *scan=$1; + while(scan->next!=NULL) + scan=scan->next; + + scan->next=$2; + $$=$1; + } + +/*(52)*/ +/**/ +member : type_spec declarators SEMI + { + YDeclarator *scan=$2; + Parse_composite::Element *current=NULL; + + for(;scan!=NULL;scan=scan->next) + { + if(current==NULL) + { + current=new Parse_composite::Element; + $$=current; + } + else + { + current->next=new Parse_composite::Element; + current=current->next; + }; + + current->type=$1; + current->name=scan->symbol->get_name(); + }; + }; + +/*(75)*/ +/**/ +marray_type : MARRAY LEFT + opt_marray_base + opt_spatial_domain + RIGHT + { + $$=new Parse_MDD; + + ((Parse_MDD*)$$)->base_type =$3; + ((Parse_MDD*)$$)->domain =$4.domain; + ((Parse_MDD*)$$)->dimensionality =$4.dimensionality; + } + +/**/ +opt_marray_base : { $$=NULL; } + | simple_type_spec + +/**/ +opt_spatial_domain : { $$.domain=NULL; $$.dimensionality = 0; } + | COMMA primary_expr { $$.domain=NULL; $$.dimensionality = $2.Integer; } + | COMMA spatial_domain { $$.domain=$2; $$.dimensionality = 0; }; + +/*(76)*/ +/**/ +spatial_domain : LEPAR dimension_spec_list REPAR { $$ = $2; } + + +/*(77)*/ +/**/ +dimension_spec_list : dimension_spec + { + $$ = new r_Minterval(1); + (*$$)[0] = (*$1); + delete $1; $1=NULL; + } + | dimension_spec COMMA dimension_spec_list + { + $$ = new r_Minterval( $3->dimension() + 1 ); + + (*$$)[0] = (*$1); + delete $1; $1=NULL; + + for( int i=0; i<$3->dimension(); i++ ) + (*$$)[i+1] = (*$3)[i]; + + delete $3; $3=NULL; + } + + +/*(78)*/ +/**/ +dimension_spec : primary_expr COLON primary_expr { $$=new r_Sinterval( (r_Range)$1.Integer, (r_Range)$3.Integer ); } + | TIMES COLON primary_expr { $$=new r_Sinterval( '*' , (r_Range)$3.Integer ); } + | primary_expr COLON TIMES { $$=new r_Sinterval( (r_Range)$1.Integer, '*' ); } + | TIMES COLON TIMES { $$=new r_Sinterval( '*' , '*' ); } + + +%% +//**************************************************************************** +// +// name : unique_symbol +// purpose : tries to create an unique symbol within scope +// remarks : calls yyerror if name already exists in scope +// +//**************************************************************************** +YSymbol *unique_symbol(const char*name,const YWhere&where) +{ + YSymbol *symbol; + + if(!Symbols->scoped_symbol(&symbol,name,where)) + { + error_source=&symbol->where; + error_token =name; + + error_arg("[%s] symbol already defined within scope",name,&where); + }; + + return(symbol); +}; + +const YWhere *error_source =NULL; +const YWhere *error_where =NULL; +const char *error_token =NULL; +// associatted place in source code with error +// is NULL if no available + +void yyerror(const char* s) +{ + std::cout<<"error!\n"; + + if(error_where!=NULL) + { + std::cerr<<"\n pos : line "<line<<" colmun "<column; + + if(error_where->file!=NULL) + std::cerr<<" in \""<file<<"\""; + + std::cerr<<".\n"; + } + else + std::cerr<<"\n near : line "< "; + + std::cerr<<"error : "<line<<" column "<column; + + if(error_source->file!=NULL) + std::cerr<<" in \""<file<<"\""; + + std::cerr<<".\n"; + }; + + error_where =NULL; + error_source=NULL; + + exit(-2); +}; + diff --git a/rasdl/parse.cc b/rasdl/parse.cc new file mode 100644 index 0000000..127b821 --- /dev/null +++ b/rasdl/parse.cc @@ -0,0 +1,996 @@ +/* +* This file is part of rasdaman community. +* +* Rasdaman community is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* Rasdaman community is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with rasdaman community. If not, see . +* +* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann / +rasdaman GmbH. +* +* For more information please see +* or contact Peter Baumann via . +*/ +#include "rasdl/parse.hh" +#include "symbtbl.hh" +#include "yparse.hh" + +#include + +#include "debug/debug.hh" + +#include "raslib/rmdebug.hh" +#include "catalogmgr/typefactory.hh" +#include "relcatalogif/alltypes.hh" + +extern void output_scope(FILE*out,const YSymbolTable::Scope*scope); + +Parse_info::Parse_info() + : line(0), column(0), file(NULL), token(NULL) +{ +} + + +Parse_info::Parse_info( long lineNo, int columnNo, const char* fileName, const char* tokenName ) + : line( lineNo ), column( columnNo ), file(NULL), token(NULL) +{ + if( fileName ) + file = strdup( fileName ); + + if( tokenName ) + token = strdup( tokenName ); +} + + + +Parse_info::Parse_info( YWhere &where, const char* tokenName ) + : line( where.line ), column( where.column ), file(NULL), token(NULL) +{ + if( where.file ) + file = strdup( where.file ); + + if( tokenName ) + token = strdup( tokenName ); +} + + + +Parse_info::Parse_info( const Parse_info& obj ) +{ + line = obj.line; + column = obj.column; + + file = obj.file ? strdup( obj.file ) : NULL; + token = obj.token ? strdup( obj.token ) : NULL; +} + + + +Parse_info::~Parse_info() +{ + if( file ) { free( file ); file = NULL; } + if( token ) { free( token ); token = NULL; } +} + + + +const Parse_info& +Parse_info::operator=( const Parse_info& obj ) +{ + if( this != &obj ) + { + line = obj.line; + column = obj.column; + + file = obj.file ? strdup( obj.file ) : NULL; + token = obj.token ? strdup( obj.token ) : NULL; + } + + return *this; +} + + + +/* THE ATOM */ +Parse_atom::Parse_atom() +{ + kind =Atom; + name =NULL; + symbol =NULL; +} + +Parse_atom::~Parse_atom() +{ +} + +void Parse_atom::insertData() const throw( r_Equery_execution_failed ) +{ + RMDBGONCE(4, RMDebug::module_rasdl, "Parse_atom", "printData() kind " << kind << ", name " << name << ", symbol " << symbol) + TALK( "Parse_atom::insertData: doing nothing with name=" << name << ", symbol=" << symbol) +} + + +void Parse_atom::setParseInfo( const Parse_info &token ) +{ + parseInfo = token; +} + + +const Parse_info& Parse_atom::getParseInfo() +{ + return parseInfo; +} + + + +/* THE TYPE */ +Parse_type::Parse_type() +{ + kind =Type; + forward =false; +}; + +Parse_type::~Parse_type() +{ +} + +const Type* +Parse_type::getType( const char* /*typeName*/ ) const +{ + std::cerr << "Internal error: getType() for a subclass of Parse_type not implemented." << std::endl; + return NULL; +} + +Parse_typereference::Parse_typereference() +{ + kind =Typereference; + type =NULL; +} + +Parse_typereference::~Parse_typereference() +{ +} + +void Parse_typereference::output(FILE*stream)const +{ + fprintf(stream,"%s",type->name); +}; + +const Type* +Parse_typereference::getType( const char* /*typeName*/ ) const +{ + const BaseType* catBaseType = TypeFactory::mapType( (char*)type->name ); + + if( !catBaseType ) + // Error: Type reference not found.. + throw( r_Equery_execution_failed( 902, symbol->where.line, symbol->where.column, symbol->get_name() ) ); + + return catBaseType; +} + + +/* composite */ +Parse_composite::Parse_composite() +{ + kind =Composite; + elements =NULL; +}; + +Parse_composite::Element::Element() +{ + readonly =false; + type =NULL; + name =NULL; + access =Private; + + next =NULL; +}; + +Parse_composite::Element::~Element() +{ +} + +void Parse_composite::Element::output(FILE*stream)const +{ + fprintf(stream," "); + type->output(stream); + fprintf(stream," %s;",name); + + if(readonly) + fprintf(stream,"// ___readonly___\n"); + else + fprintf(stream,"\n"); +}; + +/* struct */ +Parse_struct::Parse_struct() +{ + kind =Struct; +}; + +Parse_struct::~Parse_struct() +{ +} + +void Parse_struct::output(FILE*stream)const +{ + fprintf(stream,"/* STRUCT -------------------------- %s */\n",name); + fprintf(stream,"struct %s {\n",name); + + for(Element*scan=elements;scan!=NULL;scan=scan->next) + scan->output(stream); + + fprintf(stream,"};\n"); +}; + + + +void Parse_struct::insertData() const throw( r_Equery_execution_failed ) +{ + ENTER( "Parse_struct::insertData" ); + RMDBGENTER(4, RMDebug::module_rasdl, "Parse_struct", "insertData()") + + // get catalog type structure + StructType* catType = (StructType*)getType(); + TALK( "got type " << (char*)catType->getTypeName() ); + + RMDBGMIDDLE(4, RMDebug::module_rasdl, "Parse_struct", "inserting type " << catType->getTypeName()) + + if( TypeFactory::mapType( (char*)catType->getTypeName() ) ) + // Error: Struct type name exists already. + throw( r_Equery_execution_failed( 905, symbol->where.line, symbol->where.column, symbol->get_name() ) ); + + TALK( "adding to the database as cell struct type" ); + TypeFactory::addStructType( catType ); + + RMDBGEXIT(4, RMDebug::module_rasdl, "Parse_struct", "insertData()") + LEAVE( "Parse_struct::insertData" ); +}; + + + +const Type* +Parse_struct::getType( const char* /*typeName*/ ) const +{ + unsigned int noElements=0; + StructType* structType=NULL; + Element* scan=NULL; + +RMDBGENTER(4, RMDebug::module_rasdl, "Parse_struct", "getType()") + + for( scan=elements; scan!=NULL; scan=scan->next, noElements++ ); + +RMDBGMIDDLE(4, RMDebug::module_rasdl, "Parse_struct", "Struct " << name << " has " << noElements << " elements.") + + structType = new StructType( (char*)name, noElements ); + + for( scan=elements; scan!=NULL; scan=scan->next) + if( !scan->type ) + std::cerr << "Internal error: struct element doesn't deliver a catalog type" << std::endl; + else + { +RMDBGMIDDLE(4, RMDebug::module_rasdl, "Parse_struct", "Scan->name " << scan->name) + structType->addElement( (char*)(scan->name), (BaseType*)(scan->type->getType()) ); + } + +RMDBGEXIT(4, RMDebug::module_rasdl, "Parse_struct", "getType()" ) + + return structType; +} + + + +/* union */ +Parse_union::Parse_union() +{ + kind =Union; +}; + +Parse_union::~Parse_union() +{ +} + +void Parse_union::output(FILE*stream)const +{ + fprintf(stream,"/* UNION --------------------------- %s */\n",name); + fprintf(stream,"struct %s {\n",name); + + for(Element*scan=elements;scan!=NULL;scan=scan->next) + scan->output(stream); + + fprintf(stream,"};\n"); +}; + +/* interface */ +Parse_interface::Parse_interface() +{ + kind =Interface; + + base_classes =NULL; + lifetime =undefined; + + methods =NULL; + relationships =NULL; +}; + +void print_access_mode(FILE*stream,Parse_composite::Access_mode access) +{ + switch(access) + { + case Parse_composite::Private: + { + fprintf(stream,"private:\n"); + break; + }; + case Parse_composite::Public: + { + fprintf(stream,"public:\n"); + break; + }; + case Parse_composite::Protected: + { + fprintf(stream,"protected:\n"); + break; + }; + }; +}; + +void Parse_interface::output(FILE*stream)const +{ + if(forward) + { + fprintf(stream,"class %s;/**/\n",name); + return; + }; + + fprintf(stream,"/* CLASS --------------------------- %s */\n",name); + if(base_classes!=NULL) + { + fprintf(stream,"class %s : ",name); + + for(Base_class *scan=base_classes;scan!=NULL;scan=scan->next) + { + scan->output(stream); + if(scan->next!=NULL) + fprintf(stream,","); + }; + + fprintf(stream,"\n{\n"); + } + else + fprintf(stream,"class %s {\n",name); + +// output all symbols + symbol->defines->output(stream); + + Access_mode current_access=Private; + + if(methods!=NULL) + { + fprintf(stream,"// operations\n"); + methods->output(stream); + }; + + if(elements!=NULL) + { + fprintf(stream,"// attributes\n"); + + for(Element *scan=elements;scan!=NULL;scan=scan->next) + { + if(scan->access!=current_access) + { + current_access=scan->access; + print_access_mode(stream,current_access); + }; + scan->output(stream); + }; + }; + + if(relationships!=NULL) + { + fprintf(stream,"//relationships\n"); + } + + fprintf(stream,"};\n"); +}; + +Parse_interface::Base_class::Base_class() +{ + base_class =NULL; + access =Private; + + next =NULL; +}; + +void Parse_interface::Base_class::output(FILE*stream)const +{ + if(base_class==NULL) + fprintf(stream,""); + else + switch(access) + { + case Private: + fprintf(stream,"private %s",base_class->name); + break; + case Public: + fprintf(stream,"public %s",base_class->name); + break; + case Protected: + fprintf(stream,"protected %s",base_class->name); + break; + }; +}; + +Parse_interface::Method::Method() +{ + function =NULL; + access =Private; + + next =NULL; +}; + +void Parse_interface::Method::output(FILE*stream)const +{ + function->output(stream); + fprintf(stream,";\n"); +}; + +/* function */ +Parse_function::Parse_function() +{ + kind =Function; + + parameters =NULL; + return_type =NULL; +}; + +void Parse_function::output(FILE*stream)const +{ + return_type->output(stream); + fprintf(stream," %s(",name); + + if(parameters!=NULL) + { + parameters->output(stream); + }; + fprintf(stream,")"); +}; + +Parse_function::Parameter::Parameter() +{ + type =NULL; + state =Unknown; + name =NULL; + + next =NULL; +}; + +void Parse_function::Parameter::output(FILE*stream)const +{ + if(state==In) + fprintf(stream,"const "); + + type->output(stream); + + if(state==Out) + fprintf(stream,"&"); + else + fprintf(stream," "); + + fprintf(stream,"%s",name); +}; + +/* operation */ +Parse_operation::Parse_operation() +{ + kind =Operation; + scope_class =NULL; +}; + +/* pointer */ +Parse_pointer::Parse_pointer() +{ + kind =Pointer; + type =NULL; +}; + +void Parse_pointer::output(FILE*stream)const +{ + type->output(stream); + fprintf(stream,"*"); +}; + +/* array */ +Parse_array::Parse_array() +{ + kind =Array; + size =0; +}; + +void Parse_array::output(FILE*stream)const +{ + type->output(stream); + fprintf(stream,"[%i]",size); +}; + +/* alias */ +Parse_alias::Parse_alias() +{ + kind =Alias; + + type =NULL; + name =NULL; +}; + +void Parse_alias::output(FILE*stream)const +{ + fprintf(stream,"/* TYPEDEF ------------------------- %s */\n",name); + fprintf(stream,"typedef "); + type->output(stream); + fprintf(stream," %s",name); + fprintf(stream,";\n\n"); +}; + +void Parse_alias::insertData() const throw( r_Equery_execution_failed ) +{ + ENTER( "Parse_alias::insertData" ); + RMDBGENTER(4, RMDebug::module_rasdl, "Parse_alias", "insertData()") + + // get catalog type structure + + const CType* catType = type->getType( name ); + if( !catType ) + { + std::cerr << "Internal error: no type in alias definition." << std::endl; + return; + } + TALK( "got type " << name ); + +RMDBGIF(5, RMDebug::module_rasdl, "Parse_alias", \ + { \ + char* typeStructure = catType->getTypeStructure(); \ + RMInit::dbgOut << "Name " << catType->getTypeName() << ", structure " << typeStructure << std::endl; \ + free( typeStructure ); typeStructure = NULL; \ + } ) + + switch( catType->getType() ) + { + case MDDTYPE: + if( TypeFactory::mapMDDType( (char*)catType->getTypeName() ) ) + { + delete catType; + // Error: MDD type name exists already. + throw( r_Equery_execution_failed( 906, symbol->where.line, symbol->where.column, symbol->get_name() ) ); + } + TALK( "adding to the database as MDD type" ); + TypeFactory::addMDDType( (MDDType*)catType ); + break; + + case SETTYPE: + if( TypeFactory::mapType( (char*)catType->getTypeName() ) ) + { + delete catType; + // Error: Set type name exists already. + throw( r_Equery_execution_failed( 907, symbol->where.line, symbol->where.column, symbol->get_name() ) ); + } + TALK( "adding to the database as set type" ); + TypeFactory::addSetType( (SetType*)catType ); + break; + + default: + delete catType; + // Error: Type in typedef definition not supported + throw( r_Equery_execution_failed( 900, symbol->where.line, symbol->where.column, symbol->get_name() ) ); + } + + delete catType; + + RMDBGEXIT( 4, RMDebug::module_rasdl, "Parse_alias", "insertData()") + LEAVE( "Parse_alias::insertData" ); +}; + +/* enumerator */ +Parse_enum::Parse_enum() +{ + kind =Enum; + enumerators =NULL; +}; + +void Parse_enum::output(FILE*stream)const +{ + fprintf(stream,"/* ENUMERATION --------------------- %s */\n",name); + fprintf(stream,"enum %s {",name); + + const Enumerator *scan=enumerators; + while(scan!=NULL) + { + fprintf(stream,"%s=%i",scan->name,scan->value); + + scan=scan->next; + if(scan!=NULL) + fprintf(stream,","); + }; + + fprintf(stream,"};\n"); +}; + +void Parse_enum::Enumerator::output(FILE*stream)const +{ + fprintf(stream,"// %s = %6i\n",name,value); +}; + +/* atomic types&classes */ +void Parse_atomic::output(FILE*stream)const +{ + fprintf(stream,"%s",name); +}; +/* any */ +Parse_any::Parse_any() +{ + kind =Any; + name ="r_Any"; +}; + +/* void */ +Parse_void::Parse_void() +{ + kind =Void; + name ="void"; +}; + +/* string */ +Parse_string::Parse_string() +{ + kind =String; + name ="r_String"; + + length =0; +}; + +/* boolean */ +Parse_boolean::Parse_boolean() +{ + kind =Boolean; + name ="r_Boolean"; +}; + +const Type* +Parse_boolean::getType( const char* /*typeName*/ ) const +{ + return TypeFactory::mapType("Bool" ); +} + +/* float */ +Parse_float::Parse_float() +{ + kind =Float; + name ="float"; + accurance =Single; +}; + +void Parse_float::output(FILE*stream)const +{ + switch(accurance) + { + case Single: + fprintf(stream,"r_Float"); + break; + case Double: + fprintf(stream,"r_Double"); + break; + } +}; + + + +const Type* +Parse_float::getType( const char* /*typeName*/ ) const +{ + const BaseType* type; + + if( accurance == Single ) + type = TypeFactory::mapType("Float"); + else + type = TypeFactory::mapType("Double"); + + return type; +} + + + +/* int */ +Parse_int::Parse_int() +{ + kind =Integer; + name ="int"; + + width =Short; + sign =Signed; +}; + +void Parse_int::output(FILE*stream)const +{ + switch(sign) + { + case Signed: + switch(width) + { + case Long: + fprintf(stream,"r_Long "); + break; + case Short: + fprintf(stream,"r_Short "); + break; + } + break; + case Unsigned: + switch(width) + { + case Long: + fprintf(stream,"r_ULong "); + break; + case Short: + fprintf(stream,"r_UShort "); + break; + } + break; + } +}; + + + +const Type* +Parse_int::getType( const char* /*typeName*/ ) const +{ + const BaseType* type; + + if( sign == Signed ) + { + switch(width) + { + case Long: + type = TypeFactory::mapType("Long" ); + break; + case Short: + type = TypeFactory::mapType("Short"); + break; + } + } + else + { + switch(width) + { + case Long: + type = TypeFactory::mapType("ULong" ); + break; + case Short: + type = TypeFactory::mapType("UShort"); + break; + } + } + + return type; +} + + + +/* octet */ +Parse_octet::Parse_octet() +{ + kind =Octet; + name ="r_Octet"; +}; + + + +const Type* +Parse_octet::getType( const char* /*typeName*/ ) const +{ + return TypeFactory::mapType("Octet"); +} + + +/* complex1 */ +Parse_complex1::Parse_complex1() +{ + kind = Complex1; + name = "r_Complex1"; +}; + + + +const Type* +Parse_complex1::getType( const char* /*typeName*/ ) const +{ + return TypeFactory::mapType("Complex1"); +} + +/* complex2 */ +Parse_complex2::Parse_complex2() +{ + kind = Complex2; + name = "r_Complex2"; +}; + + + +const Type* +Parse_complex2::getType( const char* /*typeName*/ ) const +{ + return TypeFactory::mapType("Complex2"); +} + + + + +/* char */ +Parse_char::Parse_char() +{ + kind =Char; + name ="r_Char"; +}; + +const Type* +Parse_char::getType( const char* /*typeName*/ ) const +{ + return TypeFactory::mapType("Char"); +} + + + +// forwiss atomics +Parse_atomic_templates::Parse_atomic_templates() +{ + kind =Atomic_template; + base_type =NULL; +}; + +Parse_MDD::Parse_MDD() +{ + kind =MDD; + domain =NULL; +}; + +void Parse_MDD::output(FILE*stream)const +{ + fprintf(stream,"r_Marray<"); + if(base_type!=NULL) + base_type->output(stream); + else + fprintf(stream,"no_type"); + + if(domain!=NULL) + { + fprintf(stream,"/*"); + char* stringDomain = domain->get_string_representation(); + fprintf(stream,"%s",stringDomain); + free(stringDomain); + fprintf(stream,"*/"); + }; + fprintf(stream,"> "); +}; + + + +const Type* +Parse_MDD::getType( const char* typeName ) const +{ + RMDBGENTER( 4, RMDebug::module_rasdl, "Parse_MDD", "getType()" ) + + if( !base_type || + ( base_type->kind != Typereference && base_type->kind != Boolean && + base_type->kind != Float && base_type->kind != Integer && + base_type->kind != Char && base_type->kind != Octet && + base_type->kind != Complex1 && base_type->kind != Complex2 + ) + ) + // Error: MDD base type has to be a type reference or an atomic type. + throw( r_Equery_execution_failed( 903, parseInfo.line, parseInfo.column, parseInfo.token ) ); + + // if( !domain ) + // // Error: MDD type must have a domain specification. + // throw( r_Equery_execution_failed( 904, parseInfo.line, parseInfo.column, parseInfo.token ) ); + + if( !typeName ) + { + std::cerr << "Internal error: mdd type needs a type name" << std::endl; + return 0; + } + + const BaseType* catBaseType = (BaseType*)base_type->getType(); + +RMDBGIF(4, RMDebug::module_rasdl, "Parse_MDD", \ + { \ + char* typeStructure = catBaseType->getTypeStructure(); \ + RMInit::dbgOut << " Base type name " << catBaseType->getTypeName() << ", structure " << typeStructure << std::endl; \ + free( typeStructure ); typeStructure = NULL; \ + } ) + + RMDBGMIDDLE(4, RMDebug::module_rasdl, "Parse_MDD", "type name " << typeName << ", base typIe name " << catBaseType->getTypeName() ) + + const MDDType* mddType; + + if( domain ) + mddType = new MDDDomainType( (char*)typeName, catBaseType, *domain ); + else if( dimensionality ) + mddType = new MDDDimensionType( (char*)typeName, catBaseType, (r_Dimension)dimensionality ); + else + mddType = new MDDBaseType( (char*)typeName, catBaseType ); + + RMDBGEXIT(4, RMDebug::module_rasdl, "Parse_MDD", "getType()") + + return mddType; +} + + + +Parse_set::Parse_set() +{ + kind =Set; +}; + +void Parse_set::output(FILE*stream)const +{ + fprintf(stream,"r_Setoutput(stream); + fprintf(stream,"> >"); +}; + + + +const Type* +Parse_set::getType( const char* typeName ) const +{ + RMDBGENTER(4, RMDebug::module_rasdl, "Parse_set", "getType()") + + if( !base_type || base_type->kind != Typereference ) + // Error: Set template type has to be a type reference. + throw( r_Equery_execution_failed( 901, parseInfo.line, parseInfo.column, parseInfo.token ) ); + + if( !typeName ) + { + std::cerr << "Internal error: mdd type needs a type name" << std::endl; + return NULL; + } + + const char* baseTypeName = ((Parse_typereference*)base_type)->type->name; + + if( !baseTypeName ) + { + std::cerr << "Internal error: set type needs a base type name" << std::endl; + return NULL; + } + + RMDBGMIDDLE(4, RMDebug::module_rasdl, "Parse_set", "Base type name " << baseTypeName) + + const MDDType* catBaseType = TypeFactory::mapMDDType( (char*)baseTypeName ); + + if( !catBaseType ) + // Error: Type reference not found.. + throw( r_Equery_execution_failed( 902, base_type->symbol->where.line, base_type->symbol->where.column, base_type->name ) ); + +RMDBGIF(5, RMDebug::module_rasdl, "Parse_set", \ + { \ + char* typeStructure = catBaseType->getTypeStructure(); \ + RMInit::dbgOut << " Name " << catBaseType->getTypeName() << ", structure " << typeStructure << std::endl; \ + free( typeStructure ); typeStructure = NULL; \ + }) + + RMDBGMIDDLE(4, RMDebug::module_rasdl, "Parse_set", "type name " << typeName << ", base type name " << baseTypeName ) + + const SetType* setType = new SetType( (char*)typeName, catBaseType ); + + RMDBGEXIT(4, RMDebug::module_rasdl, "Parse_set", "getType()") + + return setType; +} + diff --git a/rasdl/parse.hh b/rasdl/parse.hh new file mode 100644 index 0000000..0afc177 --- /dev/null +++ b/rasdl/parse.hh @@ -0,0 +1,748 @@ +/* +* This file is part of rasdaman community. +* +* Rasdaman community is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* Rasdaman community is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with rasdaman community. If not, see . +* +* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann / +rasdaman GmbH. +* +* For more information please see +* or contact Peter Baumann via . +*/ +#ifndef __PARSE_H +#define __PARSE_H + +// Put it in front of any typedef bool ... because o2 is using bool as a variable. +// #include "o2template_CC.hxx" + +#include "raslib/minterval.hh" +#include "raslib/error.hh" + +#include "relcatalogif/basetype.hh" +#include "relcatalogif/type.hh" + +#include + +class YSymbol; + +typedef Type CType; + +//@ManMemo: Module: {\bf rasdl} + +/** + C structure representing a position in source. +*/ +struct YWhere +{ + /// + long line; + /// + int column; + /// + const char* file; +}; + + + +//@ManMemo: Module: {\bf rasdl} + +/** + C++ structure representing a position in source. +*/ +class Parse_info +{ + public: + /// + Parse_info(); + + /// + Parse_info( long lineNo, int columnNo, const char* fileName, const char* tokenName ); + + /// + Parse_info( YWhere &where, const char* tokenName ); + + /// copy constructor + Parse_info( const Parse_info& obj ); + + /// destructor + ~Parse_info(); + + /// assignment operator + const Parse_info& operator=( const Parse_info& obj ); + + /// + long line; + /// + int column; + /// + char* file; + /// + char* token; +}; + + + +//@ManMemo: Module: {\bf rasdl} + +/** + Base class for all types which can easily be converted to numbers. +*/ +class Parse_number +{ +}; + + + +//@ManMemo: Module: {\bf rasdl} + +/** + Virtual base class for all objects with kind and output. +*/ + +class Parse_atom { +public: + /// + Parse_atom(); + /// + virtual ~Parse_atom(); + /// + virtual void output(FILE*)const=0; + /// + virtual void insertData() const throw( r_Equery_execution_failed ); + + /// + void setParseInfo( const Parse_info &token ); + + /// + const Parse_info& getParseInfo(); + + /// + enum Kind { + Atom,Type, + Typedefinition, + Typereference, + + Composite, + Struct,Union,Interface, + + Function, + Operation, + + Pointer, + Array, + Alias, + + Enum, + + Atomic, + Any,Void,Boolean,Float,Integer,Char,Octet,Complex1,Complex2,String, + + Atomic_template, + Domain,Set,MDD + }; + + /// + Kind kind; + /// + const char *name; + /// + YSymbol *symbol; + + /// definition of corresponding token + Parse_info parseInfo; +}; + + + +//@ManMemo: Module: {\bf rasdl} + +/** + Virtual base class for all types. +*/ +class Parse_type : public Parse_atom { +public: + /// + Parse_type(); + /// + virtual ~Parse_type(); + /// + Parse_type(char*); + + /// + virtual const CType* getType( const char* typeName = NULL ) const; + + /// this type is defined as forward {should be moved into YSymbol} + bool forward; +}; + + + + +//@ManMemo: Module: {\bf rasdl} + +/** + Virtual base class for all types that create a new one. +*/ +class Parse_typedefinition : public Parse_type +{ +}; + + + +//@ManMemo: Module: {\bf rasdl} + +/** + Represents a reference to a type. +*/ +class Parse_typereference : public Parse_type +{ +public: + /// + Parse_typereference(); + /// + virtual ~Parse_typereference(); + /// + virtual void output(FILE*)const; + + /// + virtual const CType* getType( const char* typeName = NULL ) const; + + /// + const Parse_type *type; +}; + + + +//@ManMemo: Module: {\bf rasdl} + +/** + Virtual base class for all types that are a kind of composite. +*/ +class Parse_composite : public Parse_typedefinition { +public: + /// + Parse_composite(); + + /// + enum Access_mode {Private,Public,Protected}; + + /// + class Element : public Parse_atom + { + public: + /// + Element(); + /// + virtual ~Element(); + /// + virtual void output(FILE*)const; + + /// + bool readonly; + /// + const Parse_type *type; + /// + Access_mode access; + + /// + Element *next; + }; + + /// + Element *elements; +}; + + + +//@ManMemo: Module: {\bf rasdl} + +/** + Class that represents the STRUCT type. +*/ +class Parse_struct : public Parse_composite { +public: + /// + Parse_struct(); + /// + virtual ~Parse_struct(); + /// + virtual void output(FILE*)const; + /// + virtual void insertData() const throw( r_Equery_execution_failed ); + /// + virtual const CType* getType( const char* typeName = NULL ) const; +}; + + + +//@ManMemo: Module: {\bf rasdl} + +/** + Class that represents the UNION type. +*/ +class Parse_union : public Parse_composite { + /// + Parse_union(); + /// + virtual ~Parse_union(); + /// + virtual void output(FILE*)const; +}; + + +class Parse_operation; + + +//@ManMemo: Module: {\bf rasdl} + +/** + class that represents the INTERFACE type +*/ +class Parse_interface : public Parse_composite { +public: + /// + Parse_interface(); + /// + virtual void output(FILE*)const; + + /// + enum Lifetime{persistend,transient,undefined}; + + /// + class Base_class : public Parse_atom + { + public: + /// + Base_class(); + /// + virtual void output(FILE*)const; + + /// + Parse_interface *base_class; + /// + Access_mode access; + + /// + Base_class *next; + }; + + /// + class Method : public Parse_atom + { + public: + /// + Method(); + /// + virtual void output(FILE*)const; + + /// + Parse_operation *function; + + /// + Access_mode access; + + /// + Method *next; + }; + + /// + Base_class *base_classes; + /// + Lifetime lifetime; + /// + Method *methods; + /// + void *relationships; +}; + + + +//@ManMemo: Module: {\bf rasdl} + +/** + Represents a simple function with parameters and return value. +*/ +class Parse_function : public Parse_atom { +public: + /// + Parse_function(); + /// + virtual void output(FILE*)const; + + /// + class Parameter : public Parse_atom + { + public: + /// + Parameter(); + /// + virtual void output(FILE*)const; + + /// + Parse_typereference *type; + /// + enum {In,Out,Unknown} state; + + /// + Parameter *next; + }; + + /// + Parameter *parameters; + /// + Parse_typereference *return_type; +}; + + + +//@ManMemo: Module: {\bf rasdl} + +/** + Is a operation of an Parse_interface. +*/ +class Parse_operation : public Parse_function { +public: + /// + Parse_operation(); + + /// + Parse_interface *scope_class; +}; + + + +//@ManMemo: Module: {\bf rasdl} + +/** + Class that represents pointer like types. +*/ +class Parse_pointer : public Parse_typedefinition { +public: + /// + Parse_pointer(); + /// + virtual void output(FILE*)const; + + /// + const Parse_type *type; +}; + + + +//@ManMemo: Module: {\bf rasdl} + +/** + Class that represents an ARRAY. +*/ +class Parse_array : public Parse_pointer { +public: + /// + Parse_array(); + /// + virtual void output(FILE*)const; + /// + int size; +}; + + + +//@ManMemo: Module: {\bf rasdl} + +/** + Gives a type another name. +*/ +class Parse_alias : public Parse_typedefinition { +public: + /// + Parse_alias(); + /// + virtual void output(FILE*)const; + /// + virtual void insertData() const throw( r_Equery_execution_failed ); + /// + const Parse_type *type; +}; + + + +//@ManMemo: Module: {\bf rasdl} + +/** +*/ +class Parse_enum : public Parse_typedefinition,public Parse_number +{ +public: + /// + Parse_enum(); + /// + virtual void output(FILE*)const; + + /// + class Enumerator : public Parse_atom + { + public: + /// + virtual void output(FILE*)const; + + /// + const char *name; + /// + int value; + /// + Enumerator *next; + }; + + /// + Enumerator *enumerators; +}; + + + +//@ManMemo: Module: {\bf rasdl} + +/** +*/ +class Parse_atomic : public Parse_typedefinition { +public: + /// + virtual void output(FILE*)const; +}; + + + +//@ManMemo: Module: {\bf rasdl} + +/** +*/ +class Parse_any : public Parse_atomic { +public: + /// + Parse_any(); +}; + + + +//@ManMemo: Module: {\bf rasdl} + +/** +*/ +class Parse_void : public Parse_atomic { +public: + /// + Parse_void(); +}; + + + +//@ManMemo: Module: {\bf rasdl} + +/** +*/ +class Parse_string : public Parse_atomic +{ +public: + /// + Parse_string(); + + /// + int length; +}; + + + +//@ManMemo: Module: {\bf rasdl} + +/** + A fractional number. +*/ +class Parse_float : public Parse_atomic,public Parse_number { +public: + /// + Parse_float(); + /// + virtual void output(FILE*)const; + /// + virtual const CType* getType( const char* typeName = NULL ) const; + + /// + enum {Double,Single} accurance; +}; + + + +//@ManMemo: Module: {\bf rasdl} + +/** + Represents a non-fractional number signed/unsigned or 16/32 number. +*/ +class Parse_int : public Parse_atomic,public Parse_number { +public: + /// + Parse_int(); + /// + virtual void output(FILE*)const; + /// + virtual const CType* getType( const char* typeName = NULL ) const; + + /// + enum {Short,Long} width; + /// + enum {Unsigned,Signed} sign; +}; + + + +//@ManMemo: Module: {\bf rasdl} + +/** + An 8-bit unsigned number. +*/ +class Parse_octet : public Parse_atomic,public Parse_number +{ +public: + /// + Parse_octet(); + /// + virtual const CType* getType( const char* typeName = NULL ) const; +}; + +//@ManMemo: Module: {\bf rasdl} + +class Parse_complex1 : public Parse_atomic,public Parse_number +{ +public: + /// + Parse_complex1(); + /// + virtual const CType* getType( const char* typeName = NULL ) const; +}; + + +class Parse_complex2 : public Parse_atomic,public Parse_number +{ +public: + /// + Parse_complex2(); + /// + virtual const CType* getType( const char* typeName = NULL ) const; +}; + + + + +//@ManMemo: Module: {\bf rasdl} + +/** + Represents an 8-bit unsigned number. +*/ +class Parse_char : public Parse_atomic,public Parse_number { +public: + /// + Parse_char(); + /// + virtual const CType* getType( const char* typeName = NULL ) const; +}; + + + +//@ManMemo: Module: {\bf rasdl} + +/** +*/ +class Parse_boolean : public Parse_atomic,public Parse_number { +public: + /// + Parse_boolean(); + /// + virtual const CType* getType( const char* typeName = NULL ) const; +}; + + + +//@ManMemo: Module: {\bf rasdl} + +/** +*/ +class Parse_atomic_templates : public Parse_atomic { +public: + /// + Parse_atomic_templates(); + /// + const Parse_type *base_type; +}; + + + +//@ManMemo: Module: {\bf rasdl} + +/** +*/ +class Parse_set : public Parse_atomic_templates { +public: + /// + Parse_set(); + /// + virtual void output(FILE*)const; + /// + virtual const CType* getType( const char* typeName = NULL ) const; +}; + + + +//@ManMemo: Module: {\bf rasdl} + +/** +*/ +class Parse_MDD : public Parse_atomic_templates { +public: + /// + Parse_MDD(); + + /// + virtual void output(FILE*)const; + + /// + virtual const CType* getType( const char* typeName = NULL ) const; + + /// + r_Minterval* domain; + + /// + unsigned long dimensionality; +}; +#endif + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/rasdl/rasdl.awk b/rasdl/rasdl.awk new file mode 100644 index 0000000..79f99dc --- /dev/null +++ b/rasdl/rasdl.awk @@ -0,0 +1,11 @@ +BEGIN { paren = 0; sec = 0; comm = 0 } +/^ *$/ { next; } +/\%\%/ { sec += 1; next; } +sec!=1 { next; } +/^\/\*$/ { comm = 1; next; } +/^\*\// { comm = 0; next; } +comm == 1 { next; } +/^\/\*.*\*\// { next; } +/{/ { x=$0; sub(/\{.*/, "", x); if(!paren) print x; paren += 1; } +/}/ { paren -= 1; next; } +!paren { print $0; } diff --git a/rasdl/rasdl.cc b/rasdl/rasdl.cc new file mode 100644 index 0000000..6202c39 --- /dev/null +++ b/rasdl/rasdl.cc @@ -0,0 +1,724 @@ +/* +* This file is part of rasdaman community. +* +* Rasdaman community is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* Rasdaman community is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with rasdaman community. If not, see . +* +* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann / +rasdaman GmbH. +* +* For more information please see +* or contact Peter Baumann via . +*/ +/************************************************************* + * + * + * PURPOSE: + * + * + * COMMENTS: + * The internal functions return 0 on error, 1 on success. Not really common, + * but it was used in some routines and so I stuck with it. Norbert 25-05-2001. + * + * BUGS: + * - for inconsistent dictionnaries strange output might be generated + * which is not syntactically correct. + * + ************************************************************/ + +static const char rasdl_rcsid[] = "@(#)rasdl,rasdl.cc: $Id: rasdl.cc,v 1.48 2007/02/21 19:47:28 rasdev Exp $"; + +#define DEBUG +#define DEBUG_MAIN +#include "debug/debug.hh" + +#ifndef RMANVERSION +#error "Please specify RMANVERSION variable!" +#endif + +#ifndef COMPDATE +#error "Please specify the COMPDATE variable!" +/* +COMPDATE=`date +"%d.%m.%Y %H:%M:%S"` + +and -DCOMPDATE="\"$(COMPDATE)\"" when compiling +*/ +#endif + + +#ifdef EARLY_TEMPLATE +#define __EXECUTABLE__ +#ifdef __GNUG__ +#include "template_inst.hh" +#endif +#endif + +#include // cout +#include // cout +#include +#include +#include +using namespace std; + +#include // fopen, perror +#include // for atol() +#include +#include +#include // time(), ctime() + +#include "globals.hh" // DEFAULT_DBNAME + +#include "reladminif/adminif.hh" +#include "reladminif/databaseif.hh" +#include "reladminif/transactionif.hh" + +#include "relcatalogif/settype.hh" +#include "relcatalogif/mdddomaintype.hh" +#include "relcatalogif/mdddimensiontype.hh" +#include "relcatalogif/alltypes.hh" +#include "catalogmgr/typefactory.hh" +#ifndef BASEDB_O2 + #include "reladminif/dbref.hh" +#endif + +#include "raslib/rminit.hh" +#include "raslib/rmdebug.hh" + + +// error codes, exceptions +#include "rasdl_error.hh" + +// error texts +#define ERROR_NOACTION "EDL000 Error: no action specified." +#define ERROR_UNKNOWNACTION "EDL001 Error: unknown action type: " +#define ERROR_PANIC "EDL002 panic: unexpected internal exception." +#define ERROR_RASDAMAN "EDL003 rasdaman error: " + + +// init globals for server initialization +RMINITGLOBALS('S') + +#include "commline/cmlparser.hh" + +// command line flags and options + +#define FLAG_DATABASE 'd' +#define PARAM_DATABASE "database" +#define HELP_DATABASE " name of the database" + +#define PARAM_BASENAME "basename" +#define HELP_BASENAME " name of the database (deprecated, use --database)" +#define DEFAULT_BASENAME DEFAULT_DBNAME + +#define FLAG_CREATE 'c' +#define PARAM_CREATE "createdatabase" +#define HELP_CREATE "create database and initialize schema information" + +#define PARAM_DELDB "deldatabase" +#define HELP_DELDB "delete database" + +#define FLAG_PRINT 'p' +#define PARAM_PRINT "print" +#define HELP_PRINT "print all types" + +#define FLAG_READ 'r' +#define PARAM_READ "read" +#define HELP_READ " read data definition file" + +#define PARAM_DELBASETYPE "delbasetype" +#define HELP_DELBASETYPE " delete base type with name " + +#define PARAM_DELMDDTYPE "delmddtype" +#define HELP_DELMDDTYPE " delete mdd type with name " + +#define PARAM_DELSETTYPE "delsettype" +#define HELP_DELSETTYPE " delete set type with name " + +#define FLAG_INSERT 'i' +#define PARAM_INSERT "insert" +#define HELP_INSERT "insert types into database (requires -r)" + +#define PARAM_HH "hh" +#define HELP_HH " print C++ header into (requires -r)" + +#define PARAM_CONNECT "connect" +#define HELP_CONNECT " connect string for underlying database (syntax depending on base DBMS, e.g., rasbase@serverhost)" +#define DEFAULT_CONNECT "/" + +#define PARAM_DEBUG "debug" +#define HELP_DEBUG "print diagnostic output" + +#define FLAG_HELP 'h' +#define PARAM_HELP "help" +#define HELP_HELP "print this help" + + +#ifdef EXIT_SUCCESS + #undef EXIT_SUCCESS +#endif +#ifdef EXIT_FAILURE + #undef EXIT_FAILURE +#endif +#ifdef EXIT_HELP + #undef EXIT_HELP +#endif +// program return codes +#define EXIT_SUCCESS 0 +#define EXIT_FAILURE -1 +#define EXIT_HELP 2 + +#include "rasdl/symbtbl.hh" +#include "rasdl/yparse.hh" + +// globalso for lex and yacc code +extern int yyparse(); +extern FILE *yyin; +extern YSymbolTable *Symbols; + +// pointers representing O2, database, ta and session +AdminIf* admin = NULL; +DatabaseIf* db = NULL; +TransactionIf* ta = NULL; + +// command indicator (what to do) +enum ProgModes +{ + M_INVALID, + M_PRINT, + M_READ, + M_DELBASETYPE, + M_DELSETTYPE, + M_DELMDDTYPE, + M_CREATEDATABASE, + M_DELDATABASE, + M_HELP +}; + +ProgModes progMode = M_INVALID; + +// this variable is provided for Admin/DatabaseIf for opening connections, it holds the connect string +char globalConnectId[256]; + + +const char *baseName = DEFAULT_BASENAME; +const char *odlFileName = ""; +const char *headerFileName = ""; +const char *deleteName = ""; +const char *dbSchema = ""; +const char *dbVolume = ""; +int optionValueIndex; +int insertIntoDb = 0; +bool printToFile = false; + + +void +printNames() +{ + TypeIterator structIter = TypeFactory::createStructIter(); + + cout << endl; + cout << "// rasdaman database '" << baseName << "' type definitions" << endl; + time_t now = time(NULL); + cout << "// generated on: " << ctime( &now ); + cout << endl; + + cout << "//" << endl; + cout << "// marray base types" << endl; + cout << "//" << endl; + + while(structIter.not_done()) + { + StructType* typePtr = structIter.get_element(); + char* typeStructure = typePtr->getTypeStructure(); + + cout << "typedef " << typeStructure << " " << typePtr->getTypeName() << ";" << endl; + + free( typeStructure ); + typeStructure = NULL; + + structIter.advance(); + } + + cout << endl; + cout << "//" << endl; + cout << "// marray types" << endl; + cout << "//" << endl; + + TypeIterator mddIter = TypeFactory::createMDDIter(); + + while(mddIter.not_done()) + { + MDDType* typePtr = mddIter.get_element(); + char* typeStructure = typePtr->getTypeStructure(); + + cout << "typedef " << typeStructure << " " << typePtr->getTypeName() << ";" << endl; + + free( typeStructure ); + typeStructure = NULL; + + mddIter.advance(); + } + + cout << endl; + cout << "//" << endl; + cout << "// set types" << endl; + cout << "//" << endl; + + TypeIterator setIter = TypeFactory::createSetIter(); + + while(setIter.not_done()) + { + SetType* typePtr = setIter.get_element(); + char* typeStructure = typePtr->getTypeStructure(); + + cout << "typedef " << typeStructure << " " << typePtr->getTypeName() << ";" << endl; + + free( typeStructure ); + typeStructure = NULL; + + setIter.advance(); + } + + cout << endl; +} + + +void +printHeader( const char* headerFileName ) +{ + cout << "Generating header file " << headerFileName << "..." << flush; + + FILE *file=fopen( headerFileName, "wt" ); + if(!file) + throw RasdlError( CANNOTWRITEHDR ); + + char* defName = new char[strlen(headerFileName)+1]; + if (defName == NULL) + throw RasdlError( CANNOTALLOC ); + + // generate upper case version for include guard + int i = 0; + while( headerFileName[i] != '.' && headerFileName[i] != '\0' ) + { + defName[i] = toupper( headerFileName[i] ); + i++; + } + defName[i] = '\0'; + + /* header description */ + fprintf(file,"//------------------------------------------------------------\n"); + fprintf(file,"// This file is created automatically by the rasdl processor.\n"); + fprintf(file,"// better than modifying this file is to re-generate it. \n"); + fprintf(file,"//------------------------------------------------------------\n"); + fprintf(file,"\n"); + fprintf(file,"#ifndef __%s_HH_\n", defName ); + fprintf(file,"#define __%s_HH_\n", defName ); + fprintf(file,"\n"); + fprintf(file,"//------------------------------------------------------------\n"); + fprintf(file,"// Includes\n"); + fprintf(file,"//------------------------------------------------------------\n"); + fprintf(file,"\n"); + fprintf(file,"#include \"rasdaman.hh\"\n"); + fprintf(file,"\n"); + + Symbols->global_scope->output(file); + + fprintf(file,"#endif\n"); + + fclose(file); + delete[] defName; + defName = NULL; + + cout << "ok" << endl; +} + +void +disconnectDB( bool commitTa ) +{ + ENTER( "disconnectDB, commitTa =" << commitTa ); + + if( ta ) + { + if(commitTa ) + { + ta->commit(); + TALK( "TA committed." ); + } + else + { + ta->abort(); + TALK( "TA aborted." ); + } + + delete ta; + ta = NULL; + + if( db ) + { + db->close(); + TALK( "DB closed." ); + delete db; + db = NULL; + } + + if( admin ) + { + delete admin; + admin = NULL; + } + } + LEAVE( "disconnectDB" ); +} + +void +connectDB( const char* baseName, bool openDb, bool openTa ) throw (r_Error, RasdlError) +{ + ENTER( "connectDB, basename=" << baseName ); + + admin = AdminIf::instance(); + if( !admin ) + { + TALK( "cannot create adminIf instance" ); + throw RasdlError( NOCONNECTION ); + } + + if ( openDb ) + { + // connect to the database + db = new DatabaseIf(); + // TALK( "adding dbf to adminif" ); + // admin->setCurrentDatabaseIf( db ); + TALK( "opening db" ); + db->open( baseName ); + } + + if ( openTa ) + { + // start transaction + ta = new TransactionIf(); + TALK( "opening ta" ); + ta->begin( db ); + } + + LEAVE( "connectDB" ); +} + +//analyse params +void +parseParams(int argc, char* argv[]) throw (r_Error, RasdlError) +{ + CommandLineParser &cmlInter = CommandLineParser::getInstance(); + + CommandLineParameter &cmlHelp = cmlInter.addFlagParameter( FLAG_HELP, PARAM_HELP, HELP_HELP ); + + CommandLineParameter &cmlDbName = cmlInter.addStringParameter( FLAG_DATABASE, PARAM_DATABASE, HELP_DATABASE, DEFAULT_BASENAME ); + CommandLineParameter &cmlBaseName = cmlInter.addStringParameter(CommandLineParser::noShortName, PARAM_BASENAME, HELP_BASENAME, DEFAULT_BASENAME ); + CommandLineParameter &cmlCreateDb = cmlInter.addFlagParameter( FLAG_CREATE, PARAM_CREATE, HELP_CREATE ); + CommandLineParameter &cmlDelDb = cmlInter.addFlagParameter(CommandLineParser::noShortName, PARAM_DELDB, HELP_DELDB ); + CommandLineParameter &cmlReadMeta = cmlInter.addStringParameter( FLAG_READ, PARAM_READ, HELP_READ ); + CommandLineParameter &cmlInsertInDb = cmlInter.addFlagParameter( FLAG_INSERT, PARAM_INSERT, HELP_INSERT ); + + CommandLineParameter &cmlHHGen = cmlInter.addStringParameter(CommandLineParser::noShortName, PARAM_HH, HELP_HH ); + CommandLineParameter &cmlPrintMeta = cmlInter.addFlagParameter( FLAG_PRINT, PARAM_PRINT, HELP_PRINT ); + + CommandLineParameter &cmlDelBaseType = cmlInter.addStringParameter(CommandLineParser::noShortName, PARAM_DELBASETYPE, HELP_DELBASETYPE ); + CommandLineParameter &cmlDelMddType = cmlInter.addStringParameter(CommandLineParser::noShortName, PARAM_DELMDDTYPE, HELP_DELMDDTYPE ); + CommandLineParameter &cmlDelSetType = cmlInter.addStringParameter(CommandLineParser::noShortName, PARAM_DELSETTYPE, HELP_DELSETTYPE ); + +#ifdef BASEDB_O2 + CommandLineParameter &cmlSchemaDb = cmlInter.addStringParameter(CommandLineParser::noShortName, "schema", " name of o2 schema used for new bases", "RasDaSchema"); + CommandLineParameter &cmlVolumeDb = cmlInter.addStringParameter(CommandLineParser::noShortName, "volume", " name of o2 volume used for new bases"); +#endif + + CommandLineParameter &cmlConnectStr = cmlInter.addStringParameter(CommandLineParser::noShortName, PARAM_CONNECT, HELP_CONNECT, DEFAULT_CONNECT ); + +#ifdef DEBUG + CommandLineParameter &cmlDebug = cmlInter.addFlagParameter(CommandLineParser::noShortName, PARAM_DEBUG, HELP_DEBUG ); +#endif + + try + { + cmlInter.processCommandLine(argc, argv); + + if (argc == 1 || cmlHelp.isPresent()) + { + static const char* ExDbName = DEFAULT_BASENAME; + static const char* ExBaseName = "char"; + static const char* ExMddName = "GreyImage"; + static const char* ExSetName = "GreySet"; + static const char* ExMetaFile = "basictypes.dl"; + static const char* ExHHFile = "basictypes.hh"; + + cout << "Usage: rasdl [options]" << endl; + cout << "Options:" << endl; + cmlInter.printHelp(); + + cout << "Examples:" << endl; + cout << " create database:\trasdl " << CommandLineParser::LongSign << cmlDbName.getLongName() << " " << ExDbName << " " << CommandLineParser::LongSign << cmlCreateDb.getLongName() << endl; + cout << " delete database:\trasdl " << CommandLineParser::LongSign << cmlDbName.getLongName() << " " << ExDbName << " " << CommandLineParser::LongSign << cmlDelDb.getLongName() << endl; + cout << " delete base type:\trasdl " << CommandLineParser::LongSign << cmlDbName.getLongName() << " " << ExDbName << " " << CommandLineParser::LongSign << cmlDelBaseType.getLongName() << " " << ExBaseName << endl; + cout << " delete mdd type:\trasdl " << CommandLineParser::LongSign << cmlDbName.getLongName() << " " << ExDbName << " " << CommandLineParser::LongSign << cmlDelMddType.getLongName() << " " << ExMddName << endl; + cout << " delete set type:\trasdl " << CommandLineParser::LongSign << cmlDbName.getLongName() << " " << ExDbName << " " << CommandLineParser::LongSign << cmlDelSetType.getLongName() << " " << ExSetName << endl; + cout << " print all types:\trasdl " << CommandLineParser::LongSign << cmlDbName.getLongName() << " " << ExDbName << " " << CommandLineParser::LongSign << cmlPrintMeta.getLongName() << endl; + cout << " insert types:\trasdl " << CommandLineParser::LongSign << cmlDbName.getLongName() << " " << ExDbName << " " << CommandLineParser::LongSign << cmlReadMeta.getLongName() << " " << ExMetaFile << " " << CommandLineParser::LongSign << cmlInsertInDb.getLongName() << endl; + cout << " generate C++ header from type file:\trasdl " << CommandLineParser::LongSign << cmlReadMeta.getLongName() << " " << ExMetaFile << " " << CommandLineParser::LongSign << cmlHHGen.getLongName() << " " << ExHHFile << endl; + exit( EXIT_HELP ); // bash ret code for usage; FIXME: exit() no good style! + } + +#ifdef DEBUG + // debug + SET_OUTPUT( cmlDebug.isPresent() ); +#endif + + if (cmlBaseName.isPresent()) + baseName = cmlBaseName.getValueAsString(); + + if (cmlDbName.isPresent()) + baseName = cmlDbName.getValueAsString(); + + //read mode + if( cmlReadMeta.isPresent()) + { + progMode = M_READ; + odlFileName = cmlReadMeta.getValueAsString(); + } + + //schema && volume +#ifdef BASEDB_O2 + // to be done + dbSchema = cmlSchemaDb.getValueAsString()); + if( cmlVolumeDb.isPresent()) + { + if( cmlVolumeDb.getValueAsString()) + dbVolume = cmlVolumeDb.getValueAsString()); + } +#endif + + //hhgen + if( cmlHHGen.isPresent()) + { + if( cmlHHGen.getValueAsString()) + { + headerFileName = cmlHHGen.getValueAsString(); + printToFile = true; + } + } + + //insertindb + insertIntoDb = cmlInsertInDb.isPresent(); + + //print mode + if( cmlPrintMeta.isPresent()) + progMode = M_PRINT; + + //create mode + if( cmlCreateDb.isPresent()) + progMode = M_CREATEDATABASE; + + //delete mode + if( cmlDelDb.isPresent() ) + progMode = M_DELDATABASE; + + //delbasetype mode + if( cmlDelBaseType.isPresent() ) + { + progMode = M_DELBASETYPE; + if( cmlDelBaseType.getValueAsString() ) + deleteName = cmlDelBaseType.getValueAsString(); + } + + //delmddtype mode + if( cmlDelMddType.isPresent() ) + { + progMode = M_DELMDDTYPE; + if( cmlDelMddType.getValueAsString()) + deleteName = cmlDelMddType.getValueAsString(); + } + + //delsettype mode + if( cmlDelSetType.isPresent() ) + { + progMode = M_DELSETTYPE; + if( cmlDelSetType.getValueAsString() ) + deleteName = cmlDelSetType.getValueAsString(); + } + + // connectstr + if( cmlConnectStr.isPresent() ) + strcpy( globalConnectId, cmlConnectStr.getValueAsString() ); + else + strcpy( globalConnectId, DEFAULT_CONNECT ); + } + catch ( CmlException & err) + { + throw RasdlError( CMDLINE ); + } + + // --- plausi checks ------------------------------------ + // FIXME: to complete + + // if something is to be deleted in the database, then a name must be specified + if ( cmlDelBaseType.isPresent() || cmlDelMddType.isPresent() || cmlDelSetType.isPresent() ) + { + if ( deleteName == NULL || strlen(deleteName) == 0) + throw RasdlError( EMPTYTYPENAME ); + } + + // -r needs either -i or -hh + if( cmlReadMeta.isPresent() && ( !cmlInsertInDb.isPresent() && !cmlHHGen.isPresent() ) ) + throw RasdlError( ILLEGALREADCOMBI ); + if( ( cmlInsertInDb.isPresent() && cmlHHGen.isPresent() ) ) + throw RasdlError( ILLEGALREADCOMBI ); + + if( cmlInsertInDb.isPresent() && !cmlReadMeta.isPresent() ) + throw RasdlError( ILLEGALINSERTCOMBI ); + + if( cmlHHGen.isPresent() && !cmlReadMeta.isPresent() ) + throw RasdlError( ILLEGALHHCOMBI ); + + TALK( "connect=" << globalConnectId ); +} // parseParams() + +void +readMode() throw (r_Error, RasdlError) +{ + cout << "Reading rasdaman data definition file " << odlFileName << "..." << flush; + + // yyin is used by yyparse() + yyin=fopen( odlFileName,"r" ); + if( yyin==NULL ) + throw RasdlError( ODLFILEFAILED ); + + int parseResult = yyparse(); + if(yyin && (yyin != stdin)) + fclose( yyin ); + if( parseResult != 0) + throw RasdlError( ODLPARSEERROR ); + + if( insertIntoDb ) + { + cout << "inserting symbols into database..." << flush; + Symbols->global_scope->insertData(); + cout << "ok" << endl; + } + if( printToFile ) + printHeader( headerFileName ); + + cout << "ok" << endl; +} + + + +int +main( int argc, char* argv[] ) +{ + int result = EXIT_FAILURE; + + cout << "rasdl: rasdaman schema and database manipulation tool, rasdaman v" << RMANVERSION / 1000.0 << " on base DBMS " << BASEDBSTRING << " -- generated on " << COMPDATE << "." << endl; + + try + { + parseParams(argc,argv); + + switch( progMode ) + { + case M_READ: + connectDB( baseName, true, true ); + readMode(); + disconnectDB( true ); + break; + case M_DELBASETYPE: + cout << "Deleting basetype " << deleteName << "..." << flush; + connectDB( baseName, true, true ); + TypeFactory::deleteStructType( deleteName ); + disconnectDB( true ); + cout << "ok" << endl; + break; + case M_DELMDDTYPE: + cout << "Deleting MDD type " << deleteName << "..." << flush; + connectDB( baseName, true, true ); + TypeFactory::deleteMDDType( deleteName ); + disconnectDB( true ); + cout << "ok" << endl; + break; + case M_DELSETTYPE: + cout << "Deleting set type " << deleteName << "..." << flush; + connectDB( baseName, true, true ); + TypeFactory::deleteSetType( deleteName ); + disconnectDB( true ); + cout << "ok" << endl; + break; + case M_CREATEDATABASE: + cout << "Creating base " << baseName; +#ifdef BASEDB_O2 + cout << " with schema " << dbSchema; +#endif + if( strcasecmp(dbVolume,"") ) + cout << " on volume " << dbVolume; + cout << "..." << flush; + connectDB( baseName, false, false ); + db = new DatabaseIf(); + if( !strlen(dbVolume) ) + db->createDB( baseName, dbSchema, dbVolume ); + else + db->createDB( baseName, dbSchema ); + disconnectDB( true ); + cout << "ok" << endl; + break; + case M_DELDATABASE: + cout << "Deleting database " << baseName << "..."; + TALK( "connecting" ); + connectDB( baseName, false, false ); + TALK( "creating new DatabaseIf" ); + db = new DatabaseIf(); + TALK( "destroying db" ); + db->destroyDB(baseName); + disconnectDB( true ); + cout << "ok" << endl; + break; + case M_PRINT: + connectDB( baseName, true, true ); + printNames(); + disconnectDB( false ); // abort TA - we did only reading + break; + case M_INVALID: + cerr << ERROR_NOACTION << endl; + break; + default: + cerr << ERROR_UNKNOWNACTION << progMode << endl; + } + result = EXIT_SUCCESS; + } + catch ( RasdlError& e) + { + cout << argv[0] << ": " << e.what() << endl; + result = EXIT_FAILURE; + } + catch ( const r_Error& e ) + { + cout << ERROR_RASDAMAN << e.get_errorno() << ": " << e.what() << endl; + result = EXIT_FAILURE; + } + catch (...) + { + cout << argv[0] << " " << ERROR_PANIC << endl; + result = EXIT_FAILURE; + } + + if (result != EXIT_SUCCESS) + disconnectDB(false); + + cout << argv[0] << " done." << endl; + + return( result ); +} diff --git a/rasdl/rasdl_error.cc b/rasdl/rasdl_error.cc new file mode 100644 index 0000000..6544ef1 --- /dev/null +++ b/rasdl/rasdl_error.cc @@ -0,0 +1,124 @@ +/* +* This file is part of rasdaman community. +* +* Rasdaman community is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* Rasdaman community is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with rasdaman community. If not, see . +* +* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann / +rasdaman GmbH. +* +* For more information please see +* or contact Peter Baumann via . +*/ +/************************************************************* + * + * + * PURPOSE: + * + * + * COMMENTS: + * + ************************************************************/ + +using namespace std; + +static const char rcsid[] = "@(#)raslib, RasdlError: $Id: rasdl_error.cc,v 1.1 2003/12/19 17:11:59 rasdev Exp $"; + +#include +#include + +// for sprintf(): +#include + +#include "rasdl_error.hh" + +// debug facility; relies on -DDEBUG at compile time +#include "debug.hh" + +/// error object, carrying int error code +RasdlError::RasdlError( unsigned int e ) +{ + TALK( "Exception: " << e ); + errno = e; +} + +/// default destructor +RasdlError::~RasdlError() +{ +} + +/// print error message (including error code) +/// NB: not all messages can occur +const char* +RasdlError::what() +{ + const char *errorMsg; + switch (errno) + { + case CANNOTALLOC: + errorMsg = "Cannot allocate memoery."; + break; + case CANNOTWRITEHDR: + errorMsg = "Cannot write header file."; + break; + case NOCONNECTION: + errorMsg = "Cannot connect to database."; + break; + case EMPTYTYPENAME: + errorMsg = "Typename is empty."; + break; + case ILLEGALREADCOMBI: + errorMsg = "Parameter -r only in conjunction with -i or --hh."; + break; + case ODLFILEFAILED: + errorMsg = "Cannot access type definition file."; + break; + case ODLPARSEERROR: + errorMsg = "Syntax error in type definition file."; + break; + case ILLEGALHHCOMBI: + errorMsg = "Parameter -hh requires -r."; + break; + case ILLEGALINSERTCOMBI: + errorMsg = "Parameter -i requires -r."; + break; + case CMDLINE: + errorMsg = "Syntax error in command line."; + break; + default : + errorMsg = "Unknown error code."; + break; + case ALLDONE: + case 0: + errorMsg = "No errors."; + } + +// size of error text buffer below +#define ERRTEXT_BUFSIZ 200 + + static char errorText[ERRTEXT_BUFSIZ]; + +// text constants for error msg +#define MODULE_TAG "DL" +#define ERROR_TEXT " Error: " + + // check for buffer overflow + if (strlen(MODULE_TAG) + 3 + strlen(ERROR_TEXT) + strlen(errorMsg) + 1 > ERRTEXT_BUFSIZ) + sprintf( errorText, "%s%03d%s", MODULE_TAG, errno, "(error message too long, cannot display)" ); + else + sprintf( errorText, "%s%03d%s%s", MODULE_TAG, errno, ERROR_TEXT, errorMsg ); + + return errorText; +} // what() + + diff --git a/rasdl/rasdl_error.hh b/rasdl/rasdl_error.hh new file mode 100644 index 0000000..7e69ffb --- /dev/null +++ b/rasdl/rasdl_error.hh @@ -0,0 +1,77 @@ +/* +* This file is part of rasdaman community. +* +* Rasdaman community is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* Rasdaman community is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with rasdaman community. If not, see . +* +* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann / +rasdaman GmbH. +* +* For more information please see +* or contact Peter Baumann via . +*/ +/************************************************************* + * + * + * COMMENTS: + * + ************************************************************/ + +#ifndef _RASQL_ERROR_HH_ +#define _RASQL_ERROR_HH_ + +#ifdef __VISUALC__ +#pragma warning( disable : 4290 ) +#endif + +//@ManMemo: Module: {\bf raslib} + +/*@Doc: + + This class ... +*/ + + + /// valid error codes: +#define ALLDONE -1 +#define OK 0 +#define CANNOTALLOC 1 +#define CANNOTWRITEHDR 2 +#define NOCONNECTION 3 +#define EMPTYTYPENAME 4 +#define ILLEGALREADCOMBI 5 +#define ODLFILEFAILED 6 +#define ODLPARSEERROR 7 +#define ILLEGALHHCOMBI 8 +#define ILLEGALINSERTCOMBI 9 +#define CMDLINE 10 + +class RasdlError // : public std::exception +{ + public: + + /// constructor receiving an error number + RasdlError( unsigned int e ); + + /// destructor + virtual ~RasdlError(); + + /// get an error description + virtual const char * what(); + + private: + /// error information + unsigned int errno; +}; + +#endif // _RASQL_ERROR_HH_ diff --git a/rasdl/rasdlgrammar.html b/rasdl/rasdlgrammar.html new file mode 100644 index 0000000..73c2b2d --- /dev/null +++ b/rasdl/rasdlgrammar.html @@ -0,0 +1,27 @@ + + + + RasDaMan: Specification + + + + + + +

[RasDaMan-Logo]Implementation +Specification: RasDL Grammar

+ +

The following grammar specifies RasDL.

+ +
+
+
+
+
+ +


+ +

Roland Ritsch, 1997-09-10

+ + + \ No newline at end of file diff --git a/rasdl/symbtbl.cc b/rasdl/symbtbl.cc new file mode 100644 index 0000000..02c6dfc --- /dev/null +++ b/rasdl/symbtbl.cc @@ -0,0 +1,305 @@ +/* +* This file is part of rasdaman community. +* +* Rasdaman community is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* Rasdaman community is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with rasdaman community. If not, see . +* +* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann / +rasdaman GmbH. +* +* For more information please see +* or contact Peter Baumann via . +*/ +/************************************************************* + * + * + * PURPOSE: + * + * + * COMMENTS: + * The internal functions return 0 on error, 1 on success. Not really common, + * but it was used in some routines and so I stuck with it. Norbert 25-05-2001. + * + ************************************************************/ + +#include "symbtbl.hh" + +#include "raslib/rmdebug.hh" + +#include "debug/debug.hh" + +YSymbol::YSymbol() +{ + TALK( "YSymbol::YSymbol default constructor" ); + + name =NULL; + next =NULL; + owned_by_symbol=true; // by default symbols owned by symbols + + scope =NULL; + defines =NULL; +}; + +YSymbol::YSymbol(const char*_name) +{ + TALK( "YSymbol::YSymbol constructor, name=" << name ); + + name =_name; + next =NULL; + owned_by_symbol=true; // by default symbols owned by symbols + + scope =NULL; + defines =NULL; +}; + +YSymbolTable::YSymbolTable() +{ + TALK( "YSymbolTable::YSymbolTable default constructor" ); + + scope =NULL; + global_scope =NULL; +}; + +void YSymbolTable::push_scope(YSymbol*owner) +{ + Scope *new_scope=new Scope; + + new_scope->up =scope; + new_scope->son =NULL; + new_scope->symbols =NULL; + new_scope->last_symbol =NULL; + new_scope->owner =owner; + + if(scope!=NULL) + { + new_scope->next =scope->son; + scope->son =new_scope; + + owner->defines =new_scope; + } + else + { + new_scope->next =NULL; + }; + + if(owner==NULL) + global_scope=new_scope; + + scope=new_scope; +}; + +const YSymbol *YSymbolTable::pop_scope() +{ + const YSymbol *old_symbol =scope->owner; + scope =scope->up; + + return(old_symbol); +}; + +void YSymbolTable::insert_symbol(YSymbol*symbol)const +{ + ENTER( "YSymbolTable::insert_symbol" ); + + if(scope!=NULL) + { + TALK( "adding symbol " << symbol->get_name() ); + if(scope->last_symbol==NULL) + scope->symbols=symbol; + else + scope->last_symbol->next=symbol; + + scope->last_symbol = symbol; + + symbol->next = NULL; + symbol->scope = scope; + } + + LEAVE( "YSymbolTable::insert_symbol" ); +}; + +bool YSymbolTable::search_this_scope(const char*name,const Scope*this_scope,YSymbol*&result)const +{ + ENTER( "YSymbolTable::search_this_scope" ); + + bool found = false; + + if((name==NULL)||(this_scope==NULL)) + found = false; /* no name or no scope */ + else + { + for(YSymbol*scan=this_scope->symbols;scan!=NULL && found!=true;scan=scan->next) + { + if(!strcmp(name,scan->name)) + { + result=scan; + found = true; + } + } + } + + LEAVE( "YSymbolTable::search_this_scope -> " << found ); + return( found ); +}; + +bool YSymbolTable::search_scope(const char*name,YSymbol*&result)const +{ + return(search_this_scope(name,scope,result)); +}; + +bool YSymbolTable::search_scopes(const char*name,YSymbol*&result)const +{ + for(Scope*scan=scope;scan!=NULL;scan=scan->up) + { + if(search_this_scope(name,scan,result)) + return(true); + }; + return(false); +}; + +bool YSymbolTable::search_scopes_above(const YSymbol*symbol,YSymbol*&result)const +{ + const char*name=symbol->get_name(); + if(symbol->scope==NULL) + return(false); + + for(Scope*scan=scope->up;scan!=NULL;scan=scan->up) + { + if(search_this_scope(name,scan,result)) + return(true); + }; + return(false); +}; + +bool YSymbolTable::search_my_scope(const char*name,const YSymbol*symbol,YSymbol*&result)const +{ + return(search_this_scope(name,symbol->defines,result)); +}; + +bool YSymbolTable::search_global_scope(const char*name,YSymbol*&result)const +{ + if(scope==NULL) + return(false); /* no scope at all */ + + Scope*global; + for(global=scope;global->up!=NULL;global=global->up) + ; /* get up to the global scope */ + + return(search_this_scope(name,global,result)); +}; + +//**************************************************************************** +// +// name : get_symbol +// purpose : returns symbol of name in current scope +// remarks : returns NULL if no such symbol defined +// +//**************************************************************************** +const YSymbol *YSymbolTable::get_symbol(const char*name)const +{ + YSymbol*result; + if(search_scope(name,result)) + return(result); + else + return(NULL); +}; + +//**************************************************************************** +// +// name : scoped_symbol +// purpose : creates symbol name within current scope +// remarks : returns true if success full and false if name already exists +// *result is always been changed to new or defined symbol +// +//**************************************************************************** +bool YSymbolTable::scoped_symbol(YSymbol**result,const char*name,const YWhere&where) +{ + if(search_scope(name,*result)) + return(false); // duplicate identifier + + *result=new YSymbol(name); + (*result)->where =where; + + insert_symbol(*result); + return(true); +}; + +const YSymbol *YSymbolTable::get_defining_symbol()const +{ + if(scope==NULL) + return(NULL); + else + return(scope->owner); +}; + + + +void YSymbolTable::Scope::output(FILE*out)const +{ + ENTER( "YSymbolTable::Scope::output" ); + + YSymbol *scan=symbols; + + while (scan!=NULL) + { + if(!scan->owned_by_symbol) + { + fprintf(out,"/*[%li,%i]*/",scan->where.line,scan->where.column); + + switch(scan->type) + { + case YSymbol::dParse_Type: + scan->Type->output(out); + break; + case YSymbol::dParse_Enumerator: + scan->enumerator->output(out); + break; + default: + RMDBGONCE(0, RMDebug::module_rasdl, "YSymbolTable::Scope", "output() bad YSymbol_type " << scan->type); + break; + } + } + scan=(YSymbol*)scan->next; + } + + LEAVE( "YSymbolTable::Scope::output" ); +}; + + +void YSymbolTable::Scope::insertData() const +{ + ENTER( "YSymbolTable::Scope::insertData" ); + + YSymbol *scan=symbols; + + while(scan!=NULL) + { + if(!scan->owned_by_symbol) + { + switch(scan->type) + { + case YSymbol::dParse_Type: + scan->Type->insertData(); + break; + case YSymbol::dParse_Enumerator: + // scan->enumerator->output(out); + break; + default: + RMDBGONCE(0, RMDebug::module_rasdl, "YSymbolTable::Scope", "output() bad YSymbol_type " << scan->type); + break; + } + } + scan=(YSymbol*)scan->next; + } + + LEAVE( "YSymbolTable::Scope::insertData" ); +}; diff --git a/rasdl/symbtbl.hh b/rasdl/symbtbl.hh new file mode 100644 index 0000000..ab2c0b4 --- /dev/null +++ b/rasdl/symbtbl.hh @@ -0,0 +1,196 @@ +/* +* This file is part of rasdaman community. +* +* Rasdaman community is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* Rasdaman community is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with rasdaman community. If not, see . +* +* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann / +rasdaman GmbH. +* +* For more information please see +* or contact Peter Baumann via . +*/ +#ifndef __SYMBTABLE_H +#define __SYMBTABLE_H + +#include "parse.hh" + +#include + +class YSymbol; + +//@ManMemo: Module: {\bf rasdl} + +/** + Contains the all the symbols and the scopetree. +*/ +class YSymbolTable { + + friend class YSymbol; + +public: + /// + YSymbolTable(); + + /// get the corresponding symbol to name + const YSymbol *get_symbol(const char*name)const; + /// creates a symbol in the current scoped + bool scoped_symbol(YSymbol**result,const char*name,const YWhere&where); + /// get the symbol that defines this scope + const YSymbol *get_defining_symbol ()const; + + /// search only current scope + bool search_scope (const char*,YSymbol*&)const; + /// search current scope and all abov + bool search_scopes (const char*,YSymbol*&)const; + /// search me all scopes above me, and not myself + bool search_scopes_above (const YSymbol*,YSymbol*&)const; + /// search a specified scope of a symbol + bool search_my_scope (const char*,const YSymbol*,YSymbol*&)const; + /// search the global_scope + bool search_global_scope (const char*,YSymbol*&)const; + + /// + void insert_symbol (YSymbol*)const; + + /// + void push_scope(YSymbol*); + + /// + const YSymbol *pop_scope(); + + /// + struct Scope { + void output(FILE*out) const; + void insertData() const; + + struct Scope *up; + struct Scope *next,*son; + + YSymbol *symbols; + YSymbol *last_symbol; // last symbol defined in list {to assure correct order of symbols} + + const YSymbol *owner; // which symbol is the owner of this scope + }; + + /// + Scope *scope; + + /// + Scope *global_scope; + + /// + inline bool search_this_scope (const char*,const Scope*,YSymbol*&)const; + +}; + + + +//@ManMemo: Module: {\bf rasdl} + +/** + Literal used during parse process for result of an expression. +*/ +struct YLiteral { + /// + enum Literal_type {dLfloat,dLinteger,dLchar,dLbool,dLstring} type; + + /// + union { + /// + double Real; + /// + long Integer; + /// + const char *String; + /// + char Character; + /// + bool Boolean; + }; +}; + + + +//@ManMemo: Module: {\bf rasdl} + +/** + To store constants durng parse process. +*/ +struct YConstant +{ + /// + YLiteral value; + /// + Parse_type *type; +}; + + + +//@ManMemo: Module: {\bf rasdl} + +/** + Defines a symbol during parsing. It can represent various types of data. +*/ +class YSymbol +{ + friend class YSymbolTable; + +public: + /// + YSymbol(); + /// + YSymbol(const char*); + + /// + const char *get_name()const{return(name);}; + + /// defined where + YWhere where; + /// defines wether this symbol is owned by another symbol or by a scope + bool owned_by_symbol; + +private: + /// + const char *name; + +public: + /// + YSymbol *next; + /// + const YSymbolTable::Scope *scope; + /// + const YSymbolTable::Scope *defines; + + /// + enum YSymbol_type { dParse_Type, + dParse_Attribute, + dParse_Const, + dParse_Function, + dParse_Enumerator} type; + /// + union + { + /// + Parse_type *Type; + /// + Parse_composite::Element *Attribute; + /// + YConstant constant; + + /// + Parse_enum::Enumerator *enumerator; + }; +}; +#endif + diff --git a/rasdl/template_inst.hh b/rasdl/template_inst.hh new file mode 100644 index 0000000..c0b7eae --- /dev/null +++ b/rasdl/template_inst.hh @@ -0,0 +1,83 @@ +/* +* This file is part of rasdaman community. +* +* Rasdaman community is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* Rasdaman community is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with rasdaman community. If not, see . +* +* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann / +rasdaman GmbH. +* +* For more information please see +* or contact Peter Baumann via . +*/ +#include + +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include + +template class DBObjectIterator; +template class DBObjectIterator; +template class DBObjectIterator; +template class DBObjectIterator; +template class DBObjectIdIterator; +template bool operator< (const DBRef&, const DBRef&); + +template class DBRef; +template class DBRef; +template class DBRef; +template class DBRef; +template class DBRef; +template class DBRef; +template class DBRef; +template class DBRef; +template class DBRef; +template class DBRef; +template class DBRef; +template class DBRef; +template class DBRef; +template class DBRef; + +template class r_IterType; + +template class SymbolTable; + +template std::ostream& operator<< (const std::vector&, std::ostream&); +template std::ostream& operator<< (std::ostream &, const std::vector&); +template std::ostream& operator<< (std::ostream &, const std::vector&); + diff --git a/rasdl/test/Makefile b/rasdl/test/Makefile new file mode 100644 index 0000000..765ae1a --- /dev/null +++ b/rasdl/test/Makefile @@ -0,0 +1,78 @@ +# -*-Makefile-*- +# +# This file is part of rasdaman community. +# +# Rasdaman community is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Rasdaman community is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with rasdaman community. If not, see . +# +# Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann / +# rasdaman GmbH. +# +# For more information please see +# or contact Peter Baumann via . +# +# MAKEFILE FOR: +# test programs of module qlparser +# +# COMMENTS: +# +################################################################## +# +# This is just an example Makefile for a test program. +# The dependency of the test program on the lib of the +# corresponding module is in the Makefile of the module. +# + +######################### Definitions ############################ + +# standard include with general options +include $(RMANBASE)/Makefile.inc + +# all test programs +SRCCXX = test_rasdl.cc +OBJS = ${SRCCXX:%.cc=%.o} +ALLTESTS = ${SRCCXX:%.cc=%} +MISCCLEAN = core + +# add compile and link options for STL +CXXFLAGS += $(STLCXXFLAGS) +LDFLAGS += $(STLLDFLAGS) + +########################### Targets ############################## + +# general system test +.PHONY: systemtest +systemtest: + rasdl_test.sh > rasdl_test.log 2>&1 + diff rasdl_test.log rasdl_test.log.orig || (echo deviation found in rasdl test; exit) + +# test target for qlparser +.PHONY : rasdl +rasdl: test_module test_rasdl + +.PHONY : test_module +test_module: + cd $(RMANBASE)/rasdl; $(MAKE) + +test_rasdl: test_rasdl.o $(RASDL) + $(CXX) $(LDFLAGS) -o $@ $^ + +######################## Dependencies ############################ + +test_rasdl.o: test_rasdl.cc + +# general rules +include $(RMANBASE)/Makefile.rel + +# automatically created dependencies +include Makefile.dep diff --git a/rasdl/test/basictypes.dl b/rasdl/test/basictypes.dl new file mode 100644 index 0000000..60c9123 --- /dev/null +++ b/rasdl/test/basictypes.dl @@ -0,0 +1,157 @@ +/* +* This file is part of rasdaman community. +* +* Rasdaman community is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* Rasdaman community is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with rasdaman community. If not, see . +* +* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann / +rasdaman GmbH. +* +* For more information please see +* or contact Peter Baumann via . +*/ +// --------------------------------------------------------------------- +// +// +// PURPOSE: +// This file contains type definitions to challenge the rasdl utilit. +// Rasdl needs to read them and react appropriately. Reports are done +// to stdout. +// +// +// COMMENTS: +// ./. +// +// +// --------------------------------------------------------------------- + + +// --- good defs ------------------------------------------------------- +// --- bad defs -------------------------------------------------------- + + + +// example 1 +typedef marray GreyImage; +typedef set GreySet; + +// example 2 +typedef marray BoolImage; +typedef set BoolSet; + +// example 3 +struct RGBPixel { char red, green, blue; }; +typedef marray RGBImage; +typedef set RGBSet; + +// example 4 +typedef marray ULongImage; +typedef set ULongSet; + +// example 5 +typedef marray GreyCube; +typedef set GreySet3; + + +// heavily expanded types (Andreas) +typedef marray BoolString; +typedef set BoolSet1; + +typedef marray BoolCube; +typedef set BoolSet3; + +typedef marray GreyString; +typedef set GreySet1; + +typedef marray OctetString; +typedef set OctetSet1; + +typedef marray OctetImage; +typedef set OctetSet; + +typedef marray OctetCube; +typedef set OctetSet3; + +typedef marray ShortString; +typedef set ShortSet1; + +typedef marray ShortImage; +typedef set ShortSet; + +typedef marray ShortCube; +typedef set ShortSet3; + +typedef marray UShortString; +typedef set UShortSet1; + +typedef marray UShortImage; +typedef set UShortSet; + +typedef marray UShortCube; +typedef set UShortSet3; + +typedef marray LongString; +typedef set LongSet1; + +typedef marray LongImage; +typedef set LongSet; + +typedef marray LongCube; +typedef set LongSet3; + +typedef marray ULongString; +typedef set ULongSet1; + +typedef marray ULongCube; +typedef set ULongSet3; + +typedef marray RGBString; +typedef set RGBSet1; + +typedef marray RGBCube; +typedef set RGBSet3; + +typedef marray FloatString; +typedef set FloatSet1; + +typedef marray FloatImage; +typedef set FloatSet; + +typedef marray FloatCube; +typedef set FloatSet3; + +typedef marray FloatCube4; +typedef set FloatSet4; + +typedef marray DoubleString; +typedef set DoubleSet1; + +typedef marray DoubleImage; +typedef set DoubleSet; + +typedef marray DoubleCube; +typedef set DoubleSet3; + +typedef marray Gauss1; +typedef set GaussSet1; + +typedef marray Gauss2; +typedef set GaussSet2; + +typedef marray Gauss1Image; +typedef set Gauss1Set; + +typedef marray Gauss2Image; +typedef set Gauss2Set; + +// --- end ----------------------------------------------------------- diff --git a/rasdl/test/rasdl_test.sh b/rasdl/test/rasdl_test.sh new file mode 100644 index 0000000..c465f3a --- /dev/null +++ b/rasdl/test/rasdl_test.sh @@ -0,0 +1,103 @@ +#!/bin/bash -x +# +# This file is part of rasdaman community. +# +# Rasdaman community is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Rasdaman community is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with rasdaman community. If not, see . +# +# Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann / +# rasdaman GmbH. +# +# For more information please see +# or contact Peter Baumann via . +# +# rasdl_test.sh: test rasdl +# +# COMMENTS: +# - deletes and recreates databases, needs base DBMS up and running +# - FIXME: under work +# - bash -x serves to log command lines +# - has local copy of basictypes.dl; keep consistent! +################################################################## + +# program to be tested +RASDL=../rasdl + +# databases to be used (will be destroyed!) +DB1=TESTDB1 +DB2=TESTDB2 + +echo "$0: start rasdl test." + +# help +$RASDL -h +$RASDL --help + +# unknown parameter +$RASDL --unknown +$RASDL -y + +# inconsistent parameters and options +$RASDL -i +$RASDL --hh headerfile +$RASDL + +# --- from here on we need database connection +# clean starting point, result is of no interest +$RASDL --database $DB1 --deldatabase +$RASDL --database $DB2 --deldatabase + +# --- nonex. db + +#delete nonexisting database +$RASDL --database $DB2 --deldatabase + +# fill into nonexisting database +$RASDL --database $DB2 --read basictypes.dl --insert + +# --- good cases + +# create db, regular +$RASDL --database $DB1 --createdatabase + +# create existing database +$RASDL --database $DB1 --createdatabase + +# fill into existing database +$RASDL --database $DB1 --read basictypes.dl --insert + +# print types +$RASDL --database $DB1 --print + +# generate hh file +rm basictypes.hh +$RASDL --database $DB1 --hh basictypes.hh +# for the diff lateron: +cat basictypes.hh + +# delete base type +$RASDL --database $DB1 --delbasetype char +$RASDL --database $DB1 --print + +# delete MDD type +$RASDL --database $DB1 --delmddtype GreyImage +$RASDL --database $DB1 --print + +# delete set type +$RASDL --database $DB1 --delsettype GreySet +$RASDL --database $DB1 --print + +# delete database (cleanup) +$RASDL --database $DB1 --deldatabase + +echo "$0: rasdl test done." diff --git a/rasdl/test/test_rasdl.cc b/rasdl/test/test_rasdl.cc new file mode 100644 index 0000000..9577168 --- /dev/null +++ b/rasdl/test/test_rasdl.cc @@ -0,0 +1,80 @@ +/* +* This file is part of rasdaman community. +* +* Rasdaman community is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* Rasdaman community is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with rasdaman community. If not, see . +* +* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann / +rasdaman GmbH. +* +* For more information please see +* or contact Peter Baumann via . +*/ +// #include +#include +#include +#include + +#include "rasdl/symbtbl.hh" +#include "rasdl/yparse.hh" + +extern int yyparse(); +extern FILE *yyin; +extern YSymbolTable *Symbols; + +int main(int argc,char *argv[]) +{ + if(argc!=3) + { + cerr<<"USAGE: odl odl-script cpp-header"; + exit(-1); + }; + + cout<<"--BEGIN-------------------------------------------------------------------------"; + cout<<"opening \""<global_scope->output(file); + + fclose(file); + + cout<<"done!\n"; + cout<<"--END---------------------------------------------------------------------------"; + + return(0); +}; + diff --git a/rasdl/yparse.hh b/rasdl/yparse.hh new file mode 100644 index 0000000..d8d9615 --- /dev/null +++ b/rasdl/yparse.hh @@ -0,0 +1,59 @@ +/* +* This file is part of rasdaman community. +* +* Rasdaman community is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* Rasdaman community is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with rasdaman community. If not, see . +* +* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann / +rasdaman GmbH. +* +* For more information please see +* or contact Peter Baumann via . +*/ +#ifndef __YPARSE_H +#define __YPARSE_H + +#include "symbtbl.hh" +#include "parse.hh" + +//@ManMemo: Module: {\bf rasdl} + +/** + A list of integers. +*/ +struct rINT_list +{ + /// + int data; + + /// + rINT_list *next; +}; + + +//@ManMemo: Module: {\bf rasdl} + +/** + A list of symbols. +*/ +struct YDeclarator +{ + /// + YSymbol *symbol; + /// + rINT_list *array_size; + /// + YDeclarator *next; +}; + +#endif -- cgit