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
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list