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>
37 * The module lklibr.c contains the functions which
38 * (1) specify the path(s) to library files [.LIB]
39 * (2) specify the library file(s) [.LIB] to search
40 * (3) search the library files for specific symbols
41 * and link the module containing this symbol
43 * lklibr.c contains the following functions:
55 typedef struct slibrarysymbol mlibrarysymbol;
56 typedef struct slibrarysymbol *pmlibrarysymbol;
58 struct slibrarysymbol {
59 char * name; /*Warning: allocate memory before using*/
63 typedef struct slibraryfile mlibraryfile;
64 typedef struct slibraryfile *pmlibraryfile;
69 char * relfil; /*Warning: allocate memory before using*/
70 char * filename; /*Warning: allocate memory before using*/
71 long offset; //if > 0, the embedded file offset in the library file libspc
72 pmlibrarysymbol symbols;
76 /* First entry in the library object symbol cache */
77 pmlibraryfile libr=NULL;
79 int buildlibraryindex();
80 void freelibraryindex (void);
83 /*)Function VOID addpath()
85 * The function addpath() creates a linked structure containing
86 * the paths to various object module library files.
89 * lbpath *lbph pointer to new path structure
90 * lbpath *lbp temporary pointer
93 * lbpath *lbphead The pointer to the first
97 * char getnb() lklex.c
98 * VOID * new() lksym.c
99 * int strlen() c_library
100 * char * strcpy() c_library
101 * VOID unget() lklex.c
104 * An lbpath structure may be created.
110 struct lbpath *lbph, *lbp;
112 lbph = (struct lbpath *) new (sizeof(struct lbpath));
113 if (lbphead == NULL) {
122 lbph->path = (char *) new (strlen(ip)+1);
123 strcpy(lbph->path, ip);
126 /*)Function VOID addlib()
128 * The function addlib() tests for the existance of a
129 * library path structure to determine the method of
130 * adding this library file to the library search structure.
132 * This function calls the function addfile() to actually
133 * add the library file to the search list.
136 * lbpath *lbph pointer to path structure
139 * lbpath *lbphead The pointer to the first
141 * ip a pointer to the library name
144 * VOID addfile() lklibr.c
145 * char getnb() lklex.c
146 * VOID unget() lklex.c
149 * The function addfile() may add the file to
150 * the library search list.
163 foundcount=addfile(NULL, ip);
167 for (lbph=lbphead; lbph; lbph=lbph->next)
169 foundcount+=addfile(lbph->path, ip);
174 fprintf(stderr, "?ASlink-Warning-Couldn't find library '%s'\n", ip);
178 /*)Function int addfile(path,libfil)
180 * char *path library path specification
181 * char *libfil library file specification
183 * The function addfile() searches for the library file
184 * by concatenating the path and libfil specifications.
185 * if the library is found, an lbname structure is created
186 * and linked to any previously defined structures. This
187 * linked list is used by the function fndsym() to attempt
188 * to find any undefined symbols.
190 * The function does not give report an error on invalid
191 * path / file specifications or if the file is not found.
194 * lbname *lbnh pointer to new name structure
195 * lbname *lbn temporary pointer
198 * lbname *lbnhead The pointer to the first
202 * char getnb() lklex.c
203 * VOID * new() lksym.c
204 * int strlen() c_library
205 * char * strcpy() c_library
206 * VOID unget() lklex.c
209 * An lbname structure may be created.
212 * 1: the library was found
213 * 0: the library was not found
216 int addfile(char * path, char * libfil)
220 struct lbname *lbnh, *lbn;
227 str = (char *) new (strlen(path) + strlen(libfil) + 6);
230 if (str[strlen(str)-1] != '/')
238 str = (char *) new (strlen(libfil) + 5);
242 if (libfil[0] == '/')
250 if(strchr(libfil, FSEPX) == NULL)
252 sprintf(&str[strlen(str)], "%clib", FSEPX);
258 /*Ok, that didn't work. Try with the 'libfil' name only*/
260 if(libfilinc) libfil--;
262 fp=fopen(libfil, "r");
265 /*Bingo! 'libfil' is the absolute path of the library*/
267 path=NULL;/*This way 'libfil' and 'path' will be rebuilt from 'str'*/
273 /*'path' can not be null since it is needed to find the '.rel' files associated with
274 the library. So, get 'path' from 'str' and then chop it off and recreate 'libfil'.
275 That way putting 'path' and 'libfil' together will result into the original filepath
276 as contained in 'str'.*/
278 path = (char *) new (strlen(str));
280 for(j=strlen(path)-1; j>=0; j--)
282 if((path[j]=='\\')||(path[j]=='/'))
284 strcpy(libfil, &path[j+1]);
295 lbnh = (struct lbname *) new (sizeof(struct lbname));
309 lbnh->libfil = (char *) new (strlen(libfil) + 1);
310 strcpy(lbnh->libfil,libfil);
321 /*)Function VOID search()
323 * The function search() looks through all the symbol tables
324 * at the end of pass 1. If any undefined symbols are found
325 * then the function fndsym() is called. Function fndsym()
326 * searches any specified library files to automagically
327 * import the object modules containing the needed symbol.
329 * After a symbol is found and imported by the function
330 * fndsym() the symbol tables are again searched. The
331 * symbol tables are search until no more symbols can be
332 * resolved within the library files. This ensures that
333 * back references from one library module to another are
337 * int i temporary counter
338 * sym *sp pointer to a symbol structure
339 * int symfnd found a symbol flag
342 * sym *symhash[] array of pointers to symbol tables
345 * int fndsym() lklibr.c
348 * If a symbol is found then the library object module
349 * containing the symbol will be imported and linked.
355 register struct sym *sp;
356 register int i,symfnd;
359 * Look for undefined symbols. Keep
360 * searching until no more symbols are resolved.
366 * Look through all the symbols
368 for (i=0; i<NHASH; ++i) {
371 /* If we find an undefined symbol
372 * (one where S_DEF is not set), then
373 * try looking for it. If we find it
374 * in any of the libraries then
375 * increment symfnd. This will force
376 * another pass of symbol searching and
377 * make sure that back references work.
379 if ((sp->s_type & S_DEF) == 0) {
380 if (fndsym(sp->s_id)) {
390 /*Load a .rel file embedded in a sdcclib file*/
391 void LoadRel(char * libfname, FILE * libfp, char * ModName)
396 while (fgets(str, NINPUT, libfp) != NULL)
398 str[NINPUT+1] = '\0';
403 if(EQ(str, "<FILE>"))
405 fgets(str, NINPUT, libfp);
406 str[NINPUT+1] = '\0';
408 if(EQ(str, ModName)) state=1;
411 fprintf(stderr, "?Aslink-Error-Bad offset in library file %s(%s)\n",
418 if(EQ(str, "<REL>")) state=2;
421 if(EQ(str, "</REL>")) return;
429 /*Load an .adb file embedded in a sdcclib file. If there is
430 something between <ADB> and </ADB> returns 1, otherwise returns 0.
431 This way the aomf51 will not have uselless empty modules. */
433 int LoadAdb(FILE * libfp)
439 while (fgets(str, MAXLINE, libfp) != NULL)
441 str[NINPUT+1] = '\0';
446 if(EQ(str, "<ADB>")) state=1;
449 if(EQ(str, "</ADB>")) return ToReturn;
450 fprintf(dfp, "%s\n", str);
458 /*Check for a symbol in a SDCC library. If found, add the embedded .rel and
459 .adb files from the library. The library must be created with the SDCC
460 librarian 'sdcclib' since the linking process depends on the correct file offsets
461 embedded in the library file.*/
463 int SdccLib(char * PathLib, FILE * libfp, char * DirLib, char * SymName)
465 struct lbfile *lbfh, *lbf;
466 char ModName[NCPS]="";
467 char FLine[MAXLINE+1];
469 long IndexOffset=0, FileOffset;
474 fgets(FLine, MAXLINE, libfp);
480 if(EQ(FLine, "<INDEX>"))
482 /*The next line has the size of the index*/
484 fgets(FLine, MAXLINE, libfp);
486 IndexOffset=atol(FLine);
491 if(EQ(FLine, "<MODULE>"))
493 /*The next line has the name of the module and the offset
494 of the corresponding embedded file in the library*/
496 fgets(FLine, MAXLINE, libfp);
498 sscanf(FLine, "%s %ld", ModName, &FileOffset);
501 else if(EQ(FLine, "</INDEX>"))
503 /*Reached the end of the index. The symbol is not in this library.*/
508 if(EQ(FLine, "</MODULE>"))
510 /*The symbol is not in this module, try the next one*/
515 /*Check if this is the symbol we are looking for.*/
516 if (strncmp(SymName, FLine, NCPS)==0)
518 /*The symbol is in this module.*/
520 /*As in the original library format, it is assumed that the .rel
521 files reside in the same directory as the lib files.*/
522 strcat(DirLib, ModName);
523 sprintf(&DirLib[strlen(DirLib)], "%crel", FSEPX);
525 /*If this module has been loaded already don't load it again.*/
529 if(EQ(DirLib, lbf->filspc)) return 1;/*Already loaded*/
533 /*Add the embedded file to the list of files to be loaded in
534 the second pass. That is performed latter by the function
536 lbfh = (struct lbfile *) new (sizeof(struct lbfile));
549 lbfh->libspc = PathLib;
550 lbfh->filspc = DirLib;
551 lbfh->relfil = (char *) new (strlen(ModName) + 1);
552 strcpy(lbfh->relfil, ModName);
553 /*Library embedded file, so lbfh->offset must be >=0*/
554 lbfh->offset = IndexOffset+FileOffset;
556 /*Jump to where the .rel begins and load it.*/
557 fseek(libfp, lbfh->offset, SEEK_SET);
558 LoadRel(PathLib, libfp, ModName);
560 /* if cdb information required & .adb file present */
564 SaveLinkedFilePath(DirLib);
566 return 1; /*Found the symbol, so success!*/
572 return 0; /*It should never reach this point, but just in case...*/
577 return 0; /*The symbol is not in this library*/
580 /*)Function VOID fndsym(name)
582 * char *name symbol name to find
584 * The function fndsym() searches through all combinations of the
585 * library path specifications (input by the -k option) and the
586 * library file specifications (input by the -l option) that
587 * lead to an existing file.
589 * The file specicifation may be formed in one of two ways:
591 * (1) If the library file contained an absolute
592 * path/file specification then this becomes filspc.
595 * (2) If the library file contains a relative path/file
596 * specification then the concatenation of the path
597 * and this file specification becomes filspc.
600 * The structure lbfile is created for the first library
601 * object file which contains the definition for the
602 * specified undefined symbol.
604 * If the library file [.LIB] contains file specifications for
605 * non existant files, no errors are returned.
608 * char buf[] [.REL] file input line
609 * char c [.REL] file input character
610 * FILE *fp file handle for object file
611 * lbfile *lbf temporary pointer
612 * lbfile *lbfh pointer to lbfile structure
613 * FILE *libfp file handle for library file
614 * lbname *lbnh pointer to lbname structure
615 * char *path file specification path
616 * char relfil[] [.REL] file specification
617 * char *str combined path and file specification
618 * char symname[] [.REL] file symbol string
621 * lbname *lbnhead The pointer to the first
623 * lbfile *lbfhead The pointer to the first
627 * int fclose() c_library
628 * int fgets() c_library
629 * FILE *fopen() c_library
630 * VOID free() c_library
631 * char getnb() lklex.c
632 * VOID lkexit() lkmain.c
633 * VOID loadfile() lklibr.c
634 * VOID * new() lksym.c
635 * char * sprintf() c_library
636 * int sscanf() c_library
637 * char * strcat() c_library
638 * char * strchr() c_library
639 * char * strcpy() c_library
640 * int strlen() c_library
641 * int strncmp() c_library
642 * VOID unget() lklex.c
645 * If the symbol is found then a new lbfile structure
646 * is created and added to the linked list of lbfile
647 * structures. The file containing the found symbol
653 int fndsym( char *name )
655 struct lbfile *lbfh, *lbf;
656 pmlibraryfile ThisLibr;
657 pmlibrarysymbol ThisSym = NULL;
659 pmlibraryfile FirstFound;
662 /* Build the index if this is the first call to fndsym */
663 if (libr==NULL) buildlibraryindex();
665 /* Iterate through all library object files */
667 FirstFound = libr; /*So gcc stops whining*/
670 /* Iterate through all symbols in an object file */
671 ThisSym = ThisLibr->symbols;
675 if (!strcmp(ThisSym->name, name))
677 if ((!ThisLibr->loaded) && (numfound==0))
679 /* Object file is not loaded - add it to the list */
680 lbfh = (struct lbfile *) new (sizeof(struct lbfile));
692 lbfh->libspc = ThisLibr->libspc;
693 lbfh->filspc = ThisLibr->filename;
694 lbfh->relfil = (char *) new (strlen(ThisLibr->relfil) + 1);
695 strcpy(lbfh->relfil, ThisLibr->relfil);
696 lbfh->offset = ThisLibr->offset;
698 { /*For an embedded object file in a library*/
699 void loadfile_SdccLib(char * libspc, char * module, long offset);
700 loadfile_SdccLib(lbfh->libspc, lbfh->relfil, lbfh->offset);
703 { /*For a stand alone object file*/
704 /* if cdb information required & adb file present */
707 FILE *xfp = afile(lbfh->filspc, "adb",0);
710 SaveLinkedFilePath(lbfh->filspc);
715 loadfile(lbfh->filspc);
727 char absPath1[PATH_MAX];
728 char absPath2[PATH_MAX];
729 #if defined(__BORLANDC__) || defined(_MSC_VER) || defined(__MINGW32__)
732 _fullpath(absPath1, FirstFound->libspc, PATH_MAX);
733 _fullpath(absPath2, ThisLibr->libspc, PATH_MAX);
734 for(j=0; absPath1[j]!=0; j++) absPath1[j]=tolower(absPath1[j]);
735 for(j=0; absPath2[j]!=0; j++) absPath2[j]=tolower(absPath2[j]);
737 realpath(FirstFound->libspc, absPath1);
738 realpath(ThisLibr->libspc, absPath2);
740 if( !( EQ(absPath1, absPath2) && EQ(FirstFound->relfil, ThisLibr->relfil) ) )
744 fprintf(stderr, "?Aslink-Warning-Definition of public symbol '%s'"
745 " found more than once:\n", name);
746 fprintf(stderr, " Library: '%s', Module: '%s'\n",
747 FirstFound->libspc, FirstFound->relfil);
749 fprintf(stderr, " Library: '%s', Module: '%s'\n",
750 ThisLibr->libspc, ThisLibr->relfil);
755 ThisSym=ThisSym->next; /* Next sym in library */
757 ThisLibr=ThisLibr->next; /* Next library in list */
762 pmlibraryfile buildlibraryindex_SdccLib(char * PathLib, FILE * libfp, char * DirLib, pmlibraryfile This)
764 char ModName[NCPS]="";
765 char FLine[MAXLINE+1];
768 long IndexOffset=0, FileOffset;
769 pmlibrarysymbol ThisSym = NULL;
774 fgets(FLine, MAXLINE, libfp);
780 if(EQ(FLine, "<INDEX>"))
782 /*The next line has the size of the index*/
784 fgets(FLine, MAXLINE, libfp);
786 IndexOffset=atol(FLine);
791 if(EQ(FLine, "<MODULE>"))
793 /*The next line has the name of the module and the offset
794 of the corresponding embedded file in the library*/
796 fgets(FLine, MAXLINE, libfp);
798 sscanf(FLine, "%s %ld", ModName, &FileOffset);
801 /*Create a new libraryfile object for this module*/
804 libr=This=(pmlibraryfile)new( sizeof( mlibraryfile ));
808 This->next=(pmlibraryfile)new( sizeof( mlibraryfile ));
813 This->offset=FileOffset+IndexOffset;
814 This->libspc=PathLib;
816 This->relfil=(char *)new(strlen(ModName)+1);
817 strcpy(This->relfil, ModName);
819 sprintf(buff, "%s%s%crel", DirLib, ModName, FSEPX);
820 This->filename=(char *)new(strlen(buff)+1);
821 strcpy(This->filename, buff);
823 This->symbols=ThisSym=NULL; /*Start a new linked list of symbols*/
825 else if(EQ(FLine, "</INDEX>"))
827 return This; /*Finish, get out of here*/
831 if(EQ(FLine, "</MODULE>"))
834 /*Create the index for the next module*/
840 if(ThisSym==NULL) /*First symbol of the current module*/
842 ThisSym=This->symbols=(pmlibrarysymbol)new(sizeof(mlibrarysymbol));
846 ThisSym->next = (pmlibrarysymbol)new(sizeof(mlibrarysymbol));
847 ThisSym=ThisSym->next;
850 ThisSym->name=(char *)new(strlen(FLine)+1);
851 strcpy(ThisSym->name, FLine);
856 return This; /*State machine should never reach this point, but just in case...*/
861 return This; /*State machine should never reach this point, but just in case...*/
865 /* buildlibraryindex - build an in-memory cache of the symbols contained in
868 int buildlibraryindex(void)
872 char relfil[NINPUT+2], str[PATH_MAX], *path;
873 char buf[NINPUT+2], c;
874 char symname[NINPUT+2];
875 pmlibraryfile This=NULL;
876 pmlibrarysymbol ThisSym;
879 * Search through every library in the linked list "lbnhead".
882 for (lbnh=lbnhead; lbnh; lbnh=lbnh->next)
884 if ((libfp = fopen(lbnh->libspc, "r")) == NULL)
886 fprintf(stderr, "?Aslink-Error-Cannot open library file %s\n",
893 * Read in a line from the library file.
894 * This is the relative file specification
895 * for a .REL file in this library.
898 while (fgets(relfil, NINPUT, libfp) != NULL)
900 relfil[NINPUT+1] = '\0';
906 if (str[strlen(str)-1] != '/')
917 if(strcmp(relfil, "<SDCCLIB>")==0)
919 /*Get the built in index of this library*/
920 This=buildlibraryindex_SdccLib(lbnh->libspc, libfp, str, This);
921 break; /*get the index for next library*/
924 /*From here down, build the index for the original library format*/
926 if (relfil[0] == '\\')
928 strcat(str,relfil+1);
935 if(strchr(relfil, FSEPX) == NULL)
937 sprintf(&str[strlen(str)], "%crel", FSEPX);
940 if ((fp = fopen(str, "r")) != NULL)
942 /* Opened OK - create a new libraryfile object for it */
945 libr=This=(pmlibraryfile)new( sizeof( mlibraryfile ));
949 This->next=(pmlibraryfile)new( sizeof( mlibraryfile ));
954 This->offset=-1; /*We have a stand alone .rel file*/
955 This->libspc = lbnh->libspc;
957 This->relfil=(char *)new(strlen(relfil)+1);
958 strcpy(This->relfil, relfil);
960 This->filename=(char *)new(strlen(str)+1);
961 strcpy(This->filename, str);
963 /*Start a new linked list of symbols for this module:*/
964 This->symbols=ThisSym=NULL;
967 * Read in the object file. Look for lines that
968 * begin with "S" and end with "D". These are
969 * symbol table definitions. If we find one, see
970 * if it is our symbol. Make sure we only read in
971 * our object file and don't go into the next one.
974 while (fgets(buf, NINPUT, fp) != NULL)
976 buf[NINPUT+1] = '\0';
977 buf[strlen(buf) - 1] = '\0';
980 * Skip everything that's not a symbol record.
982 if (buf[0] != 'S') continue;
985 * When a 'T line' is found terminate file scan.
986 * All 'S line's preceed 'T line's in .REL files.
988 if (buf[0] == 'T') break;
990 sscanf(buf, "S %s %c", symname, &c);
992 /* If it's an actual symbol, record it */
997 ThisSym=This->symbols=(pmlibrarysymbol)new(sizeof(mlibrarysymbol));
1001 ThisSym->next=(pmlibrarysymbol)new(sizeof(mlibrarysymbol));
1002 ThisSym=ThisSym->next;
1006 ThisSym->name=(char *)new(strlen(symname)+1);
1007 strcpy(ThisSym->name, symname);
1009 } /* Closes while - read object file */
1011 } /* Closes if object file opened OK */
1014 fprintf(stderr, "?Aslink-Warning-Cannot open library module %s\n", str);
1016 } /* Ends while - processing all in libr */
1018 } /* Ends good open of libr file */
1022 /*Release all memory allocated for the in-memory library index*/
1023 void freelibraryindex (void)
1025 pmlibraryfile ThisLibr, ThisLibr2Free;
1026 pmlibrarysymbol ThisSym, ThisSym2Free;
1032 ThisSym = ThisLibr->symbols;
1036 free(ThisSym->name);
1037 ThisSym2Free=ThisSym;
1038 ThisSym=ThisSym->next;
1041 free(ThisLibr->filename);
1042 free(ThisLibr->relfil);
1043 ThisLibr2Free=ThisLibr;
1044 ThisLibr=ThisLibr->next;
1045 free(ThisLibr2Free);
1051 #else /* INDEXLIB */
1058 struct lbname *lbnh;
1059 struct lbfile *lbfh, *lbf;
1060 char relfil[NINPUT+2];
1062 char symname[NINPUT];
1068 * Search through every library in the linked list "lbnhead".
1071 for (lbnh=lbnhead; lbnh; lbnh=lbnh->next)
1073 if ((libfp = fopen(lbnh->libspc, "r")) == NULL)
1075 fprintf(stderr, "?Aslink-Error-Cannot open library file %s\n",
1082 * Read in a line from the library file.
1083 * This is the relative file specification
1084 * for a .REL file in this library.
1087 while (fgets(relfil, NINPUT, libfp) != NULL)
1089 relfil[NINPUT+1] = '\0';
1093 str = (char *) new (strlen(path)+strlen(relfil)+6);
1096 if (str[strlen(str)-1] != '/')
1104 str = (char *) new (strlen(relfil) + 5);
1107 if(strcmp(relfil, "<SDCCLIB>")==0)
1109 result=SdccLib(lbnh->libspc, libfp, str, name);
1110 if(result) return(1); /*Found the symbol*/
1112 /*The symbol is not in the current library,
1113 check the next library in the list*/
1117 /*From here down is the support for libraries in the original format*/
1118 if (relfil[0] == '\\')
1120 strcat(str,relfil+1);
1127 if(strchr(relfil, FSEPX) == NULL)
1129 sprintf(&str[strlen(str)], "%crel", FSEPX);
1132 if ((fp = fopen(str, "r")) != NULL)
1136 * Read in the object file. Look for lines that
1137 * begin with "S" and end with "D". These are
1138 * symbol table definitions. If we find one, see
1139 * if it is our symbol. Make sure we only read in
1140 * our object file and don't go into the next one.
1143 while (fgets(buf, NINPUT, fp) != NULL)
1145 buf[NINPUT+1] = '\0';
1148 * Skip everything that's not a symbol record.
1150 if (buf[0] != 'S') continue;
1153 * When a 'T line' is found terminate file scan.
1154 * All 'S line's preceed 'T line's in .REL files.
1156 if (buf[0] == 'T') break;
1158 sscanf(buf, "S %s %c", symname, &c);
1161 * If we find a symbol definition for the
1162 * symbol we're looking for, load in the
1163 * file and add it to lbfhead so it gets
1164 * loaded on pass number 2.
1166 if (strncmp(symname, name, NCPS) == 0 && c == 'D')
1168 lbfh = (struct lbfile *) new (sizeof(struct lbfile));
1169 if (lbfhead == NULL)
1181 lbfh->libspc = lbnh->libspc;
1183 lbfh->relfil = (char *) new (strlen(relfil) + 1);
1184 lbfh->offset = -1; /*Stand alone rel file*/
1185 strcpy(lbfh->relfil,relfil);
1189 /* if cdb information required & adb file present */
1192 FILE *xfp = afile(str,"adb",0); //JCF: Nov 30, 2002
1195 SaveLinkedFilePath(str);
1215 void loadfile_SdccLib(char * libspc, char * module, long offset)
1219 if ((fp = fopen(libspc,"r")) != NULL)
1221 fseek(fp, offset, SEEK_SET);
1222 LoadRel(libspc, fp, module);
1227 /*)Function VOID library()
1229 * The function library() links all the library object files
1230 * contained in the lbfile structures.
1233 * lbfile *lbfh pointer to lbfile structure
1236 * lbfile *lbfhead pointer to first lbfile structure
1239 * VOID loadfile lklibr.c
1242 * Links all files contained in the lbfile structures.
1248 struct lbfile *lbfh;
1250 for (lbfh=lbfhead; lbfh; lbfh=lbfh->next)
1254 /*Stand alone rel file (original lib format)*/
1255 loadfile(lbfh->filspc);
1259 /*rel file embedded in lib (new lib format)*/
1260 loadfile_SdccLib(lbfh->libspc, lbfh->relfil, lbfh->offset);
1268 /*)Function VOID loadfile(filspc)
1270 * char *filspc library object file specification
1272 * The function loadfile() links the library object module.
1275 * FILE *fp file handle
1276 * int i input line length
1277 * char str[] file input line
1280 * char *ip pointer to linker input string
1283 * int fclose() c_library
1284 * int fgets() c_library
1285 * FILE * fopen() c_library
1286 * VOID link_main() lkmain.c
1287 * int strlen() c_library
1290 * If file exists it is linked.
1300 if ((fp = fopen(filspc,"r")) != NULL) {
1301 while (fgets(str, NINPUT, fp) != NULL) {
1302 str[NINPUT+1] = '\0';