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];
39 #define OPT_DUMP_SYM 3
40 #define OPT_DUMP_MOD 4
43 #define EQ(A,B) !strcmp((A),(B))
44 #define NEQ(A,B) strcmp((A),(B))
47 FILE *lib, *newlib, *rel, *adb, *libindex;
48 char FLine[MAXLINE+1];
49 char ModName[MAXLINE+1];
52 void GetNameFromPath(char * path, char * name)
56 for(i=0; path[i]!=0; i++);
57 for(; (path[i]!='\\')&&(path[i]!='/')&&(i>=0); i--);
58 for(j=0, i++; (path[i]!='.')&&(path[i]!=0); i++, j++) name[j]=path[i];
62 void ChangeExtension(char * path, char * ext)
66 for(i=0; path[i]!=0; i++);
67 for(; (path[i]!='.')&&(path[i]!='\\')&&(path[i]!='/')&&(i>=0); i--);
75 printf("ERROR: Filename '%s' must have an extension\n", path);
80 void CleanLine(char * buff)
86 if((buff[j]=='\n')||(buff[j]=='\r')) buff[j]=0;
90 int set_options (char * opt)
92 int rvalue=0, unknown=0;
94 "Usage: %s [-options] library relfile\n\n"
95 "available options:\n"
96 "a - Adds relfile to library. If relfile exists, replaces it.\n"
97 "d - Deletes relfile from library.\n"
98 "e - Extracts relfile from library.\n"
99 "s - Dumps symbols of library.\n"
100 "m - Dumps modules of library.\n"
101 "v - Displays program version.\n"
111 printf("%s: SDCC librarian version %s\n", ProgName, version);
112 printf("by Jesus Calvino-Fraga\n\n");
113 if (unknown) printf("Unknown option: %c\n", opt[0]);
114 if (opt[0]=='v') exit(0);
115 printf(Help, ProgName);
137 void ProcLineOptions (int argc, char **argv)
142 /*Get the program name*/
143 GetNameFromPath(argv[0], ProgName);
145 for (j=1; j<argc; j++)
149 for(i=1; argv[j][i]!=0 ; i++)
150 if (set_options(&argv[j][i])) break;
158 strcpy(LibName, argv[j]);
163 strcpy(RelName, argv[j]);
173 if ( (cont_par!=2) && (action<OPT_DUMP_SYM) )
175 printf("Error: Too %s arguments.\n", cont_par<2?"few":"many");
176 set_options("h"); /*Show help and exit*/
178 else if ( (cont_par!=1) && (action>=OPT_DUMP_SYM) )
180 printf("Error: Too %s arguments.\n", cont_par<1?"few":"many");
181 set_options("h"); /*Show help and exit*/
188 long newlibpos, indexsize;
189 char symname[MAXLINE+1];
193 strcpy(LibNameTmp, LibName);
194 ChangeExtension(LibNameTmp, "__L");
196 strcpy(IndexName, LibName);
197 ChangeExtension(IndexName, "__I");
199 strcpy(AdbName, RelName);
200 ChangeExtension(AdbName, "adb");
202 lib=fopen(LibName, "r");
204 if(action==OPT_ADD_REL)
206 rel=fopen(RelName, "r");
209 printf("ERROR: Couldn't open file '%s'", RelName);
210 if(lib!=NULL) fclose(lib);
214 GetNameFromPath(RelName, ModName);
216 newlib=fopen(LibNameTmp, "w");
219 printf("ERROR: Couldn't create temporary file '%s'", LibNameTmp);
220 if(lib!=NULL) fclose(lib);
224 fprintf(newlib, "<FILES>\n\n");
226 libindex=fopen(IndexName, "w");
229 printf("ERROR: Couldn't create temporary file '%s'", IndexName);
230 if(lib!=NULL) fclose(lib);
236 if(lib!=NULL) while(!feof(lib))
239 fgets(FLine, MAXLINE, lib);
245 if(EQ(FLine, "<FILE>"))
248 fgets(FLine, MAXLINE, lib);
250 if(NEQ(FLine, ModName))
252 newlibpos=ftell(newlib);
253 fprintf(newlib, "<FILE>\n%s\n", FLine);
254 fprintf(libindex, "<MODULE>\n%s %ld\n", FLine, newlibpos);
260 fprintf(newlib, "%s\n", FLine);
261 if(EQ(FLine, "</FILE>"))
263 fprintf(newlib, "\n");
264 fprintf(libindex, "</MODULE>\n\n");
268 else if(EQ(FLine, "<REL>")) inrel=1;
269 else if(EQ(FLine, "</REL>")) inrel=0;
274 sscanf(FLine, "S %s %c", symname, &c);
275 if(c=='D') fprintf(libindex, "%s\n", symname);
282 if(action==OPT_ADD_REL)
284 newlibpos=ftell(newlib);
285 fprintf(newlib, "<FILE>\n%s\n<REL>\n", ModName);
286 fprintf(libindex, "<MODULE>\n%s %ld\n", ModName, newlibpos);
290 fgets(FLine, MAXLINE, rel);
294 fprintf(newlib, "%s\n", FLine);
298 sscanf(FLine, "S %s %c", symname, &c);
299 if(c=='D') fprintf(libindex, "%s\n", symname);
303 fprintf(libindex, "</MODULE>\n");
304 fprintf(newlib, "</REL>\n<ADB>\n");
306 adb=fopen(AdbName, "r");
312 fgets(FLine, MAXLINE, adb);
316 fprintf(newlib, "%s\n", FLine);
321 fprintf(newlib, "</ADB>\n</FILE>\n");
324 /*Put the temporary files together as a new library file*/
325 indexsize=ftell(libindex);
329 if(lib!=NULL) fclose(lib);
332 newlib=fopen(LibNameTmp, "r");
333 lib=fopen(LibName, "w");
334 libindex=fopen(IndexName, "r");
336 fprintf(lib, "<SDCCLIB>\n\n<INDEX>\n");
338 /*Find out if the \n is expanded to \r\n or not*/
339 if(ftell(lib)!=(long)strlen("<SDCCLIB>\n\n<INDEX>\n"))
344 indexsize+=ftell(lib)+strlen("0123456789\n\n</INDEX>\n\n");
345 if(IsDOSStyle) indexsize+=4;
347 fprintf(lib, "%10ld\n", indexsize);
349 while(!feof(libindex))
352 fgets(FLine, MAXLINE, libindex);
353 fprintf(lib, "%s", FLine);
355 fprintf(lib, "\n</INDEX>\n\n");
360 fgets(FLine, MAXLINE, newlib);
361 fprintf(lib, "%s", FLine);
363 fprintf(lib, "\n</FILES>\n\n");
364 fprintf(lib, "</SDCCLIB>\n");
374 void ExtractRel(void)
376 strcpy(AdbName, RelName);
377 ChangeExtension(AdbName, "adb");
379 lib=fopen(LibName, "r");
382 printf("ERROR: Couldn't open file '%s'", LibName);
386 rel=fopen(RelName, "w");
389 printf("ERROR: Couldn't create file '%s'", RelName);
393 GetNameFromPath(RelName, ModName);
395 adb=fopen(AdbName, "w");
398 printf("ERROR: Couldn't create file '%s'", AdbName);
408 fgets(FLine, MAXLINE, lib);
414 if(EQ(FLine, "<FILE>"))
417 fgets(FLine, MAXLINE, lib);
419 if(EQ(FLine, ModName)) state=1;
423 if(EQ(FLine, "<REL>")) state=2;
426 if(EQ(FLine, "</REL>"))
429 fprintf(rel, "%s\n", FLine);
432 if(EQ(FLine, "<ADB>")) state=4;
435 if(EQ(FLine, "</ADB>"))
438 fprintf(adb, "%s\n", FLine);
448 void DumpSymbols(void)
450 lib=fopen(LibName, "r");
453 printf("ERROR: Couldn't open file '%s'", LibName);
461 fgets(FLine, MAXLINE, lib);
467 if(EQ(FLine, "<INDEX>")) state=1;
470 if(EQ(FLine, "<MODULE>"))
473 fgets(FLine, MAXLINE, lib);
474 sscanf(FLine, "%s", ModName);
475 if(action==OPT_DUMP_SYM)
477 printf("%s.rel:\n", ModName);
482 printf("%s.rel\n", ModName);
485 else if(EQ(FLine, "</INDEX>")) state=3;
488 if(EQ(FLine, "</MODULE>"))
493 else printf(" %s\n", FLine);
505 int main(int argc, char **argv)
507 ProcLineOptions (argc, argv);
527 return 0; //Success!!!