4 * (C) Copyright 1989-1995
11 * With contributions for the
12 * object libraries from
14 * kenh@cmf.nrl.navy.mil
18 #define EQ(A,B) !strcmp((A),(B))
19 #define MAXLINE 254 /*when using fgets*/
21 #if defined(__APPLE__) && defined(__MACH__)
22 #include <sys/types.h>
23 #include <sys/malloc.h>
24 #elseif !defined(__FreeBSD__)
35 * The module lklibr.c contains the functions which
36 * (1) specify the path(s) to library files [.LIB]
37 * (2) specify the library file(s) [.LIB] to search
38 * (3) search the library files for specific symbols
39 * and link the module containing this symbol
41 * lklibr.c contains the following functions:
53 typedef struct slibrarysymbol mlibrarysymbol;
54 typedef struct slibrarysymbol *pmlibrarysymbol;
56 struct slibrarysymbol {
57 char * name; /*Warning: allocate memory before using*/
61 typedef struct slibraryfile mlibraryfile;
62 typedef struct slibraryfile *pmlibraryfile;
67 char * relfil; /*Warning: allocate memory before using*/
68 char * filename; /*Warning: allocate memory before using*/
69 long offset; //if > 0, the embedded file offset in the library file libspc
70 pmlibrarysymbol symbols;
74 /* First entry in the library object symbol cache */
75 pmlibraryfile libr=NULL;
77 int buildlibraryindex();
78 void freelibraryindex (void);
81 /*)Function VOID addpath()
83 * The function addpath() creates a linked structure containing
84 * the paths to various object module library files.
87 * lbpath *lbph pointer to new path structure
88 * lbpath *lbp temporary pointer
91 * lbpath *lbphead The pointer to the first
95 * char getnb() lklex.c
96 * VOID * new() lksym.c
97 * int strlen() c_library
98 * char * strcpy() c_library
99 * VOID unget() lklex.c
102 * An lbpath structure may be created.
108 struct lbpath *lbph, *lbp;
110 lbph = (struct lbpath *) new (sizeof(struct lbpath));
111 if (lbphead == NULL) {
120 lbph->path = (char *) new (strlen(ip)+1);
121 strcpy(lbph->path, ip);
124 /*)Function VOID addlib()
126 * The function addlib() tests for the existance of a
127 * library path structure to determine the method of
128 * adding this library file to the library search structure.
130 * This function calls the function addfile() to actually
131 * add the library file to the search list.
134 * lbpath *lbph pointer to path structure
137 * lbpath *lbphead The pointer to the first
139 * ip a pointer to the library name
142 * VOID addfile() lklibr.c
143 * char getnb() lklex.c
144 * VOID unget() lklex.c
147 * The function addfile() may add the file to
148 * the library search list.
161 foundcount=addfile(NULL, ip);
165 for (lbph=lbphead; lbph; lbph=lbph->next)
167 foundcount+=addfile(lbph->path, ip);
172 fprintf(stderr, "?ASlink-Warning-Couldn't find library '%s'\n", ip);
176 /*)Function int addfile(path,libfil)
178 * char *path library path specification
179 * char *libfil library file specification
181 * The function addfile() searches for the library file
182 * by concatenating the path and libfil specifications.
183 * if the library is found, an lbname structure is created
184 * and linked to any previously defined structures. This
185 * linked list is used by the function fndsym() to attempt
186 * to find any undefined symbols.
188 * The function does not give report an error on invalid
189 * path / file specifications or if the file is not found.
192 * lbname *lbnh pointer to new name structure
193 * lbname *lbn temporary pointer
196 * lbname *lbnhead The pointer to the first
200 * char getnb() lklex.c
201 * VOID * new() lksym.c
202 * int strlen() c_library
203 * char * strcpy() c_library
204 * VOID unget() lklex.c
207 * An lbname structure may be created.
210 * 1: the library was found
211 * 0: the library was not found
214 int addfile(char * path, char * libfil)
218 struct lbname *lbnh, *lbn;
225 str = (char *) new (strlen(path) + strlen(libfil) + 6);
228 if (str[strlen(str)-1] != '/')
236 str = (char *) new (strlen(libfil) + 5);
240 if (libfil[0] == '/')
248 if(strchr(libfil, FSEPX) == NULL)
250 sprintf(&str[strlen(str)], "%clib", FSEPX);
256 /*Ok, that didn't work. Try with the 'libfil' name only*/
258 if(libfilinc) libfil--;
260 fp=fopen(libfil, "r");
263 /*Bingo! 'libfil' is the absolute path of the library*/
265 path=NULL;/*This way 'libfil' and 'path' will be rebuilt from 'str'*/
271 /*'path' can not be null since it is needed to find the '.rel' files associated with
272 the library. So, get 'path' from 'str' and then chop it off and recreate 'libfil'.
273 That way putting 'path' and 'libfil' together will result into the original filepath
274 as contained in 'str'.*/
276 path = (char *) new (strlen(str));
278 for(j=strlen(path)-1; j>=0; j--)
280 if((path[j]=='\\')||(path[j]=='/'))
282 strcpy(libfil, &path[j+1]);
293 lbnh = (struct lbname *) new (sizeof(struct lbname));
307 lbnh->libfil = (char *) new (strlen(libfil) + 1);
308 strcpy(lbnh->libfil,libfil);
319 /*)Function VOID search()
321 * The function search() looks through all the symbol tables
322 * at the end of pass 1. If any undefined symbols are found
323 * then the function fndsym() is called. Function fndsym()
324 * searches any specified library files to automagically
325 * import the object modules containing the needed symbol.
327 * After a symbol is found and imported by the function
328 * fndsym() the symbol tables are again searched. The
329 * symbol tables are search until no more symbols can be
330 * resolved within the library files. This ensures that
331 * back references from one library module to another are
335 * int i temporary counter
336 * sym *sp pointer to a symbol structure
337 * int symfnd found a symbol flag
340 * sym *symhash[] array of pointers to symbol tables
343 * int fndsym() lklibr.c
346 * If a symbol is found then the library object module
347 * containing the symbol will be imported and linked.
353 register struct sym *sp;
354 register int i,symfnd;
357 * Look for undefined symbols. Keep
358 * searching until no more symbols are resolved.
364 * Look through all the symbols
366 for (i=0; i<NHASH; ++i) {
369 /* If we find an undefined symbol
370 * (one where S_DEF is not set), then
371 * try looking for it. If we find it
372 * in any of the libraries then
373 * increment symfnd. This will force
374 * another pass of symbol searching and
375 * make sure that back references work.
377 if ((sp->s_type & S_DEF) == 0) {
378 if (fndsym(sp->s_id)) {
388 /*Load a .rel file embedded in a sdcclib file*/
389 void LoadRel(char * libfname, FILE * libfp, char * ModName)
394 while (fgets(str, NINPUT, libfp) != NULL)
396 str[NINPUT+1] = '\0';
401 if(EQ(str, "<FILE>"))
403 fgets(str, NINPUT, libfp);
404 str[NINPUT+1] = '\0';
406 if(EQ(str, ModName)) state=1;
409 fprintf(stderr, "?Aslink-Error-Bad offset in library file %s(%s)\n",
416 if(EQ(str, "<REL>")) state=2;
419 if(EQ(str, "</REL>")) return;
427 /*Load an .adb file embedded in a sdcclib file. If there is
428 something between <ADB> and </ADB> returns 1, otherwise returns 0.
429 This way the aomf51 will not have uselless empty modules. */
431 int LoadAdb(FILE * libfp)
437 while (fgets(str, MAXLINE, libfp) != NULL)
439 str[NINPUT+1] = '\0';
444 if(EQ(str, "<ADB>")) state=1;
447 if(EQ(str, "</ADB>")) return ToReturn;
448 fprintf(dfp, "%s\n", str);
456 /*Check for a symbol in a SDCC library. If found, add the embedded .rel and
457 .adb files from the library. The library must be created with the SDCC
458 librarian 'sdcclib' since the linking process depends on the correct file offsets
459 embedded in the library file.*/
461 int SdccLib(char * PathLib, FILE * libfp, char * DirLib, char * SymName)
463 struct lbfile *lbfh, *lbf;
464 char ModName[NCPS]="";
465 char FLine[MAXLINE+1];
467 long IndexOffset=0, FileOffset;
472 fgets(FLine, MAXLINE, libfp);
478 if(EQ(FLine, "<INDEX>"))
480 /*The next line has the size of the index*/
482 fgets(FLine, MAXLINE, libfp);
484 IndexOffset=atol(FLine);
489 if(EQ(FLine, "<MODULE>"))
491 /*The next line has the name of the module and the offset
492 of the corresponding embedded file in the library*/
494 fgets(FLine, MAXLINE, libfp);
496 sscanf(FLine, "%s %ld", ModName, &FileOffset);
499 else if(EQ(FLine, "</INDEX>"))
501 /*Reached the end of the index. The symbol is not in this library.*/
506 if(EQ(FLine, "</MODULE>"))
508 /*The symbol is not in this module, try the next one*/
513 /*Check if this is the symbol we are looking for.*/
514 if (strncmp(SymName, FLine, NCPS)==0)
516 /*The symbol is in this module.*/
518 /*As in the original library format, it is assumed that the .rel
519 files reside in the same directory as the lib files.*/
520 strcat(DirLib, ModName);
521 sprintf(&DirLib[strlen(DirLib)], "%crel", FSEPX);
523 /*If this module has been loaded already don't load it again.*/
527 if(EQ(DirLib, lbf->filspc)) return 1;/*Already loaded*/
531 /*Add the embedded file to the list of files to be loaded in
532 the second pass. That is performed latter by the function
534 lbfh = (struct lbfile *) new (sizeof(struct lbfile));
547 lbfh->libspc = PathLib;
548 lbfh->filspc = DirLib;
549 lbfh->relfil = (char *) new (strlen(ModName) + 1);
550 strcpy(lbfh->relfil, ModName);
551 /*Library embedded file, so lbfh->offset must be >=0*/
552 lbfh->offset = IndexOffset+FileOffset;
554 /*Jump to where the .rel begins and load it.*/
555 fseek(libfp, lbfh->offset, SEEK_SET);
556 LoadRel(PathLib, libfp, ModName);
558 /* if cdb information required & .adb file present */
562 SaveLinkedFilePath(DirLib);
564 return 1; /*Found the symbol, so success!*/
570 return 0; /*It should never reach this point, but just in case...*/
575 return 0; /*The symbol is not in this library*/
578 /*)Function VOID fndsym(name)
580 * char *name symbol name to find
582 * The function fndsym() searches through all combinations of the
583 * library path specifications (input by the -k option) and the
584 * library file specifications (input by the -l option) that
585 * lead to an existing file.
587 * The file specicifation may be formed in one of two ways:
589 * (1) If the library file contained an absolute
590 * path/file specification then this becomes filspc.
593 * (2) If the library file contains a relative path/file
594 * specification then the concatenation of the path
595 * and this file specification becomes filspc.
598 * The structure lbfile is created for the first library
599 * object file which contains the definition for the
600 * specified undefined symbol.
602 * If the library file [.LIB] contains file specifications for
603 * non existant files, no errors are returned.
606 * char buf[] [.REL] file input line
607 * char c [.REL] file input character
608 * FILE *fp file handle for object file
609 * lbfile *lbf temporary pointer
610 * lbfile *lbfh pointer to lbfile structure
611 * FILE *libfp file handle for library file
612 * lbname *lbnh pointer to lbname structure
613 * char *path file specification path
614 * char relfil[] [.REL] file specification
615 * char *str combined path and file specification
616 * char symname[] [.REL] file symbol string
619 * lbname *lbnhead The pointer to the first
621 * lbfile *lbfhead The pointer to the first
625 * int fclose() c_library
626 * int fgets() c_library
627 * FILE *fopen() c_library
628 * VOID free() c_library
629 * char getnb() lklex.c
630 * VOID lkexit() lkmain.c
631 * VOID loadfile() lklibr.c
632 * VOID * new() lksym.c
633 * char * sprintf() c_library
634 * int sscanf() c_library
635 * char * strcat() c_library
636 * char * strchr() c_library
637 * char * strcpy() c_library
638 * int strlen() c_library
639 * int strncmp() c_library
640 * VOID unget() lklex.c
643 * If the symbol is found then a new lbfile structure
644 * is created and added to the linked list of lbfile
645 * structures. The file containing the found symbol
651 int fndsym( char *name )
653 struct lbfile *lbfh, *lbf;
654 pmlibraryfile ThisLibr;
655 pmlibrarysymbol ThisSym = NULL;
657 pmlibraryfile FirstFound;
660 /* Build the index if this is the first call to fndsym */
661 if (libr==NULL) buildlibraryindex();
663 /* Iterate through all library object files */
665 FirstFound = libr; /*So gcc stops whining*/
668 /* Iterate through all symbols in an object file */
669 ThisSym = ThisLibr->symbols;
673 if (!strcmp(ThisSym->name, name))
675 if ((!ThisLibr->loaded) && (numfound==0))
677 /* Object file is not loaded - add it to the list */
678 lbfh = (struct lbfile *) new (sizeof(struct lbfile));
690 lbfh->libspc = ThisLibr->libspc;
691 lbfh->filspc = ThisLibr->filename;
692 lbfh->relfil = (char *) new (strlen(ThisLibr->relfil) + 1);
693 strcpy(lbfh->relfil, ThisLibr->relfil);
694 lbfh->offset = ThisLibr->offset;
696 { /*For an embedded object file in a library*/
697 void loadfile_SdccLib(char * libspc, char * module, long offset);
698 loadfile_SdccLib(lbfh->libspc, lbfh->relfil, lbfh->offset);
701 { /*For a stand alone object file*/
702 /* if cdb information required & adb file present */
705 FILE *xfp = afile(lbfh->filspc, "adb",0);
708 SaveLinkedFilePath(lbfh->filspc);
713 loadfile(lbfh->filspc);
725 char absPath1[PATH_MAX];
726 char absPath2[PATH_MAX];
727 #if defined(__BORLANDC__) || defined(_MSC_VER) || defined(__MINGW32__)
730 _fullpath(absPath1, FirstFound->libspc, PATH_MAX);
731 _fullpath(absPath2, ThisLibr->libspc, PATH_MAX);
732 for(j=0; absPath1[j]!=0; j++) absPath1[j]=tolower(absPath1[j]);
733 for(j=0; absPath2[j]!=0; j++) absPath2[j]=tolower(absPath2[j]);
735 realpath(FirstFound->libspc, absPath1);
736 realpath(ThisLibr->libspc, absPath2);
738 if( !( EQ(absPath1, absPath2) && EQ(FirstFound->relfil, ThisLibr->relfil) ) )
742 fprintf(stderr, "?Aslink-Warning-Definition of public symbol '%s'"
743 " found more than once:\n", name);
744 fprintf(stderr, " Library: '%s', Module: '%s'\n",
745 FirstFound->libspc, FirstFound->relfil);
747 fprintf(stderr, " Library: '%s', Module: '%s'\n",
748 ThisLibr->libspc, ThisLibr->relfil);
753 ThisSym=ThisSym->next; /* Next sym in library */
755 ThisLibr=ThisLibr->next; /* Next library in list */
760 pmlibraryfile buildlibraryindex_SdccLib(char * PathLib, FILE * libfp, char * DirLib, pmlibraryfile This)
762 char ModName[NCPS]="";
763 char FLine[MAXLINE+1];
766 long IndexOffset=0, FileOffset;
767 pmlibrarysymbol ThisSym = NULL;
772 fgets(FLine, MAXLINE, libfp);
778 if(EQ(FLine, "<INDEX>"))
780 /*The next line has the size of the index*/
782 fgets(FLine, MAXLINE, libfp);
784 IndexOffset=atol(FLine);
789 if(EQ(FLine, "<MODULE>"))
791 /*The next line has the name of the module and the offset
792 of the corresponding embedded file in the library*/
794 fgets(FLine, MAXLINE, libfp);
796 sscanf(FLine, "%s %ld", ModName, &FileOffset);
799 /*Create a new libraryfile object for this module*/
802 libr=This=(pmlibraryfile)new( sizeof( mlibraryfile ));
806 This->next=(pmlibraryfile)new( sizeof( mlibraryfile ));
811 This->offset=FileOffset+IndexOffset;
812 This->libspc=PathLib;
814 This->relfil=(char *)new(strlen(ModName)+1);
815 strcpy(This->relfil, ModName);
817 sprintf(buff, "%s%s%crel", DirLib, ModName, FSEPX);
818 This->filename=(char *)new(strlen(buff)+1);
819 strcpy(This->filename, buff);
821 This->symbols=ThisSym=NULL; /*Start a new linked list of symbols*/
823 else if(EQ(FLine, "</INDEX>"))
825 return This; /*Finish, get out of here*/
829 if(EQ(FLine, "</MODULE>"))
832 /*Create the index for the next module*/
838 if(ThisSym==NULL) /*First symbol of the current module*/
840 ThisSym=This->symbols=(pmlibrarysymbol)new(sizeof(mlibrarysymbol));
844 ThisSym->next = (pmlibrarysymbol)new(sizeof(mlibrarysymbol));
845 ThisSym=ThisSym->next;
848 ThisSym->name=(char *)new(strlen(FLine)+1);
849 strcpy(ThisSym->name, FLine);
854 return This; /*State machine should never reach this point, but just in case...*/
859 return This; /*State machine should never reach this point, but just in case...*/
863 /* buildlibraryindex - build an in-memory cache of the symbols contained in
866 int buildlibraryindex(void)
870 char relfil[NINPUT+2], str[PATH_MAX], *path;
871 char buf[NINPUT+2], c;
872 char symname[NINPUT+2];
873 pmlibraryfile This=NULL;
874 pmlibrarysymbol ThisSym;
877 * Search through every library in the linked list "lbnhead".
880 for (lbnh=lbnhead; lbnh; lbnh=lbnh->next)
882 if ((libfp = fopen(lbnh->libspc, "r")) == NULL)
884 fprintf(stderr, "?Aslink-Error-Cannot open library file %s\n",
891 * Read in a line from the library file.
892 * This is the relative file specification
893 * for a .REL file in this library.
896 while (fgets(relfil, NINPUT, libfp) != NULL)
898 relfil[NINPUT+1] = '\0';
904 if (str[strlen(str)-1] != '/')
915 if(strcmp(relfil, "<SDCCLIB>")==0)
917 /*Get the built in index of this library*/
918 This=buildlibraryindex_SdccLib(lbnh->libspc, libfp, str, This);
919 break; /*get the index for next library*/
922 /*From here down, build the index for the original library format*/
924 if (relfil[0] == '\\')
926 strcat(str,relfil+1);
933 if(strchr(relfil, FSEPX) == NULL)
935 sprintf(&str[strlen(str)], "%crel", FSEPX);
938 if ((fp = fopen(str, "r")) != NULL)
940 /* Opened OK - create a new libraryfile object for it */
943 libr=This=(pmlibraryfile)new( sizeof( mlibraryfile ));
947 This->next=(pmlibraryfile)new( sizeof( mlibraryfile ));
952 This->offset=-1; /*We have a stand alone .rel file*/
953 This->libspc = lbnh->libspc;
955 This->relfil=(char *)new(strlen(relfil)+1);
956 strcpy(This->relfil, relfil);
958 This->filename=(char *)new(strlen(str)+1);
959 strcpy(This->filename, str);
961 /*Start a new linked list of symbols for this module:*/
962 This->symbols=ThisSym=NULL;
965 * Read in the object file. Look for lines that
966 * begin with "S" and end with "D". These are
967 * symbol table definitions. If we find one, see
968 * if it is our symbol. Make sure we only read in
969 * our object file and don't go into the next one.
972 while (fgets(buf, NINPUT, fp) != NULL)
974 buf[NINPUT+1] = '\0';
975 buf[strlen(buf) - 1] = '\0';
978 * Skip everything that's not a symbol record.
980 if (buf[0] != 'S') continue;
983 * When a 'T line' is found terminate file scan.
984 * All 'S line's preceed 'T line's in .REL files.
986 if (buf[0] == 'T') break;
988 sscanf(buf, "S %s %c", symname, &c);
990 /* If it's an actual symbol, record it */
995 ThisSym=This->symbols=(pmlibrarysymbol)new(sizeof(mlibrarysymbol));
999 ThisSym->next=(pmlibrarysymbol)new(sizeof(mlibrarysymbol));
1000 ThisSym=ThisSym->next;
1004 ThisSym->name=(char *)new(strlen(symname)+1);
1005 strcpy(ThisSym->name, symname);
1007 } /* Closes while - read object file */
1009 } /* Closes if object file opened OK */
1012 fprintf(stderr, "?Aslink-Warning-Cannot open library module %s\n", str);
1014 } /* Ends while - processing all in libr */
1016 } /* Ends good open of libr file */
1020 /*Release all memory allocated for the in-memory library index*/
1021 void freelibraryindex (void)
1023 pmlibraryfile ThisLibr, ThisLibr2Free;
1024 pmlibrarysymbol ThisSym, ThisSym2Free;
1030 ThisSym = ThisLibr->symbols;
1034 free(ThisSym->name);
1035 ThisSym2Free=ThisSym;
1036 ThisSym=ThisSym->next;
1039 free(ThisLibr->filename);
1040 free(ThisLibr->relfil);
1041 ThisLibr2Free=ThisLibr;
1042 ThisLibr=ThisLibr->next;
1043 free(ThisLibr2Free);
1049 #else /* INDEXLIB */
1056 struct lbname *lbnh;
1057 struct lbfile *lbfh, *lbf;
1058 char relfil[NINPUT+2];
1060 char symname[NINPUT];
1066 * Search through every library in the linked list "lbnhead".
1069 for (lbnh=lbnhead; lbnh; lbnh=lbnh->next)
1071 if ((libfp = fopen(lbnh->libspc, "r")) == NULL)
1073 fprintf(stderr, "?Aslink-Error-Cannot open library file %s\n",
1080 * Read in a line from the library file.
1081 * This is the relative file specification
1082 * for a .REL file in this library.
1085 while (fgets(relfil, NINPUT, libfp) != NULL)
1087 relfil[NINPUT+1] = '\0';
1091 str = (char *) new (strlen(path)+strlen(relfil)+6);
1094 if (str[strlen(str)-1] != '/')
1102 str = (char *) new (strlen(relfil) + 5);
1105 if(strcmp(relfil, "<SDCCLIB>")==0)
1107 result=SdccLib(lbnh->libspc, libfp, str, name);
1108 if(result) return(1); /*Found the symbol*/
1110 /*The symbol is not in the current library,
1111 check the next library in the list*/
1115 /*From here down is the support for libraries in the original format*/
1116 if (relfil[0] == '\\')
1118 strcat(str,relfil+1);
1125 if(strchr(relfil, FSEPX) == NULL)
1127 sprintf(&str[strlen(str)], "%crel", FSEPX);
1130 if ((fp = fopen(str, "r")) != NULL)
1134 * Read in the object file. Look for lines that
1135 * begin with "S" and end with "D". These are
1136 * symbol table definitions. If we find one, see
1137 * if it is our symbol. Make sure we only read in
1138 * our object file and don't go into the next one.
1141 while (fgets(buf, NINPUT, fp) != NULL)
1143 buf[NINPUT+1] = '\0';
1146 * Skip everything that's not a symbol record.
1148 if (buf[0] != 'S') continue;
1151 * When a 'T line' is found terminate file scan.
1152 * All 'S line's preceed 'T line's in .REL files.
1154 if (buf[0] == 'T') break;
1156 sscanf(buf, "S %s %c", symname, &c);
1159 * If we find a symbol definition for the
1160 * symbol we're looking for, load in the
1161 * file and add it to lbfhead so it gets
1162 * loaded on pass number 2.
1164 if (strncmp(symname, name, NCPS) == 0 && c == 'D')
1166 lbfh = (struct lbfile *) new (sizeof(struct lbfile));
1167 if (lbfhead == NULL)
1179 lbfh->libspc = lbnh->libspc;
1181 lbfh->relfil = (char *) new (strlen(relfil) + 1);
1182 lbfh->offset = -1; /*Stand alone rel file*/
1183 strcpy(lbfh->relfil,relfil);
1187 /* if cdb information required & adb file present */
1190 FILE *xfp = afile(str,"adb",0); //JCF: Nov 30, 2002
1193 SaveLinkedFilePath(str);
1213 void loadfile_SdccLib(char * libspc, char * module, long offset)
1217 if ((fp = fopen(libspc,"r")) != NULL)
1219 fseek(fp, offset, SEEK_SET);
1220 LoadRel(libspc, fp, module);
1225 /*)Function VOID library()
1227 * The function library() links all the library object files
1228 * contained in the lbfile structures.
1231 * lbfile *lbfh pointer to lbfile structure
1234 * lbfile *lbfhead pointer to first lbfile structure
1237 * VOID loadfile lklibr.c
1240 * Links all files contained in the lbfile structures.
1246 struct lbfile *lbfh;
1248 for (lbfh=lbfhead; lbfh; lbfh=lbfh->next)
1252 /*Stand alone rel file (original lib format)*/
1253 loadfile(lbfh->filspc);
1257 /*rel file embedded in lib (new lib format)*/
1258 loadfile_SdccLib(lbfh->libspc, lbfh->relfil, lbfh->offset);
1266 /*)Function VOID loadfile(filspc)
1268 * char *filspc library object file specification
1270 * The function loadfile() links the library object module.
1273 * FILE *fp file handle
1274 * int i input line length
1275 * char str[] file input line
1278 * char *ip pointer to linker input string
1281 * int fclose() c_library
1282 * int fgets() c_library
1283 * FILE * fopen() c_library
1284 * VOID link_main() lkmain.c
1285 * int strlen() c_library
1288 * If file exists it is linked.
1298 if ((fp = fopen(filspc,"r")) != NULL) {
1299 while (fgets(str, NINPUT, fp) != NULL) {
1300 str[NINPUT+1] = '\0';