The following patch (against CVS hugs98) adds a new option -S providing
user control over the filename suffixes Hugs looks for.  For example,

        hugs -S.hask,.haskell,

will look for files ending in .hask or .haskell as well as the
usual names.  Suffixes are separated by commas, and as with -P, an
empty component includes the previous suffix list (without which the
above example would fail to read the standard prelude).  The initial
suffix list is ".hs,.lhs" (or ".hs,.lhs,.hsx,.hash" if HSCRIPT is set).
The null suffix is never specified, but it is always tried last.

In addition, if USE_PREPROCESSOR is set and popen() is available, one
can specify programs as preprocessors for particular suffixes, as in

        hugs -S.as=arrowp,.las=arrowpl, Example.as

which means that hugs reads the output of "arrowp Example.as", and similar
things happen to imports.  If USE_PREPROCESSOR is not set or popen() is
unavailable, suffixes with preprocessors are ignored (as they presumably
make no sense without preprocessing).

It's a quick hack, and could be cleaner, but I find it useful.
--------------------------------- cut here --------------------------------
diff -r -u src/connect.h src-new/connect.h
--- src/connect.h       Fri May  5 16:49:52 2000
+++ src-new/connect.h   Thu May 25 10:58:35 2000
@@ -189,8 +189,12 @@
 
 extern Int   cutoff;                   /* Constraint Cutoff depth         */
 
-#if USE_PREPROCESSOR
-extern String preprocessor;             /* preprocessor command            */
+extern int   num_file_suffixes;
+extern String *file_suffix;             /* filename suffix                 */
+
+#if USE_PREPROCESSOR && (defined(HAVE_POPEN) || defined(HAVE__POPEN))
+extern String *file_preprocessor;       /* preprocessors for suffixes      */
+extern String default_preprocessor;     /* default preprocessor command    */
 #endif
 
 #if DEBUG_CODE
@@ -383,5 +387,8 @@
 #if MULTI_INST
 extern  List   findInstsFor     Args((Cell,Int));
 #endif
+
+extern Void   setSuffixes      Args((String));
+extern String getSuffixes      Args((Void));
 
 /*-------------------------------------------------------------------------*/
diff -r -u src/hugs.c src-new/hugs.c
--- src/hugs.c  Sun May 21 17:02:15 2000
+++ src-new/hugs.c      Thu May 25 10:59:50 2000
@@ -222,6 +222,7 @@
     hugsEdit      = strCopy(fromEnv("EDITOR",NULL));
 #endif
     hugsPath      = strCopy(HUGSPATH);
