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>
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)) {
391 /*Load a .rel file embedded in a sdcclib file*/
392 void LoadRel(char * libfname, FILE * libfp, char * ModName)
397 while (fgets(str, NINPUT, libfp) != NULL)
399 str[NINPUT+1] = '\0';
404 if(EQ(str, "<FILE>"))
406 fgets(str, NINPUT, libfp);
407 str[NINPUT+1] = '\0';
409 if(EQ(str, ModName)) state=1;
412 fprintf(stderr, "?Aslink-Error-Bad offset in library file %s(%s)\n",
419 if(EQ(str, "<REL>")) state=2;
422 if(EQ(str, "</REL>")) return;
430 /*Load an .adb file embedded in a sdcclib file. If there is
431 something between <ADB> and </ADB> returns 1, otherwise returns 0.
432 This way the aomf51 will not have uselless empty modules. */
434 int LoadAdb(FILE * libfp)
440 while (fgets(str, MAXLINE, libfp) != NULL)
442 str[NINPUT+1] = '\0';
447 if(EQ(str, "<ADB>")) state=1;
450 if(EQ(str, "</ADB>")) return ToReturn;
451 fprintf(dfp, "%s\n", str);
459 /*Check for a symbol in a SDCC library. If found, add the embedded .rel and
460 .adb files from the library. The library must be created with the SDCC
461 librarian 'sdcclib' since the linking process depends on the correct file offsets
462 embedded in the library file.*/
464 int SdccLib(char * PathLib, FILE * libfp, char * DirLib, char * SymName)
466 struct lbfile *lbfh, *lbf;
467 char ModName[NCPS]="";
468 char FLine[MAXLINE+1];
470 long IndexOffset=0, FileOffset;
475 fgets(FLine, MAXLINE, libfp);
481 if(EQ(FLine, "<INDEX>"))
483 /*The next line has the size of the index*/
485 fgets(FLine, MAXLINE, libfp);
487 IndexOffset=atol(FLine);
492 if(EQ(FLine, "<MODULE>"))
494 /*The next line has the name of the module and the offset
495 of the corresponding embedded file in the library*/
497 fgets(FLine, MAXLINE, libfp);
499 sscanf(FLine, "%s %ld", ModName, &FileOffset);
502 else if(EQ(FLine, "</INDEX>"))
504 /*Reached the end of the index. The symbol is not in this library.*/
509 if(EQ(FLine, "</MODULE>"))
511 /*The symbol is not in this module, try the next one*/
516 /*Check if this is the symbol we are looking for.*/
517 if (strncmp(SymName, FLine, NCPS)==0)
519 /*The symbol is in this module.*/
521 /*As in the original library format, it is assumed that the .rel
522 files reside in the same directory as the lib files.*/
523 strcat(DirLib, ModName);
524 sprintf(&DirLib[strlen(DirLib)], "%crel", FSEPX);
526 /*If this module has been loaded already don't load it again.*/
530 if(EQ(DirLib, lbf->filspc)) return 1;/*Already loaded*/
534 /*Add the embedded file to the list of files to be loaded in
535 the second pass. That is performed latter by the function
537 lbfh = (struct lbfile *) new (sizeof(struct lbfile));
550 lbfh->libspc = PathLib;
551 lbfh->filspc = DirLib;
552 lbfh->relfil = (char *) new (strlen(ModName) + 1);
553 strcpy(lbfh->relfil, ModName);
554 /*Library embedded file, so lbfh->offset must be >=0*/
555 lbfh->offset = IndexOffset+FileOffset;
557 /*Jump to where the .rel begins and load it.*/
558 fseek(libfp, lbfh->offset, SEEK_SET);
559 LoadRel(PathLib, libfp, ModName);
561 /* if cdb information required & .adb file present */
565 SaveLinkedFilePath(DirLib);
567 return 1; /*Found the symbol, so success!*/
573 return 0; /*It should never reach this point, but just in case...*/
578 return 0; /*The symbol is not in this library*/
581 /*)Function VOID fndsym(name)
583 * char *name symbol name to find
585 * The function fndsym() searches through all combinations of the
586 * library path specifications (input by the -k option) and the
587 * library file specifications (input by the -l option) that
588 * lead to an existing file.
590 * The file specicifation may be formed in one of two ways:
592 * (1) If the library file contained an absolute
593 * path/file specification then this becomes filspc.
596 * (2) If the library file contains a relative path/file
597 * specification then the concatenation of the path
598 * and this file specification becomes filspc.
601 * The structure lbfile is created for the first library
602 * object file which contains the definition for the
603 * specified undefined symbol.
605 * If the library file [.LIB] contains file specifications for
606 * non existant files, no errors are returned.
609 * char buf[] [.REL] file input line
610 * char c [.REL] file input character
611 * FILE *fp file handle for object file
612 * lbfile *lbf temporary pointer
613 * lbfile *lbfh pointer to lbfile structure
614 * FILE *libfp file handle for library file
615 * lbname *lbnh pointer to lbname structure
616 * char *path file specification path
617 * char relfil[] [.REL] file specification
618 * char *str combined path and file specification
619 * char symname[] [.REL] file symbol string
622 * lbname *lbnhead The pointer to the first
624 * lbfile *lbfhead The pointer to the first
628 * int fclose() c_library
629 * int fgets() c_library
630 * FILE *fopen() c_library
631 * VOID free() c_library
632 * char getnb() lklex.c
633 * VOID lkexit() lkmain.c
634 * VOID loadfile() lklibr.c
635 * VOID * new() lksym.c
636 * char * sprintf() c_library
637 * int sscanf() c_library
638 * char * strcat() c_library
639 * char * strchr() c_library
640 * char * strcpy() c_library
641 * int strlen() c_library
642 * int strncmp() c_library
643 * VOID unget() lklex.c
646 * If the symbol is found then a new lbfile structure
647 * is created and added to the linked list of lbfile
648 * structures. The file containing the found symbol
654 int fndsym( char *name )
656 struct lbfile *lbfh, *lbf;
657 pmlibraryfile ThisLibr;
658 pmlibrarysymbol ThisSym = NULL;
660 pmlibraryfile FirstFound;
663 /* Build the index if this is the first call to fndsym */
664 if (libr==NULL) buildlibraryindex();
666 /* Iterate through all library object files */
668 FirstFound = libr; /*So gcc stops whining*/
671 /* Iterate through all symbols in an object file */
672 ThisSym = ThisLibr->symbols;
676 if (!strcmp(ThisSym->name, name))
678 if ((!ThisLibr->loaded) && (numfound==0))
680 /* Object file is not loaded - add it to the list */
681 lbfh = (struct lbfile *) new (sizeof(struct lbfile));
693 lbfh->libspc = ThisLibr->libspc;
694 lbfh->filspc = ThisLibr->filename;
695 lbfh->relfil = (char *) new (strlen(ThisLibr->relfil) + 1);
696 strcpy(lbfh->relfil, ThisLibr->relfil);
697 lbfh->offset = ThisLibr->offset;
699 { /*For an embedded object file in a library*/
700 void loadfile_SdccLib(char * libspc, char * module, long offset);
701 loadfile_SdccLib(lbfh->libspc, lbfh->relfil, lbfh->offset);
704 { /*For a stand alone object file*/
705 /* if cdb information required & adb file present */
708 FILE *xfp = afile(lbfh->filspc, "adb",0);
711 SaveLinkedFilePath(lbfh->filspc);
716 loadfile(lbfh->filspc);
728 char absPath1[PATH_MAX];
729 char absPath2[PATH_MAX];
730 #if defined(__BORLANDC__) || defined(_MSC_VER) || defined(__MINGW32__)
733 _fullpath(absPath1, FirstFound->libspc, PATH_MAX);
734 _fullpath(absPath2, ThisLibr->libspc, PATH_MAX);
735 for(j=0; absPath1[j]!=0; j++) absPath1[j]=tolower(absPath1[j]);
736 for(j=0; absPath2[j]!=0; j++) absPath2[j]=tolower(absPath2[j]);
738 realpath(FirstFound->libspc, absPath1);
739 realpath(ThisLibr->libspc, absPath2);
741 if( !( EQ(absPath1, absPath2) && EQ(FirstFound->relfil, ThisLibr->relfil) ) )
745 fprintf(stderr, "?Aslink-Warning-Definition of public symbol '%s'"
746 " found more than once:\n", name);
747 fprintf(stderr, " Library: '%s', Module: '%s'\n",
748 FirstFound->libspc, FirstFound->relfil);
750 fprintf(stderr, " Library: '%s', Module: '%s'\n",
751 ThisLibr->libspc, ThisLibr->relfil);
756 ThisSym=ThisSym->next; /* Next sym in library */
758 ThisLibr=ThisLibr->next; /* Next library in list */
763 pmlibraryfile buildlibraryindex_SdccLib(char * PathLib, FILE * libfp, char * DirLib, pmlibraryfile This)
765 char ModName[NCPS]="";
766 char FLine[MAXLINE+1];
769 long IndexOffset=0, FileOffset;
770 pmlibrarysymbol ThisSym = NULL;
775 fgets(FLine, MAXLINE, libfp);
781 if(EQ(FLine, "<INDEX>"))
783 /*The next line has the size of the index*/
785 fgets(FLine, MAXLINE, libfp);
787 IndexOffset=atol(FLine);
792 if(EQ(FLine, "<MODULE>"))
794 /*The next line has the name of the module and the offset
795 of the corresponding embedded file in the library*/
797 fgets(FLine, MAXLINE, libfp);
799 sscanf(FLine, "%s %ld", ModName, &FileOffset);
802 /*Create a new libraryfile object for this module*/
805 libr=This=(pmlibraryfile)new( sizeof( mlibraryfile ));
809 This->next=(pmlibraryfile)new( sizeof( mlibraryfile ));
814 This->offset=FileOffset+IndexOffset;
815 This->libspc=PathLib;
817 This->relfil=(char *)new(strlen(ModName)+1);
818 strcpy(This->relfil, ModName);
820 sprintf(buff, "%s%s%crel", DirLib, ModName, FSEPX);
821 This->filename=(char *)new(strlen(buff)+1);
822 strcpy(This->filename, buff);
824 This->symbols=ThisSym=NULL; /*Start a new linked list of symbols*/
826 else if(EQ(FLine, "</INDEX>"))
828 return This; /*Finish, get out of here*/
832 if(EQ(FLine, "</MODULE>"))
835 /*Create the index for the next module*/
841 if(ThisSym==NULL) /*First symbol of the current module*/
843 ThisSym=This->symbols=(pmlibrarysymbol)new(sizeof(mlibrarysymbol));
847 ThisSym->next = (pmlibrarysymbol)new(sizeof(mlibrarysymbol));
848 ThisSym=ThisSym->next;
851 ThisSym->name=(char *)new(strlen(FLine)+1);
852 strcpy(ThisSym->name, FLine);
857 return This; /*State machine should never reach this point, but just in case...*/
862 return This; /*State machine should never reach this point, but just in case...*/
866 /* buildlibraryindex - build an in-memory cache of the symbols contained in
869 int buildlibraryindex(void)
873 char relfil[NINPUT+2], str[PATH_MAX], *path;
874 char buf[NINPUT+2], c;
875 char symname[NINPUT+2];
876 pmlibraryfile This=NULL;
877 pmlibrarysymbol ThisSym;
880 * Search through every library in the linked list "lbnhead".
883 for (lbnh=lbnhead; lbnh; lbnh=lbnh->next)
885 if ((libfp = fopen(lbnh->libspc, "r")) == NULL)
887 fprintf(stderr, "?Aslink-Error-Cannot open library file %s\n",
894 * Read in a line from the library file.
895 * This is the relative file specification
896 * for a .REL file in this library.
899 while (fgets(relfil, NINPUT, libfp) != NULL)
901 relfil[NINPUT+1] = '\0';
907 if (str[strlen(str)-1] != '/')
918 if(strcmp(relfil, "<SDCCLIB>")==0)
920 /*Get the built in index of this library*/
921 This=buildlibraryindex_SdccLib(lbnh->libspc, libfp, str, This);
922 break; /*get the index for next library*/
925 /*From here down, build the index for the original library format*/
927 if (relfil[0] == '\\')
929 strcat(str,relfil+1);
936 if(strchr(relfil, FSEPX) == NULL)
938 sprintf(&str[strlen(str)], "%crel", FSEPX);
941 if ((fp = fopen(str, "r")) != NULL)
943 /* Opened OK - create a new libraryfile object for it */
946 libr=This=(pmlibraryfile)new( sizeof( mlibraryfile ));
950 This->next=(pmlibraryfile)new( sizeof( mlibraryfile ));
955 This->offset=-1; /*We have a stand alone .rel file*/
956 This->libspc = lbnh->libspc;
958 This->relfil=(char *)new(strlen(relfil)+1);
959 strcpy(This->relfil, relfil);
961 This->filename=(char *)new(strlen(str)+1);
962 strcpy(This->filename, str);
964 /*Start a new linked list of symbols for this module:*/
965 This->symbols=ThisSym=NULL;
968 * Read in the object file. Look for lines that
969 * begin with "S" and end with "D". These are
970 * symbol table definitions. If we find one, see
971 * if it is our symbol. Make sure we only read in
972 * our object file and don't go into the next one.
975 while (fgets(buf, NINPUT, fp) != NULL)
977 buf[NINPUT+1] = '\0';
978 buf[strlen(buf) - 1] = '\0';
981 * Skip everything that's not a symbol record.
983 if (buf[0] != 'S') continue;
986 * When a 'T line' is found terminate file scan.
987 * All 'S line's preceed 'T line's in .REL files.
989 if (buf[0] == 'T') break;
991 sscanf(buf, "S %s %c", symname, &c);
993 /* If it's an actual symbol, record it */
998 ThisSym=This->symbols=(pmlibrarysymbol)new(sizeof(mlibrarysymbol));
1002 ThisSym->next=(pmlibrarysymbol)new(sizeof(mlibrarysymbol));
1003 ThisSym=ThisSym->next;
1007 ThisSym->name=(char *)new(strlen(symname)+1);
1008 strcpy(ThisSym->name, symname);
1010 } /* Closes while - read object file */
1012 } /* Closes if object file opened OK */
1015 fprintf(stderr, "?Aslink-Warning-Cannot open library module %s\n", str);
1017 } /* Ends while - processing all in libr */
1019 } /* Ends good open of libr file */
1023 /*Release all memory allocated for the in-memory library index*/
1024 void freelibraryindex (void)
1026 pmlibraryfile ThisLibr, ThisLibr2Free;
1027 pmlibrarysymbol ThisSym, ThisSym2Free;
1033 ThisSym = ThisLibr->symbols;
1037 free(ThisSym->name);
1038 ThisSym2Free=ThisSym;
1039 ThisSym=ThisSym->next;
1042 free(ThisLibr->filename);
1043 free(ThisLibr->relfil);
1044 ThisLibr2Free=ThisLibr;
1045 ThisLibr=ThisLibr->next;
1046 free(ThisLibr2Free);
1052 #else /* INDEXLIB */
1059 struct lbname *lbnh;
1060 struct lbfile *lbfh, *lbf;
1061 char relfil[NINPUT+2];
1063 char symname[NINPUT];
1069 * Search through every library in the linked list "lbnhead".
1072 for (lbnh=lbnhead; lbnh; lbnh=lbnh->next)
1074 if ((libfp = fopen(lbnh->libspc, "r")) == NULL)
1076 fprintf(stderr, "?Aslink-Error-Cannot open library file %s\n",
1083 * Read in a line from the library file.
1084 * This is the relative file specification
1085 * for a .REL file in this library.
1088 while (fgets(relfil, NINPUT, libfp) != NULL)
1090 relfil[NINPUT+1] = '\0';
1094 str = (char *) new (strlen(path)+strlen(relfil)+6);
1097 if (str[strlen(str)-1] != '/')
1105 str = (char *) new (strlen(relfil) + 5);
1108 if(strcmp(relfil, "<SDCCLIB>")==0)
1110 result=SdccLib(lbnh->libspc, libfp, str, name);
1111 if(result) return(1); /*Found the symbol*/
1113 /*The symbol is not in the current library,
1114 check the next library in the list*/
1118 /*From here down is the support for libraries in the original format*/
1119 if (relfil[0] == '\\')
1121 strcat(str,relfil+1);
1128 if(strchr(relfil, FSEPX) == NULL)
1130 sprintf(&str[strlen(str)], "%crel", FSEPX);
1133 if ((fp = fopen(str, "r")) != NULL)
1137 * Read in the object file. Look for lines that
1138 * begin with "S" and end with "D". These are
1139 * symbol table definitions. If we find one, see
1140 * if it is our symbol. Make sure we only read in
1141 * our object file and don't go into the next one.
1144 while (fgets(buf, NINPUT, fp) != NULL)
1146 buf[NINPUT+1] = '\0';
1149 * Skip everything that's not a symbol record.
1151 if (buf[0] != 'S') continue;
1154 * When a 'T line' is found terminate file scan.
1155 * All 'S line's preceed 'T line's in .REL files.
1157 if (buf[0] == 'T') break;
1159 sscanf(buf, "S %s %c", symname, &c);
1162 * If we find a symbol definition for the
1163 * symbol we're looking for, load in the
1164 * file and add it to lbfhead so it gets
1165 * loaded on pass number 2.
1167 if (strncmp(symname, name, NCPS) == 0 && c == 'D')
1169 lbfh = (struct lbfile *) new (sizeof(struct lbfile));
1170 if (lbfhead == NULL)
1182 lbfh->libspc = lbnh->libspc;
1184 lbfh->relfil = (char *) new (strlen(relfil) + 1);
1185 lbfh->offset = -1; /*Stand alone rel file*/
1186 strcpy(lbfh->relfil,relfil);
1190 /* if cdb information required & adb file present */
1193 FILE *xfp = afile(str,"adb",0); //JCF: Nov 30, 2002
1196 SaveLinkedFilePath(str);
1216 void loadfile_SdccLib(char * libspc, char * module, long offset)
1220 if ((fp = fopen(libspc,"r")) != NULL)
1222 fseek(fp, offset, SEEK_SET);
1223 LoadRel(libspc, fp, module);
1228 /*)Function VOID library()
1230 * The function library() links all the library object files
1231 * contained in the lbfile structures.
1234 * lbfile *lbfh pointer to lbfile structure
1237 * lbfile *lbfhead pointer to first lbfile structure
1240 * VOID loadfile lklibr.c
1243 * Links all files contained in the lbfile structures.
1249 struct lbfile *lbfh;
1251 for (lbfh=lbfhead; lbfh; lbfh=lbfh->next)
1255 /*Stand alone rel file (original lib format)*/
1256 loadfile(lbfh->filspc);
1260 /*rel file embedded in lib (new lib format)*/
1261 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';