Gonzalo Tornaria on Tue, 13 Jan 2004 20:43:58 +0100


[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

Patch: default(sopath), default(outputsp[aces])


This is a patch to add two new default's to gp:

1) default(outputsp):

flag that determines if output routines show spaces. Pretty trivial,
just adds a one-line function sd_outputsp() and adds it to
gp_default_list[].

2) default(sopath):

similar to default(path), but for dynamic libraries loaded with
install(). The bulk of it is a function sd_sopath() [almost copied from
sd_path()], and gp_dlopen(), a wrapper for dlopen(). Note that if
default(sopath) is not set, gp_dlopen() defaults to the old dlopen().

Note also that I allow the special path ":" to stand for "" (meaning:
revert back to the old behaviour), since there is no way to set a
default to an empty value!!! (since the argument "" is used to retrieve
the value of the default)

I've only done it for dlopen(), but a similar wrapper should work for
win32 LoadLibrary().

BTW, is it intentional that gp_expand_path() takes empty path components
as if they where "/" ??? I think they should be ignored.
E.g:

? default(path,"/usr:/bin")
   path = "/usr:/bin"
? read("proc")
  ***   error opening input file: proc
                                  ^----
? default(path,"/usr::/bin")
   path = "/usr::/bin"
? read("proc")
  ***   Warning: skipping directory /proc.
  ***   error opening input file: proc

Gonzalo
-- 
GM/CS/S d? a-- C++(+++)  UL+++(++++)  P++>+++  L+++>++++ E---
W-(+) N+(++) w--- O M-(--) V-(--) PGP(--) b++(+++) G++ e>++++

... A mathematician is a machine for converting coffee into theorems.
Index: src/gp/gp.c
===================================================================
RCS file: /home/megrez/cvsroot/pari/src/gp/gp.c,v
retrieving revision 1.217
diff -u -p -u -r1.217 gp.c
--- src/gp/gp.c	19 Dec 2003 11:41:37 -0000	1.217
+++ src/gp/gp.c	13 Jan 2004 19:24:39 -0000
@@ -123,6 +123,15 @@ init_path(gp_path *path)
   path->dirs = NULL;
 }
 
+#ifdef HAS_DLOPEN
+static void
+init_sopath(gp_path *sopath)
+{
+  sopath->PATH = pari_strdup("");
+  sopath->dirs = NULL;
+}
+#endif
+
 static char *
 init_help()
 {
@@ -162,6 +171,9 @@ gp_preinit(void)
   static gp_hist __HIST;
   static gp_pp   __PP;
   static gp_path __PATH;
+#ifdef HAS_DLOPEN
+  static gp_path __SOPATH;
+#endif
   static pari_timer __T;
   long i;
 
@@ -187,10 +199,16 @@ gp_preinit(void)
   GP_DATA->hist = &__HIST;
   GP_DATA->pp   = &__PP;
   GP_DATA->path = &__PATH;
+#ifdef HAS_DLOPEN
+  GP_DATA->sopath = &__SOPATH;
+#endif
   GP_DATA->help = init_help();
   GP_DATA->fmt  = init_fmt();
   init_hist(GP_DATA->hist, 5000, 0);
   init_path(GP_DATA->path);
+#ifdef HAS_DLOPEN
+  init_sopath(GP_DATA->sopath);
+#endif
   init_pp(GP_DATA->pp);
 }
 
@@ -803,6 +821,10 @@ sd_output(const char *v, int flag)
   GP_DATA->fmt->prettyp = n; return z;
 }
 
+static GEN
+sd_outputsp(const char *v, int flag)
+{ return sd_toggle(v,flag,"outputsp", &(GP_DATA->fmt->sp)); }
+
 void
 allocatemem0(size_t newsize)
 {
@@ -949,6 +971,28 @@ sd_path(char *v, int flag)
   return gnil;
 }
 
