Changeset: 4464c60a81d5 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=4464c60a81d5
Modified Files:
        MonetDB5/src/mal/mal_import.mx
        MonetDB5/src/mal/mal_linker.mx
Branch: default
Log Message:

Add the ability to include directories
(transplanted from daba5234988c72ed2e02a583b15de59895b7901b)


diffs (297 lines):

diff -r 8990c4a0fa19 -r 4464c60a81d5 MonetDB5/src/mal/mal_import.mx
--- a/MonetDB5/src/mal/mal_import.mx    Thu May 13 16:49:39 2010 +0200
+++ b/MonetDB5/src/mal/mal_import.mx    Wed May 12 16:22:44 2010 +0200
@@ -34,7 +34,6 @@
 #include "mal_utils.h"
 
 mal_export void slash_2_dir_sep(str fname);
-mal_export stream *openSourceFile(str fname);
 @-
 The import context is located. If the module already exists, 
 we should silently skip parsing the file. This is handled at the parser level.
@@ -62,23 +61,22 @@
                        *s = DIR_SEP;
 }
 
-stream *
-openSourceFile(str fname)
+static str
+malResolveFile(str fname)
+{
+       char path[PATHLENGTH];
+
+       snprintf(path, PATHLENGTH, "%s", fname);
+       slash_2_dir_sep(path);
+       return MSP_locate_script(path);
+}
+
+static stream *
+malOpenSource(str file)
 {
        stream *fd = NULL;
-       char path[PATHLENGTH];
-       str fullname;
-
-       snprintf(path,PATHLENGTH,"%s",fname);
-       slash_2_dir_sep(path);
-       fullname = MSP_locate_script(path);
-
-       if (fullname) {
-               fd = open_rastream(fullname);
-               GDKfree(fullname);
-       } else {
-               fd = open_rastream(path);
-       }
+       if (file)
+               fd = open_rastream(file);
        return fd;
 }
 
@@ -97,14 +95,14 @@
 {
        stream *fd;
 
-       fd = openSourceFile(name);
+       fd = malOpenSource(name);
        if (stream_errnr(fd) == OPEN_ERROR) {
                stream_destroy(fd);
                throw(MAL, "malInclude", "could not open file: %s", name);
        }
        *fdin = bstream_create(fd, 128 * BLOCK);
-       if( bstream_next(*fdin) < 0)    
-               stream_printf(c->fdout,"!WARNING: could not read %s\n",name);
+       if (bstream_next(*fdin) < 0)
+               stream_printf(c->fdout, "!WARNING: could not read %s\n", name);
        return MAL_SUCCEED;
 }
 
