* support/librarian/sdcclib.c:
[fw/sdcc] / support / librarian / sdcclib.c
index 95817b2e1bbd98915cac8423633234cc828baf2f..5ab4c4a5b34dd9d111f6ce7f74d396eabd061901 100644 (file)
@@ -28,55 +28,66 @@ char ProgName[PATH_MAX];
 char LibName[PATH_MAX];
 char LibNameTmp[PATH_MAX];
 char IndexName[PATH_MAX];
-char RelName[PATH_MAX];
 char AdbName[PATH_MAX];
 char ListName[PATH_MAX];
 
-#define version "1.0"
+char **RelName;
+int NumRelFiles=0;
 
-#define OPT_ADD_REL 0
-#define OPT_EXT_REL 1
-#define OPT_DEL_REL 2
-#define OPT_ADD_LIST 3
-#define OPT_DUMP_SYM 4
-#define OPT_DUMP_MOD 5
+#define version "1.2"
+
+#define OPT_NONE     0
+#define OPT_ADD_REL  1
+#define OPT_EXT_REL  2
+#define OPT_DEL_REL  3
+#define OPT_ADD_LIST 4
+#define OPT_DUMP_SYM 5
+#define OPT_DUMP_MOD 6
 
 #define MAXLINE 254
 #define EQ(A,B) !strcmp((A),(B))
 #define NEQ(A,B) strcmp((A),(B))
 
-int action=0;
+#if 1
+#include <assert.h>
+
+#define system(CMD)             do {                    \
+  int __res4568 = system(CMD);                          \
+  assert(-1 != __res4568);                              \
+} while (0)
+#endif
+
+int action=OPT_NONE;
 FILE *lib, *newlib, *rel, *adb, *libindex;
 char FLine[MAXLINE+1];
 char ModName[MAXLINE+1];
-int state=0;
 
 void GetNameFromPath(char * path, char * name)
 {
-       int i, j;
+    int i, j;
 
-       for(i=0; path[i]!=0; i++);
-       for(; (path[i]!='\\')&&(path[i]!='/')&&(i>=0); i--);
-       for(j=0, i++; (path[i]!='.')&&(path[i]!=0); i++, j++) name[j]=path[i];
-       name[j]=0;
+    for(i=0; path[i]!=0; i++);
+    for(; (path[i]!='\\')&&(path[i]!='/')&&(i>=0); i--);
+    for(j=0, i++; (path[i]!='.')&&(path[i]!=0); i++, j++) name[j]=path[i];
+    name[j]=0;
 }
 
 void ChangeExtension(char * path, char * ext)
 {
-       int i;
+    int i;
 
-       for(i=0; path[i]!=0; i++);
-       for(; (path[i]!='.')&&(path[i]!='\\')&&(path[i]!='/')&&(i>=0); i--);
-       if(path[i]=='.')
-       {
-           path[i+1]=0;
+    for(i=0; path[i]!=0; i++);
+    for(; (path[i]!='.')&&(path[i]!='\\')&&(path[i]!='/')&&(i>=0); i--);
+    if(path[i]=='.')
+    {
+        path[i+1]=0;
         strcat(path, ext);
-       }
-       else
-       {
-           printf("ERROR: Filename '%s' must have an extension\n", path);
-           exit(1);
-       }
+    }
+    else
+    {
+        printf("ERROR: Filename '%s' must have an extension\n", path);
+        exit(1);
+    }
 }
 
 void CleanLine(char * buff)