+    setSuffixes(SUFFIXES);
     readOptions("-p\"%s> \" -r$$");
 #if USE_REGISTRY
     projectPath   = strCopy(readRegChildStrings(HKEY_LOCAL_MACHINE,ProjectRoot,
@@ -340,8 +341,9 @@
     Printf(fmts,"Pstr","Set search path for modules to str");
     Printf(fmts,"Estr","Use editor setting given by str");
     Printf(fmts,"cnum","Set constraint cutoff limit");
+    Printf(fmts,"Sstr","Set source file suffixes");
 #if USE_PREPROCESSOR  && (defined(HAVE_POPEN) || defined(HAVE__POPEN))
-    Printf(fmts,"Fstr","Set preprocessor filter to str");
+    Printf(fmts,"Fstr","Set default preprocessor filter to str");
 #endif
 #if PROFILING
     Printf(fmts,"dnum","Gather profiling statistics every <num> reductions\n");
@@ -363,9 +365,15 @@
     }
     Printf("\nEditor setting  : -E");
     printString(hugsEdit);
+    Printf("\nFile suffixes   : -S");
+    {
+        String s = getSuffixes();
+        printString(s);
+        free(s);
+    }
 #if USE_PREPROCESSOR  && (defined(HAVE_POPEN) || defined(HAVE__POPEN))
     Printf("\nPreprocessor    : -F");
-    printString(preprocessor);
+    printString(default_preprocessor);
 #endif
 #if PROFILING
     Printf("\nProfile interval: -d%d", profiling ? profInterval : 0);
@@ -432,8 +440,13 @@
     PUTStr('P',hugsPath);
     PUTStr('E',hugsEdit);
     PUTInt('c',cutoff);  PUTC(' ');
+    {
+       String s = getSuffixes();
+       PUTStr('S',s);
+       free(s);
+    }
 #if USE_PREPROCESSOR  && (defined(HAVE_POPEN) || defined(HAVE__POPEN))
-    PUTStr('F',preprocessor);
+    PUTStr('F',default_preprocessor);
 #endif
 #if PROFILING
     PUTInt('d',profiling ? profInterval : 0);
@@ -517,9 +530,12 @@
                       hugsEdit = strCopy(s+1);
                       return TRUE;
 
+           case 'S' : setSuffixes(s+1);
+                      return TRUE;
+
 #if USE_PREPROCESSOR  && (defined(HAVE_POPEN) || defined(HAVE__POPEN))
-           case 'F' : if (preprocessor) free(preprocessor);
-                      preprocessor = strCopy(s+1);
+           case 'F' : if (default_preprocessor) free(default_preprocessor);
+                      default_preprocessor = strCopy(s+1);
                       return TRUE;
 #endif
 
diff -r -u src/input.c src-new/input.c
--- src/input.c Sun May 21 17:02:15 2000
+++ src-new/input.c     Thu May 25 11:16:10 2000
@@ -53,8 +53,14 @@
 
 String repeatStr     = 0;               /* Repeat last expr                */
 
+int num_file_suffixes;
+String *file_suffix;
 #if USE_PREPROCESSOR && (defined(HAVE_POPEN) || defined(HAVE__POPEN))
-String preprocessor  = 0;
+String *file_preprocessor;
+
+String default_preprocessor  = 0;
+
+static String preprocessor  = 0;
 #endif
 
 /* --------------------------------------------------------------------------
@@ -323,10 +329,177 @@
     }
 }
 
+static String local strnSave(s, n)
+String s;
+Int n; {
+    String s2;
+    s2 = malloc(n+1);
+    strncpy(s2, s, n);
+    s2[n] = '\0';
+    return s2;
+}
+
+String getSuffixes() {
+    int size;
+    String all;
+    int i;
+    char *p;
+    size = 0;
+    for (i=0; i < num_file_suffixes; i++) {
+       size += strlen(file_suffix[i]) + 1;
+#if USE_PREPROCESSOR && (defined(HAVE_POPEN) || defined(HAVE__POPEN))
+       if (file_preprocessor[i])
+           size += strlen(file_preprocessor[i]) + 1;
+#endif
+    }
+    all = malloc(size);
+    p = all;
+    for (i=0; i < num_file_suffixes; i++) {
+       if (i > 0)
+           *p++ = ',';
+       strcpy(p, file_suffix[i]);
+       p += strlen(p);
+#if USE_PREPROCESSOR && (defined(HAVE_POPEN) || defined(HAVE__POPEN))
+       if (file_preprocessor[i]) {
+           *p++ = '=';
+           strcpy(p, file_preprocessor[i]);
+           p += strlen(p);
+       }
+#endif
+    }
+    *p = '\0';
+    return all;
+}
+
+Void setSuffixes(list)
+String list; {
+    int num;
+    String *suffix;
+#if USE_PREPROCESSOR && (defined(HAVE_POPEN) || defined(HAVE__POPEN))
+    String *program;
+#endif
+    char *current;
+    char *next;
+    char *equals;
+    int len;
+    int i;
+    Bool all_copied;   /* all old strings shared among the new. */
+
+    /* first pass: see how many entries there will be. */
+    num = 0;
+    current = list;
+    all_copied = FALSE;
+    for (;;) {
+       next = strchr(current, ',');
+       len = next ? next - current : strlen(current);
+       if (len == 0) {
+           if (! all_copied) {
+               num += num_file_suffixes;
+               all_copied = TRUE;
+           }
+       } else {
+           /* if not preprocessing, only included if no '=' */
+#if USE_PREPROCESSOR && (defined(HAVE_POPEN) || defined(HAVE__POPEN))
+           num++;
+#else
+           equals = strchr(current, '=');
+           if (equals == 0 || equals - current > len)
+               num++;
+#endif
+       }
+       if (next == 0)
+           break;
+       current = next+1;
+    }
+
+    if (num > 0) {
+       suffix = malloc(num*sizeof(String));
+#if USE_PREPROCESSOR && (defined(HAVE_POPEN) || defined(HAVE__POPEN))
+       program = malloc(num*sizeof(String));
+#endif
+    }
+    /* second pass: compute the new arrays. */
+    num = 0;
+    current = list;
+    all_copied = FALSE;
+    for (;;) {
+       next = strchr(current, ',');
+       len = next ? next - current : strlen(current);
+       if (len == 0) {
+           if (! all_copied) {
+               for (i=0; i < num_file_suffixes; i++) {
+                   suffix[num] = file_suffix[i];
+#if USE_PREPROCESSOR && (defined(HAVE_POPEN) || defined(HAVE__POPEN))
+                   program[num] = file_preprocessor[i];
+#endif
+                   num++;
+               }
+               all_copied = TRUE;
+           }
+       } else {
+           /* if not preprocessing, only included if no '=' */
+           equals = strchr(current, '=');
+#if USE_PREPROCESSOR && (defined(HAVE_POPEN) || defined(HAVE__POPEN))
+           if (equals == 0 || equals - current > len) {
+               suffix[num] = strnSave(current, len);
+               program[num] = 0;
+           } else {
+               int suffix_len = equals - current;
+               suffix[num] = strnSave(current, suffix_len);
+               program[num] = strnSave(equals+1, len-suffix_len-1);
+           }
+           num++;
+#else
+           if (equals == 0 || equals - current > len) {
+               suffix[num] = strnSave(current, len);
+               num++;
+           }
+#endif
+       }
+       if (next == 0)
+           break;
+       current = next+1;
+    }
+
+    if (num_file_suffixes > 0) {
+       if (! all_copied)
+           for (i=0; i < num_file_suffixes; i++)
+               free(file_suffix[i]);
+       free((char *)file_suffix);
+#if USE_PREPROCESSOR && (defined(HAVE_POPEN) || defined(HAVE__POPEN))
+       if (! all_copied)
+           for (i=0; i < num_file_suffixes; i++)
+               if (file_preprocessor[i])
+                   free(file_preprocessor[i]);
+       free((char *)file_preprocessor);
+#endif
+    }
+    num_file_suffixes = num;
+    if (num_file_suffixes > 0) {
+       file_suffix = suffix;
+#if USE_PREPROCESSOR && (defined(HAVE_POPEN) || defined(HAVE__POPEN))
+       file_preprocessor = program;
+#endif
+    }
+}
+
 static Void local fileInput(nm,len)     /* prepare to input characters from*/
 String nm;                              /* named file (specified length is */
 Long   len; {                           /* used to set target for reading) */
 #if USE_PREPROCESSOR && (defined(HAVE_POPEN) || defined(HAVE__POPEN))
+    preprocessor = default_preprocessor;
+    { /* special preprocessor for this file name? */
+       char *end_nm = nm + strlen(nm);
+       int i;
+       char *suffix;
+       for (i=0; i < num_file_suffixes; i++) {
+           suffix = file_suffix[i];
+           if (strcmp(end_nm - strlen(suffix), suffix) == 0) {
+               preprocessor = file_preprocessor[i];
+               break;
+           }
+       }
+    }
     if (preprocessor) {
        Int reallen = strlen(preprocessor) + 1 + strlen(nm) + 1;
        char *cmd = malloc(reallen);
diff -r -u src/machdep.c src-new/machdep.c
--- src/machdep.c       Wed Mar  8 14:31:10 2000
+++ src-new/machdep.c   Thu May 25 10:51:58 2000
@@ -369,11 +369,6 @@
 #endif /* ! PATH_CANONICALIZATION */
 }
 
-#if HSCRIPT
-static String endings[] = { "", ".hs", ".lhs", ".hsx", ".hash", 0 };
-#else
-static String endings[] = { "", ".hs", ".lhs", 0 };
-#endif
 static char   searchBuf[FILENAME_MAX+1];
 static Int    searchPos;
 
@@ -398,14 +393,15 @@
 String s; {
     Int i = 0;
     searchStr(s);
-    for (; endings[i]; ++i) {
+    for ( ; i < num_file_suffixes; ++i) {
        Int save = searchPos;
-       searchStr(endings[i]);
+       searchStr(file_suffix[i]);
        if (readable(searchBuf))
            return TRUE;
        searchReset(save);
     }
-    return FALSE;
+    /* finally, try no ending */
+    return readable(searchBuf);
 }
 
 
diff -r -u src/options.h.in src-new/options.h.in
--- src/options.h.in    Wed Mar  8 14:31:10 2000
+++ src-new/options.h.in        Thu May 25 10:52:00 2000
@@ -50,6 +50,16 @@
 #define HUGSDIR ".."
 #endif
 
+/* The list of possible suffixes on source files.
+ * (The empty suffix is always tried after these.)
+ * This list may be overridden or augmented using the -T option.
+ */
+#if HSCRIPT
+#define        SUFFIXES ".hs,.lhs,.hsx,.hash"
+#else
+#define        SUFFIXES ".hs,.lhs"
+#endif
+
 /* --------------------------------------------------------------------------
  * User interface options
  * ------------------------------------------------------------------------*/
diff -r -u src/server.c src-new/server.c
--- src/server.c        Mon Sep 13 12:01:06 1999
+++ src-new/server.c    Thu May 25 10:43:43 2000
@@ -176,6 +176,7 @@
        numScripts    = 0;              /* Number of scripts loaded        */
        namesUpto     = 0;              /* Number of script names set      */
        hugsPath      = strCopy(HUGSPATH);
+       setSuffixes(SUFFIXES);
        if (argc == -1) {
            readOptions(argv[0]);
        } else {

Reply via email to