1 /* sdcclib.c: sdcc librarian
2 Copyright (C) 2003, Jesus Calvino-Fraga jesusc(at)ece.ubc.ca
4 This program is free software; you can redistribute it and/or modify it
5 under the terms of the GNU General Public License as published by the
6 Free Software Foundation; either version 2, or (at your option) any
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
23 #if !defined(__BORLANDC__) && !defined(_MSC_VER)
27 char ProgName[PATH_MAX];
28 char LibName[PATH_MAX];
29 char LibNameTmp[PATH_MAX];
30 char IndexName[PATH_MAX];
31 char RelName[PATH_MAX];
32 char AdbName[PATH_MAX];
33 char ListName[PATH_MAX];
40 #define OPT_ADD_LIST 3
41 #define OPT_DUMP_SYM 4
42 #define OPT_DUMP_MOD 5
45 #define EQ(A,B) !strcmp((A),(B))
46 #define NEQ(A,B) strcmp((A),(B))
49 FILE *lib, *newlib, *rel, *adb, *libindex;
50 char FLine[MAXLINE+1];
51 char ModName[MAXLINE+1];
54 void GetNameFromPath(char * path, char * name)
58 for(i=0; path[i]!=0; i++);
59 for(; (path[i]!='\\')&&(path[i]!='/')&&(i>=0); i--);
60 for(j=0, i++; (path[i]!='.')&&(path[i]!=0); i++, j++) name[j]=path[i];
64 void ChangeExtension(char * path, char * ext)
68 for(i=0; path[i]!=0; i++);
69 for(; (path[i]!='.')&&(path[i]!='\\')&&(path[i]!='/')&&(i>=0); i--);
77 printf("ERROR: Filename '%s' must have an extension\n", path);
82 void CleanLine(char * buff)
88 if((buff[j]=='\n')||(buff[j]=='\r')) buff[j]=0;
92 int set_options (char * opt)
94 int rvalue=0, unknown=0;
96 "Usage: %s [-options] library relfile\n\n"
97 "available options:\n"
98 "a - Adds relfile to library. If relfile exists, replaces it.\n"
99 "l - Adds relfile list to library.\n"
100 "d - Deletes relfile from library.\n"
101 "e - Extracts relfile from library.\n"
102 "s - Dumps symbols of library.\n"
103 "m - Dumps modules of library.\n"
104 "v - Displays program version.\n"
114 printf("%s: SDCC librarian version %s\n", ProgName, version);
115 printf("by Jesus Calvino-Fraga\n\n");
116 if (unknown) printf("Unknown option: %c\n", opt[0]);
117 if (opt[0]=='v') exit(0);
118 printf(Help, ProgName);
143 void ProcLineOptions (int argc, char **argv)
148 /*Get the program name*/
149 GetNameFromPath(argv[0], ProgName);
151 for (j=1; j<argc; j++)
155 for(i=1; argv[j][i]!=0 ; i++)
156 if (set_options(&argv[j][i])) break;
164 strcpy(LibName, argv[j]);
169 if(action==OPT_ADD_LIST)
170 strcpy(ListName, argv[j]);
172 strcpy(RelName, argv[j]);
182 if ( (cont_par!=2) && (action<OPT_DUMP_SYM) )
184 printf("ERROR: Too %s arguments.\n", cont_par<2?"few":"many");
185 set_options("h"); /*Show help and exit*/
187 else if ( (cont_par!=1) && (action>=OPT_DUMP_SYM) )
189 printf("ERROR: Too %s arguments.\n", cont_par<1?"few":"many");
190 set_options("h"); /*Show help and exit*/
197 long newlibpos, indexsize;
198 char symname[MAXLINE+1];
202 strcpy(LibNameTmp, LibName);
203 ChangeExtension(LibNameTmp, "__L");
205 strcpy(IndexName, LibName);
206 ChangeExtension(IndexName, "__I");
208 strcpy(AdbName, RelName);
209 ChangeExtension(AdbName, "adb");
211 lib=fopen(LibName, "r");
213 if(action==OPT_ADD_REL)
215 rel=fopen(RelName, "r");
218 printf("ERROR: Couldn't open file '%s'\n", RelName);
219 if(lib!=NULL) fclose(lib);
223 GetNameFromPath(RelName, ModName);
225 newlib=fopen(LibNameTmp, "w");
228 printf("ERROR: Couldn't create temporary file '%s'\n", LibNameTmp);
229 if(lib!=NULL) fclose(lib);
233 fprintf(newlib, "<FILES>\n\n");
235 libindex=fopen(IndexName, "w");
238 printf("ERROR: Couldn't create temporary file '%s'\n", IndexName);
239 if(lib!=NULL) fclose(lib);
245 if(lib!=NULL) while(!feof(lib))
248 fgets(FLine, MAXLINE, lib);
254 if(EQ(FLine, "<FILE>"))
257 fgets(FLine, MAXLINE, lib);
259 if(NEQ(FLine, ModName))
261 newlibpos=ftell(newlib);
262 fprintf(newlib, "<FILE>\n%s\n", FLine);
263 fprintf(libindex, "<MODULE>\n%s %ld\n", FLine, newlibpos);
269 fprintf(newlib, "%s\n", FLine);
270 if(EQ(FLine, "</FILE>"))
272 fprintf(newlib, "\n");
273 fprintf(libindex, "</MODULE>\n\n");
277 else if(EQ(FLine, "<REL>")) inrel=1;
278 else if(EQ(FLine, "</REL>")) inrel=0;
283 sscanf(FLine, "S %s %c", symname, &c);
284 if(c=='D') fprintf(libindex, "%s\n", symname);
291 if(action==OPT_ADD_REL)
293 newlibpos=ftell(newlib);
294 fprintf(newlib, "<FILE>\n%s\n<REL>\n", ModName);
295 fprintf(libindex, "<MODULE>\n%s %ld\n", ModName, newlibpos);
299 fgets(FLine, MAXLINE, rel);
303 fprintf(newlib, "%s\n", FLine);
307 sscanf(FLine, "S %s %c", symname, &c);
308 if(c=='D') fprintf(libindex, "%s\n", symname);
312 fprintf(libindex, "</MODULE>\n");
313 fprintf(newlib, "</REL>\n<ADB>\n");
315 adb=fopen(AdbName, "r");
321 fgets(FLine, MAXLINE, adb);
325 fprintf(newlib, "%s\n", FLine);
330 fprintf(newlib, "</ADB>\n</FILE>\n");
333 /*Put the temporary files together as a new library file*/
334 indexsize=ftell(libindex);
338 if(lib!=NULL) fclose(lib);
341 newlib=fopen(LibNameTmp, "r");
342 lib=fopen(LibName, "w");
343 libindex=fopen(IndexName, "r");
345 fprintf(lib, "<SDCCLIB>\n\n<INDEX>\n");
347 /*Find out if the \n is expanded to \r\n or not*/
348 if(ftell(lib)!=(long)strlen("<SDCCLIB>\n\n<INDEX>\n"))
353 indexsize+=ftell(lib)+strlen("0123456789\n\n</INDEX>\n\n");
354 if(IsDOSStyle) indexsize+=4;
356 fprintf(lib, "%10ld\n", indexsize);
358 while(!feof(libindex))
361 fgets(FLine, MAXLINE, libindex);
362 fprintf(lib, "%s", FLine);
364 fprintf(lib, "\n</INDEX>\n\n");
369 fgets(FLine, MAXLINE, newlib);
370 fprintf(lib, "%s", FLine);
372 fprintf(lib, "\n</FILES>\n\n");
373 fprintf(lib, "</SDCCLIB>\n");
383 void ExtractRel(void)
385 strcpy(AdbName, RelName);
386 ChangeExtension(AdbName, "adb");
388 lib=fopen(LibName, "r");
391 printf("ERROR: Couldn't open file '%s'\n", LibName);
395 rel=fopen(RelName, "w");
398 printf("ERROR: Couldn't create file '%s'\n", RelName);
402 GetNameFromPath(RelName, ModName);
404 adb=fopen(AdbName, "w");
407 printf("ERROR: Couldn't create file '%s'\n", AdbName);
417 fgets(FLine, MAXLINE, lib);
423 if(EQ(FLine, "<FILE>"))
426 fgets(FLine, MAXLINE, lib);
428 if(EQ(FLine, ModName)) state=1;
432 if(EQ(FLine, "<REL>")) state=2;
435 if(EQ(FLine, "</REL>"))
438 fprintf(rel, "%s\n", FLine);
441 if(EQ(FLine, "<ADB>")) state=4;
444 if(EQ(FLine, "</ADB>"))
447 fprintf(adb, "%s\n", FLine);
457 void DumpSymbols(void)
459 lib=fopen(LibName, "r");
462 printf("ERROR: Couldn't open file '%s'\n", LibName);
467 fgets(FLine, MAXLINE, lib);
469 if(NEQ(FLine, "<SDCCLIB>"))
471 printf("ERROR: File '%s' was not created with '%s'\n", LibName, ProgName);
479 fgets(FLine, MAXLINE, lib);
485 if(EQ(FLine, "<INDEX>")) state=1;
488 if(EQ(FLine, "<MODULE>"))
491 fgets(FLine, MAXLINE, lib);
492 sscanf(FLine, "%s", ModName);
493 if(action==OPT_DUMP_SYM)
495 printf("%s.rel:\n", ModName);
500 printf("%s.rel\n", ModName);
503 else if(EQ(FLine, "</INDEX>")) state=3;
506 if(EQ(FLine, "</MODULE>"))
511 else printf(" %s\n", FLine);
523 int fileexist(char * fname)
527 fp=fopen(fname, "r");
528 if(fp==NULL) return 0;
539 char SrcName[PATH_MAX];
541 list=fopen(ListName, "r");
544 printf("ERROR: Couldn't open list file '%s'\n", ListName);
548 cc = getenv("SDCCLIB_CC");
549 as = getenv("SDCCLIB_AS");
555 fgets(RelName, PATH_MAX, list);
557 if(strlen(RelName)>0) //Skip empty lines
559 if((cc!=NULL)||(as!=NULL))
561 strcpy(SrcName, RelName);
562 if(strchr(SrcName,'.')==NULL)
563 strcat(SrcName,".src");
568 ChangeExtension(SrcName, "c");
569 if(fileexist(SrcName))
571 sprintf(CmdLine, "%s %s", cc, SrcName);
572 printf("%s\n", CmdLine);
578 ChangeExtension(SrcName, "asm");
579 if(fileexist(SrcName))
581 sprintf(CmdLine, "%s %s", as, SrcName);
582 printf("%s\n", CmdLine);
587 if(strchr(RelName,'.')==NULL)
589 //Try adding the default sdcc extensions
590 strcat(RelName,".o");
591 if(!fileexist(RelName))
592 ChangeExtension(RelName, "rel");
595 printf("Adding: %s\n", RelName);
603 int main(int argc, char **argv)
605 ProcLineOptions (argc, argv);
629 return 0; //Success!!!