@@ -175,6 +173,8 @@
 malInclude(Client c, str name, int listing)
 {
        str s= MAL_SUCCEED;
+       str filename;
+       str p;
 
        bstream *oldfdin = c->fdin;
        int oldyycur = c->yycur;
@@ -189,16 +189,30 @@
        Module oldnspace = c->nspace;
        Symbol oldprg = c->curprg;
 
-       c->yycur = 0;
        c->prompt = GDKstrdup("");      /* do not produce visible prompts */
        c->promptlength = 0;
        c->listing = listing;
-       c->bak = NULL;
 
        c->fdin = NULL;
-       c->srcFile = name;
-       if ((s = malLoadScript(c, name, &c->fdin)) == 0) 
-               parseMAL(c,c->curprg);
+
+       if ((filename = malResolveFile(name)) != NULL) {
+               name = filename;
+               while ((p = strchr(filename, PATH_SEP)) != NULL) {
+                       *p = '\0';
+                       c->srcFile = filename;
+                       c->yycur = 0;
+                       c->bak = NULL;
+                       if ((s = malLoadScript(c, filename, &c->fdin)) == 0) 
+                               parseMAL(c, c->curprg);
+                       filename = p + 1;
+               }
+               c->srcFile = filename;
+               c->yycur = 0;
+               c->bak = NULL;
+               if ((s = malLoadScript(c, filename, &c->fdin)) == 0) 
+                       parseMAL(c, c->curprg);
+               GDKfree(name);
+       }
 
        @:restoreClient()@
        return s;
@@ -229,24 +243,55 @@
        @:restoreState@
        stream *fd;
        str msg= MAL_SUCCEED;
+       str p;
+       str filename;
 
-       c->yycur = 0;
        c->prompt = GDKstrdup("");      /* do not produce visible prompts */
        c->promptlength = 0;
        c->listing = listing;
-       c->bak = NULL;
 
        c->fdin = NULL;
-       c->srcFile= fname;
-       fd = openSourceFile(fname);
+
+       filename = malResolveFile(fname);
+       if (filename == NULL) {
+               stream_printf(c->fdout, "#WARNING: could not open file: %s\n", 
fname);
+               @:restoreClient3()@
+               @:restoreClient()@
+               return msg;
+       }
+
+       fname = filename;
+       while ((p = strchr(filename, PATH_SEP)) != NULL) {
+               *p = '\0';
+               fd = malOpenSource(filename);
+               if (stream_errnr(fd) == OPEN_ERROR) {
+                       stream_destroy(fd);
+                       stream_printf(c->fdout, "#WARNING: could not open file: 
%s\n",
+                                       filename);
+               } else {
+                       c->srcFile = filename;
+                       c->yycur = 0;
+                       c->bak = NULL;
+                       MSinitClientPrg(c, "user", "main");     /* 
re-initialize context */
+                       MCpushClientInput(c, bstream_create(fd, 128 * BLOCK), 
c->listing, "");
+                       msg = runScenario(c);
+               }
+               filename = p + 1;
+       }
+       fd = malOpenSource(filename);
        if (stream_errnr(fd) == OPEN_ERROR) {
                stream_destroy(fd);
-               stream_printf(c->fdout, "#WARNING: could not open file: %s\n", 
fname);
+               stream_printf(c->fdout, "#WARNING: could not open file: %s\n",
+                               filename);
        } else {
-               MSinitClientPrg(c,"user","main");       /* re-initialize 
context */
-               MCpushClientInput(c, bstream_create(fd, 128 * 
BLOCK),c->listing,"");
+               c->srcFile = filename;
+               c->yycur = 0;
+               c->bak = NULL;
+               MSinitClientPrg(c, "user", "main");     /* re-initialize 
context */
+               MCpushClientInput(c, bstream_create(fd, 128 * BLOCK), 
c->listing, "");
                msg = runScenario(c);
        }
+       GDKfree(fname);
 
        @:restoreClient3()@
        @:restoreClient()@
diff -r 8990c4a0fa19 -r 4464c60a81d5 MonetDB5/src/mal/mal_linker.mx
--- a/MonetDB5/src/mal/mal_linker.mx    Thu May 13 16:49:39 2010 +0200
+++ b/MonetDB5/src/mal/mal_linker.mx    Wed May 12 16:22:44 2010 +0200
@@ -59,6 +59,9 @@
 #define RTLD_NOW_REPORT_ERROR   8
 #endif
 
+#include <sys/types.h> /* opendir */
+#include <dirent.h> /* opendir */
+
 /* #define DEBUG_MAL_LINKER */
 #define MONET64 1
 mal_export MALfcn getAddress(str filename, str modnme, str fcnname,int silent);
@@ -71,7 +74,7 @@
 mal_export int isLoaded(str modulename);
 #endif
 @-
-The MAL module should be compiled with -rdynamic and -ldl.
+The MAL module should be compiled with -rdynamic and -ldl (Linux).
 This enables loading the routines and finding out the address
 of a particular routine.
 The mapping from MAL module.function() identifier to an address is
@@ -83,7 +86,7 @@
 the current directory.
 
 Note, however, that the libraries are reference counted. Although we
-do;t close them until end of session it seems prudent to maintain
+don't close them until end of session it seems prudent to maintain
 the consistency of this counter.
 
 @c
@@ -320,8 +323,14 @@
 The plausible locations of the modules can be designated by
 an environment variable. 
 @c
+static int
+cmpstr(const void *p1, const void *p2)
+{
+       return strcmp(*(char* const*)p1, *(char* const*)p2);
+}
+
 static char *
-locate_file(const char *basename, const char *ext)
+locate_file(const char *basename, const char *ext, const bit recurse)
 {
        char *mod_path = GDKgetenv("monet_mod_path");
        char *fullname;
@@ -342,6 +351,7 @@
                size_t i;
                char *p;
                int fd;
+               DIR *rdir;
 
                if ((p = strchr(mod_path, PATH_SEP)) != NULL) {
                        i = p - mod_path;
@@ -361,6 +371,44 @@
                strncpy(fullname, mod_path, i);
                fullname[i] = DIR_SEP;
                strcpy(fullname + i + 1, basename);
+               /* see if this is a directory, if so, recurse */
+               if (recurse == 1 && (rdir = opendir(fullname)) != NULL) {
+                       struct dirent *e;
+                       str strs[48]; /* hardwired limit */
+                       int lasts = 0;
+                       int c;
+                       /* list *ext, sort, return */
+                       while ((e = readdir(rdir)) != NULL) {
+                               if (strcmp(e->d_name, "..") == 0 || 
strcmp(e->d_name, ".") == 0)
+                                       continue;
+                               if (strcmp(e->d_name + strlen(e->d_name) - 
strlen(ext), ext) == 0) {
+                                       strs[lasts] = 
GDKmalloc(strlen(fullname) +
+                                                       sizeof(DIR_SEP) + 
strlen(e->d_name) + 1);
+                                       sprintf(strs[lasts], "%s%c%s",
+                                                       fullname, DIR_SEP, 
GDKstrdup(e->d_name));
+                                       lasts++;
+                               }
+                               if (lasts >= 48)
+                                       break;
+                       }
+                       (void)closedir(rdir);
+                       if (lasts > 0) {
+                               /* assure that an ordering such as 10_first, 
20_second works */
+                               qsort(strs, lasts, sizeof(char *), cmpstr);
+                               i = 0;
+                               for (c = 0; c < lasts; c++)
+                                       i += strlen(strs[c]) + 1; /* PATH_SEP 
or \0 */
+                               fullname = GDKrealloc(fullname, i);
+                               i = 0;
+                               for (c = 0; c < lasts; c++) {
+                                       strcpy(fullname + i, strs[c]);
+                                       i += strlen(strs[c]);
+                                       fullname[i++] = PATH_SEP;
+                               }
+                               fullname[i - 1] = '\0';
+                               return fullname;
+                       }
+               }
                strcat(fullname + i + 1, ext);
                if ((fd = open(fullname, O_RDONLY)) >= 0) {
                        close(fd);
@@ -379,11 +427,7 @@
 char *
 MSP_locate_script(const char *filename)
 {
-       char *f;
-       f= locate_file(filename, MAL_EXT);
-       if ( f == NULL)
-               f= locate_file(filename, SQL_EXT);
-       return f;
+       return locate_file(filename, MAL_EXT, 1);
 }
 
 char *
@@ -395,7 +439,7 @@
        strcpy(lib_name, SO_PREFIX);
        strcpy(lib_name + strlen(SO_PREFIX), filename);
 
-       fullname = locate_file(lib_name, SO_EXT);
+       fullname = locate_file(lib_name, SO_EXT, 0);
 #ifdef _AIX
        fullname = GDKrealloc(fullname, strlen(fullname) + strlen(lib_name) + 
5);
        strcat(fullname, "(");
_______________________________________________
Checkin-list mailing list
Checkin-list@monetdb.org
http://mail.monetdb.org/mailman/listinfo/checkin-list

Reply via email to