@@ -91,109 +102,146 @@ void CleanLine(char * buff)
 
 int set_options (char * opt)
 {
-       int rvalue=0, unknown=0;
-       static char Help[] =
-       "Usage: %s [-options] library relfile\n\n"
-       "available options:\n"
-       "a - Adds relfile to library.  If relfile exists, replaces it.\n"
-       "l - Adds relfile list to library.\n"
-       "d - Deletes relfile from library.\n"
-       "e - Extracts relfile from library.\n"
-       "s - Dumps symbols of library.\n"
-       "m - Dumps modules of library.\n"
-       "v - Displays program version.\n"
-       "h - This help.\n";
-
-       switch (opt[0])
-       {
-               default:
-                   unknown=1;
-               case 'h':
-               case '?':
-               case 'v':
-                   printf("%s: SDCC librarian version %s\n", ProgName, version);
-                   printf("by Jesus Calvino-Fraga\n\n");
-                       if (unknown) printf("Unknown option: %c\n", opt[0]);
-                   if (opt[0]=='v') exit(0);
-                       printf(Help, ProgName);
-                       exit(1);
-               break;
-               case 'a':
-                   action=OPT_ADD_REL;
-               break;
-               case 'l':
-                   action=OPT_ADD_LIST;
-               break;
-               case 'e':
-                   action=OPT_EXT_REL;
-               break;
-               case 'd':
-                   action=OPT_DEL_REL;
-               break;
-               case 's':
-                   action=OPT_DUMP_SYM;
-               break;
-               case 'm':
-                   action=OPT_DUMP_MOD;
-               break;
-       }
-       return (rvalue);
+    int rvalue=0, unknown=0;
+    static char Help[] =
+    "Usage: %s [option|-options] library relfile1 relfile2 relfile3 ...\n\n"
+    "available options:\n"
+    "a,r - Adds relfile(s) to library.  If relfile exists, replaces it.\n"
+    "  l - Adds relfile list to library.\n"
+    "  d - Deletes relfile(s) from library.\n"
+    "e,x - Extracts relfile(s) from library.\n"
+    "  s - Dumps symbols of library.\n"
+    "  m - Dumps modules of library.\n"
+    "  v - Displays program version.\n"
+    "h,? - This help.\n";
+
+    switch (opt[0])
+    {
+        default:
+            unknown=1;
+        case 'h':
+        case '?':
+        case 'v':
+            printf("%s: SDCC librarian version %s\n", ProgName, version);
+            printf("by Jesus Calvino-Fraga\n\n");
+            if (unknown) printf("Unknown option: %c\n", opt[0]);
+            if (opt[0]=='v') exit(0);
+            printf(Help, ProgName);
+            exit(1);
+        break;
+        case 'a':
+        case 'r':
+            action=OPT_ADD_REL;
+        break;
+        case 'l':
+            action=OPT_ADD_LIST;
+        break;
+        case 'e':
+        case 'x':
+            action=OPT_EXT_REL;
+        break;
+        case 'd':
+            action=OPT_DEL_REL;
+        break;
+        case 's':
+            action=OPT_DUMP_SYM;
+        break;
+        case 'm':
+            action=OPT_DUMP_MOD;
+        break;
+    }
+    return (rvalue);
 }
 
 void ProcLineOptions (int argc, char **argv)
 {
-       int cont_par=0;
-       int i, j;
+    int cont_par=0;
+    int i, j;
 
-       /*Get the program name*/
+    /*Get the program name*/
     GetNameFromPath(argv[0], ProgName);
 
-       for (j=1; j<argc; j++)
-       {
-               if(argv[j][0]=='-')
-               {
-                       for(i=1; argv[j][i]!=0 ; i++)
-                               if (set_options(&argv[j][i])) break;
-               }
-               else
-               {
-                       switch(cont_par)
-                       {
-                               case 0:
-                                       cont_par++;
-                                       strcpy(LibName, argv[j]);
-                               break;
-
-                               case 1:
-                                       cont_par++;
+    for (j=1; j<argc; j++)
+    {
+        if(argv[j][0]=='-')
+        {
+            for(i=1; argv[j][i]!=0 ; i++)
+                if (set_options(&argv[j][i])) break;
+        }
+        else
+        {
+            switch(cont_par)
+            {
+                case 0:
+                    if ((strlen(argv[j])==1) && (action==OPT_NONE))
+                        set_options(argv[j]);
+                    else
+                    {
+                        cont_par++;
+                        strcpy(LibName, argv[j]);
+                    }
+                break;
+
+                case 1:
+                    cont_par++;
                     if(action==OPT_ADD_LIST)
                         strcpy(ListName, argv[j]);
                     else
-                                           strcpy(RelName, argv[j]);
-                               break;
-
-                               default:
-                                       cont_par++;
-                               break;
-                       }
-               }
-       }
-
-       if ( (cont_par!=2) && (action<OPT_DUMP_SYM) )
-       {
-               printf("ERROR: Too %s arguments.\n", cont_par<2?"few":"many");
-               set_options("h"); /*Show help and exit*/
-       }
-       else if ( (cont_par!=1) && (action>=OPT_DUMP_SYM) )
-       {
-               printf("ERROR: Too %s arguments.\n", cont_par<1?"few":"many");
-               set_options("h"); /*Show help and exit*/
-       }
+                    {
+                        NumRelFiles=1;
+                        RelName = (char **) calloc (1, sizeof (char *));
+                        if(RelName==NULL)
+                        {
+                            printf("ERROR: Insuficient memory.\n");
+                            exit(2);
+                        }
+                        RelName[0]=(char *)malloc(PATH_MAX);
+                        if(RelName[0]==NULL)
+                        {
+                            printf("ERROR: Insuficient memory.\n");
+                            exit(2);
+                        }
+                        strcpy(RelName[0], argv[j]);
+                    }
+                break;
+
+                default:
+                    cont_par++;
+                    NumRelFiles++;
+                    RelName = (char **) realloc (RelName, NumRelFiles * sizeof (char *));
+                    if(RelName==NULL)
+                    {
+                        printf("ERROR: Insuficient memory.\n");
+                        exit(2);
+                    }
+                    RelName[NumRelFiles-1]=(char *)malloc(PATH_MAX);
+                    if(RelName[NumRelFiles-1]==NULL)
+                    {
+                        printf("ERROR: Insuficient memory.\n");
+                        exit(2);
+                    }
+                    strcpy(RelName[NumRelFiles-1], argv[j]);
+                break;
+            }
+        }
+    }
+
+    if ( (cont_par<2) && (action<OPT_DUMP_SYM) )
+    {
+        printf("ERROR: Too few arguments.\n");
+        set_options("h"); /*Show help and exit*/
+    }
+    else if ( (cont_par!=1) && (action>=OPT_DUMP_SYM) )
+    {
+        printf("ERROR: Too %s arguments.\n", cont_par<1?"few":"many");
+        set_options("h"); /*Show help and exit*/
+    }
 }
 