+#ifdef HAS_DLOPEN
+static GEN
+sd_sopath(char *v, int flag)
+{
+  gp_path *p = GP_DATA->sopath;
+  if (*v)
+  {
+    /* Do not allow an empty first component ! */
+    /* Also, this allows ":" to stand for "empty sopath" */
+    if(*v==':') v++;
+    free((void*)p->PATH);
+    p->PATH = pari_strdup(v);
+    if (flag == d_INITRC) return gnil;
+    gp_expand_path(p);
+  }
+  if (flag == d_RETURN) return STRtoGENstr(p->PATH);
+  if (flag == d_ACKNOWLEDGE)
+    pariputsf("   sopath = \"%s\"\n",p->PATH);
+  return gnil;
+}
+#endif
+
 static GEN
 sd_prettyprinter(char *v, int flag)
 {
@@ -1035,6 +1079,7 @@ default_type gp_default_list[] =
   {"logfile",(void*)sd_logfile},
   {"new_galois_format",(void*)sd_new_galois_format},
   {"output",(void*)sd_output},
+  {"outputsp",(void*)sd_outputsp},
   {"parisize",(void*)sd_parisize},
   {"path",(void*)sd_path},
   {"primelimit",(void*)sd_primelimit},
@@ -1047,6 +1092,9 @@ default_type gp_default_list[] =
   {"secure",(void*)sd_secure},
   {"seriesprecision",(void*)sd_seriesprecision},
   {"simplify",(void*)sd_simplify},
+#ifdef HAS_DLOPEN
+  {"sopath",(void*)sd_sopath},
+#endif
   {"strictmatch",(void*)sd_strictmatch},
   {"TeXstyle",(void *)sd_TeXstyle},
   {"timer",(void *)sd_timer},
@@ -3032,6 +3080,9 @@ main(int argc, char **argv)
   whatnow_fun = whatnow;
   default_exception_handler = gp_exception_handler;
   gp_expand_path(GP_DATA->path);
+#ifdef HAS_DLOPEN
+  gp_expand_path(GP_DATA->sopath);
+#endif
 
   if (!(GP_DATA->flags & QUIET)) gp_head();
   if (A.n)
Index: src/gp/highlvl.c
===================================================================
RCS file: /home/megrez/cvsroot/pari/src/gp/highlvl.c,v
retrieving revision 1.20
diff -u -p -u -r1.20 highlvl.c
--- src/gp/highlvl.c	26 Jun 2003 19:30:52 -0000	1.20
+++ src/gp/highlvl.c	13 Jan 2004 19:24:39 -0000
@@ -32,6 +32,32 @@ extern void kill0(entree *ep);
 #ifdef HAS_DLOPEN
 #include <dlfcn.h>
 
+/* like dlopen, but using default(sopath) */
+void *
+gp_dlopen(char *name, int flag)
+{
+  void *handle;
+  char *s;
+  char **tmp;
+
+  /* if PATH is "", use dlopen */
+  if (!GP_DATA || *(GP_DATA->sopath->PATH)==0)
+    return dlopen(name, flag);
+
+  /* if name contains '/', don't use dir_list */
+  s=name; while (*s && *s != '/' && *s != '\\') s++;
+  if (*s) { return dlopen(name, flag); }
+  for (tmp = GP_DATA->sopath->dirs; *tmp; tmp++)
+  { /* make room for '/' and '\0', try_name frees it */
+    s = gpmalloc(2 + strlen(*tmp) + strlen(name));
+    sprintf(s,"%s/%s",*tmp,name);
+    handle=dlopen(s,flag);
+    if(handle) return handle;
+    dlerror(); /* Clean error message */
+  }
+  return NULL;
+}
+
 void 
 install0(char *name, char *code, char *gpname, char *lib)
 {
@@ -53,7 +79,7 @@ install0(char *name, char *code, char *g
 #define RTLD_GLOBAL 0
 #endif
 
-  handle = dlopen(lib,RTLD_LAZY|RTLD_GLOBAL);
+  handle = gp_dlopen(lib,RTLD_LAZY|RTLD_GLOBAL);
 
   if (!handle)
   {
Index: src/language/anal.h
===================================================================
RCS file: /home/megrez/cvsroot/pari/src/language/anal.h,v
retrieving revision 1.39
diff -u -p -u -r1.39 anal.h
--- src/language/anal.h	10 Dec 2003 16:13:30 -0000	1.39
+++ src/language/anal.h	13 Jan 2004 19:24:40 -0000
@@ -315,6 +315,9 @@ typedef struct {
   ulong flags, lim_lines;
   char *help;
   pari_timer *T;
+#ifdef HAS_DLOPEN
+  gp_path *sopath;
+#endif
 } gp_data;
 
 extern gp_data *GP_DATA;