summaryrefslogtreecommitdiffstats
path: root/rasdl
diff options
context:
space:
mode:
authorConstantin Jucovschi <cj@ubuntu.localdomain>2009-04-24 07:20:22 -0400
committerConstantin Jucovschi <cj@ubuntu.localdomain>2009-04-24 07:20:22 -0400
commit8f27e65bddd7d4b8515ce620fb485fdd78fcdf89 (patch)
treebd328a4dd4f92d32202241b5e3a7f36177792c5f /rasdl
downloadrasdaman-upstream-8f27e65bddd7d4b8515ce620fb485fdd78fcdf89.tar.gz
rasdaman-upstream-8f27e65bddd7d4b8515ce620fb485fdd78fcdf89.tar.xz
rasdaman-upstream-8f27e65bddd7d4b8515ce620fb485fdd78fcdf89.zip
Initial commitv8.0
Diffstat (limited to 'rasdl')
-rw-r--r--rasdl/Makefile.am70
-rw-r--r--rasdl/alloca.cc530
-rw-r--r--rasdl/lex.ll240
-rw-r--r--rasdl/odl.yy631
-rw-r--r--rasdl/parse.cc996
-rw-r--r--rasdl/parse.hh748
-rw-r--r--rasdl/rasdl.awk11
-rw-r--r--rasdl/rasdl.cc724
-rw-r--r--rasdl/rasdl_error.cc124
-rw-r--r--rasdl/rasdl_error.hh77
-rw-r--r--rasdl/rasdlgrammar.html27
-rw-r--r--rasdl/symbtbl.cc305
-rw-r--r--rasdl/symbtbl.hh196
-rw-r--r--rasdl/template_inst.hh83
-rw-r--r--rasdl/test/Makefile78
-rw-r--r--rasdl/test/basictypes.dl157
-rw-r--r--rasdl/test/rasdl_test.sh103
-rw-r--r--rasdl/test/test_rasdl.cc80
-rw-r--r--rasdl/yparse.hh59
19 files changed, 5239 insertions, 0 deletions
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 <http://www.gnu.org/licenses/>.
+#
+# Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+# rasdaman GmbH.
+#
+# For more information please see <http://www.rasdaman.org>
+# or contact Peter Baumann via <baumann@rasdaman.com>.
+#
+# 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 <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+#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 <jot@cray.com> 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 <config.h>
+#endif
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#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 <stdio.h>
+#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 <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+//==============================================================================
+//
+// NAME: ODL.lex
+//
+//
+// DESCRIPTION : Pattern description for lexical analyzer generators.
+//
+//==============================================================================
+
+#include <string.h>
+#include <stdlib.h>
+
+#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
+
+%%
+
+<INITIAL,Comment>"/*" {
+ if(commentLevel++<1)
+ BEGIN(Comment);
+
+ columnNumber+=2;
+ }
+<Comment>"*/" {
+ if(--commentLevel==0)
+ BEGIN(INITIAL);
+
+ columnNumber+=2;
+ }
+<Comment>\n {
+ lineNumber++;
+ columnNumber=1;
+ }
+<Comment>. {
+ 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 <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+//==============================================================================
+//
+//
+//
+// DESCRIPTION : Grammar description used to parse ODL files.
+//
+//==============================================================================
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream>
+
+#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 <Entry> Identifier
+%token <LEX_integer> IntegerLiteral
+
+%token <Command> 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<dummyValue> model,specification,definition;
+%type <Literal> literal,primary_expr
+%type <element> member,member_list
+%type <Symbol> scoped_name
+// enum_name
+%type <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> declarator,declarators,simple_declarator
+
+%type <dimension> dimension_spec
+%type <domainSpec> opt_spatial_domain
+%type <domain> 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)*/
+/*<Symbol>*/
+scoped_name : Identifier
+ {
+ if(!Symbols->search_scopes($1.name,$$))
+ error_arg("undefined symbol[%s]",$1.name,&$1.where);
+ }
+
+/*(23)*/
+/*<Literal>*/
+primary_expr : literal { $$ = $1; }
+
+/*(24)*/
+/*<Literal>*/
+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>*/
+type_spec : simple_type_spec
+ | constr_type_spec
+ {
+ Parse_typereference *reference=new Parse_typereference;
+ reference->type=$1;
+ reference->setParseInfo( $1->getParseInfo() );
+
+ $$=reference;
+ }
+
+/*(30)*/
+/*<Type>*/
+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)*/
+/*<Type>*/
+base_type_spec : floating_pt_type
+ | integer_type
+ | char_type
+ | boolean_type
+ | octet_type
+ | complex1_type
+ | complex2_type
+
+/*(32)*/
+/*<Type>*/
+template_type_spec : collection_type
+ | marray_type
+
+/*(32a)*/
+/*<Type>*/
+collection_type : SET LEFT simple_type_spec RIGHT
+ {
+ $$=new Parse_set;
+ $$->setParseInfo( Parse_info( $1.where, "Set" ) );
+ ((Parse_set*)$$)->base_type=$3;
+ };
+
+/*(33)*/
+/*<Type>*/
+constr_type_spec : struct_type
+
+/*(34)*/
+/*<Declarator>*/
+declarators : declarator
+ | declarator COMMA declarators
+ {
+ $1->next =$3;
+ $$ =$1;
+ };
+
+/*(35)*/
+/*<Declarator>*/
+declarator : simple_declarator
+
+/*(36)*/
+/*<Declarator>*/
+simple_declarator : Identifier
+ {
+ YSymbol *symbol=unique_symbol($1.name,$1.where);
+
+ $$=new YDeclarator;
+ $$->next =NULL;
+ $$->symbol =symbol;
+ $$->array_size =NULL;
+ }
+
+/*(38)*/
+/*<Type>*/
+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)*/
+/*<Type>*/
+integer_type : signed_int
+ | unsigned_int
+
+/*(40)*/
+/*<Type>*/
+signed_int : signed_long_int
+ | signed_short_int
+
+/*(41)*/
+/*<Type>*/
+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)*/
+/*<Type>*/
+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)*/
+/*<Type>*/
+unsigned_int : unsigned_long_int
+ | unsigned_short_int
+
+/*(44)*/
+/*<Type>*/
+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)*/
+/*<Type>*/
+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)*/
+/*<Type>*/
+char_type : PCHAR
+ {
+ $$=new Parse_char;
+ $$->setParseInfo( Parse_info( $1.where, "char") );
+ }
+
+/*(47)*/
+/*<Type>*/
+boolean_type : PBOOLEAN
+ {
+ $$=new Parse_boolean;
+ $$->setParseInfo( Parse_info( $1.where, "boolean") );
+ }
+
+/*(48)*/
+/*<Type>*/
+octet_type : POCTET
+ {
+ $$=new Parse_octet;
+ $$->setParseInfo( Parse_info( $1.where, "octet") );
+ }
+
+/*(48a)*/
+/*<Type>*/
+complex1_type : PCOMPLEX1
+ {
+ $$=new Parse_complex1;
+ $$->setParseInfo( Parse_info( $1.where, "complex") );
+ }
+
+
+/*(48b)*/
+/*<Type>*/
+complex2_type : PCOMPLEX2
+ {
+ $$=new Parse_complex2;
+ $$->setParseInfo( Parse_info( $1.where, "complexd") );
+ }
+
+/*(50)*/
+/*<Type>*/
+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)*/
+/*<Element>*/
+member_list : member
+ | member member_list
+ {
+ Parse_composite::Element *scan=$1;
+ while(scan->next!=NULL)
+ scan=scan->next;
+
+ scan->next=$2;
+ $$=$1;
+ }
+
+/*(52)*/
+/*<Element>*/
+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)*/
+/*<Type>*/
+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;
+ }
+
+/*<Type>*/
+opt_marray_base : { $$=NULL; }
+ | simple_type_spec
+
+/*<domain>*/
+opt_spatial_domain : { $$.domain=NULL; $$.dimensionality = 0; }
+ | COMMA primary_expr { $$.domain=NULL; $$.dimensionality = $2.Integer; }
+ | COMMA spatial_domain { $$.domain=$2; $$.dimensionality = 0; };
+
+/*(76)*/
+/*<domain>*/
+spatial_domain : LEPAR dimension_spec_list REPAR { $$ = $2; }
+
+
+/*(77)*/
+/*<dimension>*/
+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>*/
+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 "<<error_where->line<<" colmun "<<error_where->column;
+
+ if(error_where->file!=NULL)
+ std::cerr<<" in \""<<error_where->file<<"\"";
+
+ std::cerr<<".\n";
+ }
+ else
+ std::cerr<<"\n near : line "<<lineNumber<<" column "<<columnNumber<<".\n";
+
+ if(error_token!=NULL)
+ std::cerr<<"at token <"<<error_token<<"> ";
+
+ std::cerr<<"error : "<<s<<".\n";
+
+ if(error_source!=NULL)
+ {
+ std::cerr<<"source: line "<<error_source->line<<" column "<<error_source->column;
+
+ if(error_source->file!=NULL)
+ std::cerr<<" in \""<<error_source->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 <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+#include "rasdl/parse.hh"
+#include "symbtbl.hh"
+#include "yparse.hh"
+
+#include <stdlib.h>
+
+#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;/*<forward definition>*/\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,"<none>");
+ 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_Set<r_Ref<");
+ base_type->output(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 <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+#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 <stdio.h>
+
+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 <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+/*************************************************************
+ *
+ *
+ * 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 <iostream> // cout
+#include <sstream> // cout
+#include <iomanip>
+#include <set>
+#include <map>
+using namespace std;
+
+#include <stdio.h> // fopen, perror
+#include <stdlib.h> // for atol()
+#include <string.h>
+#include <ctype.h>
+#include <sys/times.h> // 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 "<db-name> name of the database"
+
+#define PARAM_BASENAME "basename"
+#define HELP_BASENAME "<db-name> 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 "<file> read data definition file"
+
+#define PARAM_DELBASETYPE "delbasetype"
+#define HELP_DELBASETYPE "<base-name> delete base type with name <base-name>"
+
+#define PARAM_DELMDDTYPE "delmddtype"
+#define HELP_DELMDDTYPE "<mdd-name> delete mdd type with name <mdd-name>"
+
+#define PARAM_DELSETTYPE "delsettype"
+#define HELP_DELSETTYPE "<set-name> delete set type with name <set-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 "<hh-file> print C++ header into <hh-file> (requires -r)"
+
+#define PARAM_CONNECT "connect"
+#define HELP_CONNECT "<connect-str> 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<StructType> 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<MDDType> 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<SetType> 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", "<sch-name> name of o2 schema used for new bases", "RasDaSchema");
+ CommandLineParameter &cmlVolumeDb = cmlInter.addStringParameter(CommandLineParser::noShortName, "volume", "<vol-name> 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 <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+/*************************************************************
+ *
+ *
+ * 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 <exception>
+#include <cstring>
+
+// for sprintf():
+#include <stdio.h>
+
+#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 <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+/*************************************************************
+ *
+ *
+ * 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 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
+<HTML>
+<HEAD>
+ <TITLE>RasDaMan: Specification</TITLE>
+ <META NAME="GENERATOR" CONTENT="Mozilla/3.0b6Gold (X11; I; HP-UX B.10.01 9000/770) [Netscape]">
+</HEAD>
+<BODY>
+
+<!-- BASE HREF=http://www.forwiss.tu-muenchen.de/ -->
+
+<H1><IMG SRC="/public/forwiss/projekte/rasdaman/rmanlogo-s.gif" ALT="[RasDaMan-Logo]" >Implementation
+Specification: RasDL Grammar</H1>
+
+<P>The following grammar specifies RasDL.</P>
+
+<PRE>
+
+<grammar>
+
+</PRE>
+
+<P><HR WIDTH="100%"></P>
+
+<P><A HREF="mailto:ritsch@forwiss.tu-muenchen.de">Roland Ritsch</A>, 1997-09-10</P>
+
+</BODY>
+</HTML> \ 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 <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+/*************************************************************
+ *
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+#ifndef __SYMBTABLE_H
+#define __SYMBTABLE_H
+
+#include "parse.hh"
+
+#include <string.h>
+
+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 <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+#include <qlparser/symtab.hh>
+
+#include <raslib/itertype.hh>
+#include <raslib/attribute.hh>
+#include <raslib/dlist.hh>
+
+#include <indexmgr/keyobject.hh>
+
+#include <reladminif/dbref.hh>
+#include <reladminif/dbobjectiterator.hh>
+#include <reladminif/dbobjectiditerator.hh>
+#include <reladminif/dbobject.hh>
+
+#include <relblobif/dbtile.hh>
+#include <relblobif/blobtile.hh>
+#include <relblobif/inlinetile.hh>
+
+#include <relcatalogif/structtype.hh>
+#include <relcatalogif/settype.hh>
+#include <relcatalogif/mddtype.hh>
+#include <relcatalogif/dbminterval.hh>
+
+#include <relindexif/hierindex.hh>
+#include <relindexif/dbrcindexds.hh>
+#include <relindexif/dbtcindex.hh>
+
+#include <relmddif/dbmddobj.hh>
+#include <relmddif/dbmddset.hh>
+
+#include <relstorageif/dbstoragelayout.hh>
+
+template class DBObjectIterator<SetType>;
+template class DBObjectIterator<StructType>;
+template class DBObjectIterator<MDDType>;
+template class DBObjectIterator<DBMDDObj>;
+template class DBObjectIdIterator<DBMDDObj>;
+template bool operator< (const DBRef<DBMDDObj>&, const DBRef<DBMDDObj>&);
+
+template class DBRef<DBTile>;
+template class DBRef<InlineTile>;
+template class DBRef<BLOBTile>;
+template class DBRef<DBObject>;
+template class DBRef<DBMDDObj>;
+template class DBRef<DBMDDSet>;
+template class DBRef<DBHierIndex>;
+template class DBRef<DBTCIndex>;
+template class DBRef<DBRCIndexDS>;
+template class DBRef<DBMinterval>;
+template class DBRef<StructType>;
+template class DBRef<MDDType>;
+template class DBRef<SetType>;
+template class DBRef<DBStorageLayout>;
+
+template class r_IterType<r_Attribute>;
+
+template class SymbolTable<int>;
+
+template std::ostream& operator<< (const std::vector<KeyObject>&, std::ostream&);
+template std::ostream& operator<< (std::ostream &, const std::vector<KeyObject>&);
+template std::ostream& operator<< (std::ostream &, const std::vector<double>&);
+
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 <http://www.gnu.org/licenses/>.
+#
+# Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+# rasdaman GmbH.
+#
+# For more information please see <http://www.rasdaman.org>
+# or contact Peter Baumann via <baumann@rasdaman.com>.
+#
+# 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 <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+// ---------------------------------------------------------------------
+//
+//
+// 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 <char,2> GreyImage;
+typedef set<GreyImage> GreySet;
+
+// example 2
+typedef marray <boolean,2> BoolImage;
+typedef set<BoolImage> BoolSet;
+
+// example 3
+struct RGBPixel { char red, green, blue; };
+typedef marray <RGBPixel,2> RGBImage;
+typedef set<RGBImage> RGBSet;
+
+// example 4
+typedef marray <unsigned long, 2> ULongImage;
+typedef set<ULongImage> ULongSet;
+
+// example 5
+typedef marray <char, 3> GreyCube;
+typedef set<GreyCube> GreySet3;
+
+
+// heavily expanded types (Andreas)
+typedef marray <boolean, 1> BoolString;
+typedef set<BoolString> BoolSet1;
+
+typedef marray <boolean, 3> BoolCube;
+typedef set<BoolCube> BoolSet3;
+
+typedef marray <char, 1> GreyString;
+typedef set<GreyString> GreySet1;
+
+typedef marray <octet, 1> OctetString;
+typedef set<OctetString> OctetSet1;
+
+typedef marray <octet, 2> OctetImage;
+typedef set<OctetImage> OctetSet;
+
+typedef marray <octet, 3> OctetCube;
+typedef set<OctetCube> OctetSet3;
+
+typedef marray <short, 1> ShortString;
+typedef set<ShortString> ShortSet1;
+
+typedef marray <short, 2> ShortImage;
+typedef set<ShortImage> ShortSet;
+
+typedef marray <short, 3> ShortCube;
+typedef set<ShortCube> ShortSet3;
+
+typedef marray <unsigned short, 1> UShortString;
+typedef set<UShortString> UShortSet1;
+
+typedef marray <unsigned short, 2> UShortImage;
+typedef set<UShortImage> UShortSet;
+
+typedef marray <unsigned short, 3> UShortCube;
+typedef set<UShortCube> UShortSet3;
+
+typedef marray <long, 1> LongString;
+typedef set<LongString> LongSet1;
+
+typedef marray <long, 2> LongImage;
+typedef set<LongImage> LongSet;
+
+typedef marray <long, 3> LongCube;
+typedef set<LongCube> LongSet3;
+
+typedef marray <unsigned long, 1> ULongString;
+typedef set<ULongString> ULongSet1;
+
+typedef marray <unsigned long, 3> ULongCube;
+typedef set<ULongCube> ULongSet3;
+
+typedef marray <RGBPixel, 1> RGBString;
+typedef set<RGBString> RGBSet1;
+
+typedef marray <RGBPixel, 3> RGBCube;
+typedef set<RGBCube> RGBSet3;
+
+typedef marray <float, 1> FloatString;
+typedef set<FloatString> FloatSet1;
+
+typedef marray <float, 2> FloatImage;
+typedef set<FloatImage> FloatSet;
+
+typedef marray <float, 3> FloatCube;
+typedef set<FloatCube> FloatSet3;
+
+typedef marray <float, 4> FloatCube4;
+typedef set<FloatCube4> FloatSet4;
+
+typedef marray <double, 1> DoubleString;
+typedef set<DoubleString> DoubleSet1;
+
+typedef marray <double, 2> DoubleImage;
+typedef set<DoubleImage> DoubleSet;
+
+typedef marray <double, 3> DoubleCube;
+typedef set<DoubleCube> DoubleSet3;
+
+typedef marray <complex, 1> Gauss1;
+typedef set<Gauss1> GaussSet1;
+
+typedef marray<complexd, 1> Gauss2;
+typedef set<Gauss2> GaussSet2;
+
+typedef marray <complex, 2> Gauss1Image;
+typedef set<Gauss1Image> Gauss1Set;
+
+typedef marray<complexd, 2> Gauss2Image;
+typedef set<Gauss2Image> 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 <http://www.gnu.org/licenses/>.
+#
+# Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+# rasdaman GmbH.
+#
+# For more information please see <http://www.rasdaman.org>
+# or contact Peter Baumann via <baumann@rasdaman.com>.
+#
+# 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 <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+// #include <conio.h>
+#include <iostream>
+#include <stdio.h>
+#include <stdlib.h>
+
+#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 \""<<argv[1]<<"\"...";
+ yyin=fopen(argv[1],"r");
+
+ if(yyin==NULL)
+ {
+ cout<<"fail!\n";
+ cerr<<"\nfailed to open "<<argv[1]<<".\n";
+
+ exit(-1);
+ };
+
+ cout<<"ok!\n";
+
+ cout<<"parsing...";
+ yyparse();
+ cout<<"done!\n";
+
+ cout<<"output...";
+
+ FILE *file=fopen(argv[2],"wt");
+
+ /* header description */
+ fprintf(file,"//------------------------------------------------------------\n");
+ fprintf(file,"// automatic created C++-header \n");
+ fprintf(file,"//------------------------------------------------------------\n");
+ fprintf(file,"\n");
+
+ Symbols->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 <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+#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