-void AddRel(void)
+void AddRel(char * RelName)
 {
     int inrel=0;
+    int state=0;
     long newlibpos, indexsize;
     char symname[MAXLINE+1];
     char c;
@@ -263,7 +311,7 @@ void AddRel(void)
                         fprintf(libindex, "<MODULE>\n%s %ld\n", FLine, newlibpos);
                         state++;
                     }
-                }                
+                }
             break;
             case 1:
                 fprintf(newlib, "%s\n", FLine);
@@ -311,7 +359,7 @@ void AddRel(void)
         fclose(rel);
         fprintf(libindex, "</MODULE>\n");
         fprintf(newlib, "</REL>\n<ADB>\n");
-    
+
         adb=fopen(AdbName, "r");
         if(adb!=NULL)
         {
@@ -380,8 +428,10 @@ void AddRel(void)
     remove(IndexName);
 }
 
-void ExtractRel(void)
+void ExtractRel(char * RelName)
 {
+    int state=0;
+
     strcpy(AdbName, RelName);
     ChangeExtension(AdbName, "adb");
 
@@ -426,7 +476,7 @@ void ExtractRel(void)
                     fgets(FLine, MAXLINE, lib);
                     CleanLine(FLine);
                     if(EQ(FLine, ModName)) state=1;
-                }                
+                }
             break;
             case 1:
                 if(EQ(FLine, "<REL>")) state=2;
@@ -445,10 +495,10 @@ void ExtractRel(void)
                     state=5;
                 else
                     fprintf(adb, "%s\n", FLine);
-            break; 
+            break;
         }
     }
-    
+
     fclose(rel);
     fclose(lib);
     fclose(adb);
@@ -456,6 +506,8 @@ void ExtractRel(void)
 
 void DumpSymbols(void)
 {
+    int state=0;
+
     lib=fopen(LibName, "r");
     if(lib==NULL)
     {
@@ -468,10 +520,10 @@ void DumpSymbols(void)
     CleanLine(FLine);
     if(NEQ(FLine, "<SDCCLIB>"))
     {
-        printf("ERROR: File '%s' was not created with '%s'\n", LibName, ProgName); 
+        printf("ERROR: File '%s' was not created with '%s'\n", LibName, ProgName);
         return;
     }
-    
+
     while(!feof(lib))
     {
         if(state==3) break;
@@ -516,14 +568,14 @@ void DumpSymbols(void)
             break;
         }
     }
-    
+
     fclose(lib);
 }
 
 int fileexist(char * fname)
 {
     FILE * fp;
-    
+
     fp=fopen(fname, "r");
     if(fp==NULL) return 0;
     fclose(fp);
@@ -533,6 +585,11 @@ int fileexist(char * fname)
 void AddList(void)
 {
     FILE * list;
+    char *cc;
+    char *as;
+    char CmdLine[1024];
+    char SrcName[PATH_MAX];
+    char RelName[PATH_MAX];
 
     list=fopen(ListName, "r");
     if(list==NULL)
@@ -541,6 +598,9 @@ void AddList(void)
         return;
     }
 
+    cc = getenv("SDCCLIB_CC");
+    as = getenv("SDCCLIB_AS");
+
     action=OPT_ADD_REL;
     while(!feof(list))
     {
@@ -549,6 +609,34 @@ void AddList(void)
         CleanLine(RelName);
         if(strlen(RelName)>0) //Skip empty lines
         {
+            if((cc!=NULL)||(as!=NULL))
+            {
+                strcpy(SrcName, RelName);
+                if(strchr(SrcName,'.')==NULL)
+                    strcat(SrcName,".src");
+            }
+
+            if(cc!=NULL)
+            {
+                ChangeExtension(SrcName, "c");
+                if(fileexist(SrcName))
+                {
+                    sprintf(CmdLine, "%s %s", cc, SrcName);
+                    printf("%s\n", CmdLine);
+                    system(CmdLine);
+                }
+            }
+            else if(as!=NULL)
+            {
+                ChangeExtension(SrcName, "asm");
+                if(fileexist(SrcName))
+                {
+                    sprintf(CmdLine, "%s %s", as, SrcName);
+                    printf("%s\n", CmdLine);
+                    system(CmdLine);
+                }
+            }
+
             if(strchr(RelName,'.')==NULL)
             {
                 //Try adding the default sdcc extensions
@@ -556,8 +644,9 @@ void AddList(void)
                 if(!fileexist(RelName))
                     ChangeExtension(RelName, "rel");
             }
+
             printf("Adding: %s\n", RelName);
-            AddRel();
+            AddRel(RelName);
         }
     }
     action=OPT_ADD_LIST;
@@ -566,29 +655,36 @@ void AddList(void)
 
 int main(int argc, char **argv)
 {
-       ProcLineOptions (argc, argv);
-
-       switch(action)
-       {
-           default:
-               action=OPT_ADD_REL;
-               case OPT_ADD_REL:
-               case OPT_DEL_REL:
-                   AddRel();
-               break;
-               
+    int j;
+    ProcLineOptions (argc, argv);
+
+    switch(action)
+    {
+        default:
+            action=OPT_ADD_REL;
+        case OPT_ADD_REL:
+        case OPT_DEL_REL:
+            for(j=0; j<NumRelFiles; j++) AddRel(RelName[j]);
+            //Clean up
+            for(j=0; j<NumRelFiles; j++) free(RelName[j]);
+            free(RelName);
+        break;
+
         case OPT_ADD_LIST:
             AddList();
         break;
 
-               case OPT_EXT_REL:
-            ExtractRel();
+        case OPT_EXT_REL:
+            for(j=0; j<NumRelFiles; j++) ExtractRel(RelName[j]);
+            //Clean up
+            for(j=0; j<NumRelFiles; j++) free(RelName[j]);
+            free(RelName);
+        break;
+
+        case OPT_DUMP_SYM:
+        case OPT_DUMP_MOD:
+            DumpSymbols();
         break;
-        
-               case OPT_DUMP_SYM:
-               case OPT_DUMP_MOD:
-                   DumpSymbols();
-               break;
-       }
-       return 0; //Success!!!
+    }
+    return 0; //Success!!!
 }