4 * Copyright (C) 1989-2009 Alan R. Baldwin
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
29 * The module lklex.c contains the general lexical analysis
30 * functions used to scan the text lines from the .rel files.
32 * lklex.c contains the following functions:
46 * lklex.c contains no local variables.
49 /*)Function VOID getid(id,c)
51 * char * id a pointer to a string of
52 * maximum length NCPS-1
54 * >=0 this is first character to
55 * copy to the string buffer
58 * The function getid() scans the current input text line
59 * from the current position copying the next LETTER | DIGIT string
60 * into the external string buffer (id). The string ends when a non
61 * LETTER or DIGIT character is found. The maximum number of characters
62 * copied is NCPS-1. If the input string is larger than NCPS-1
63 * characters then the string is truncated. The string is always
64 * NULL terminated. If the mode argument (c) is >=0 then (c) is
65 * the first character copied to the string buffer, if (c) is <0
66 * then intervening white space (SPACES and TABS) are skipped.
69 * char * p pointer to external string buffer
70 * int c current character value
73 * char ctype[] a character array which defines the
74 * type of character being processed.
75 * This index is the character
81 * VOID unget() lklex.c
84 * use of getnb(), get(), and unget() updates the
85 * global pointer ip the position in the current
90 getid(char *id
, int c
)
101 } while (ctype
[c
=get()] & (LETTER
|DIGIT
));
106 /*)Function VOID getSid (char *id)
108 * char * id a pointer to a string of
109 * maximum length NCPS-1
111 * getSid is derived from getid. It is called from newsym()
112 * in lksym.c, when an S-record has to be scanned. getSid accepts
113 * much more characters than getid, which is necessary for SDCC.
115 * The function getSid() scans the current input text line
116 * from the current position copying the next string
117 * into the external string buffer (id). The string ends when a space
118 * character (space, tab, \0) is found. The maximum number of
119 * characters copied is NCPS. If the input string is larger than
120 * NCPS characters then the string is truncated, if the input string
121 * is shorter than NCPS characters then the string is NULL filled.
122 * Intervening white space (SPACES and TABS) are skipped.
125 * char * p pointer to external string buffer
126 * int c current character value
133 * int getnb() lklex.c
134 * VOID unget() lklex.c
137 * use of getnb(), get(), and unget() updates the
138 * global pointer ip the position in the current
154 } while (c
!= '\0' && c
!= ' ' && c
!= '\t');
159 /*)Function VOID getfid(str,c)
161 * char * str a pointer to a string of
162 * maximum length FILSPC-1
163 * int c this is first character to
164 * copy to the string buffer
168 * The function getfid() copies a string of characters from
169 * the current text line into the external string buffer (str).
170 * The maximum number of characters copied is FILSPC-1. The
171 * string is terminated by a 'space', 'tab' or end of string.
175 * The function getfid() scans the current input text line from
176 * the current position copying the next string into the external
177 * string buffer (str). The string ends when end of line is found.
178 * Trailing spaces are removed. The maximum number of characters
179 * copied is FILSPC-1. If the input string is larger than FILSPC-1
180 * characters then the string is truncated. The string is NULL
184 * char * p pointer to external string buffer
185 * int c current character value
188 * char ctype[] a character array which defines the
189 * type of character being processed.
190 * This index is the character
197 * use of get() updates the global pointer ip
198 * the position in the current input text line.
202 getfid(char *str
, int c
)
209 if (p
< &str
[FILSPC
-1])
212 } while ((c
!= 0) && (c
!= ' ') && (c
!= '\t'));
217 if (p
< &str
[FILSPC
-1])
225 /* trim trailing spaces */
227 while (p
>= str
&& ctype
[*p
& 0x00FF] == SPACE
)
229 /* terminate the string */
234 /*)Function int getnb()
236 * The function getnb() scans the current input text
237 * line returning the first character not a SPACE or TAB.
240 * int c current character from input
249 * use of get() updates the global pointer ip, the position
250 * in the current input text line
258 while ((c
=get())==' ' || c
=='\t')
263 /*)Function VOID skip(c)
265 * The function skip() scans the input text skipping all
266 * letters and digits.
269 * int c last character read
273 * char ctype[] array of character types, one per
278 * int getnb() lklex.c
279 * VOID unget() lklex.c
282 * Input letters and digits are skipped.
291 while (ctype
[c
=get()] & (LETTER
|DIGIT
)) { ; }
295 /*)Function int get()
297 * The function get() returns the next character in the
298 * input text line, at the end of the line a
299 * NULL character is returned.
302 * int c current character from
306 * char * ip pointer into the current
313 * updates ip to the next character position in the
314 * input text line. If ip is at the end of the
315 * line, ip is not updated.
328 /*)Function VOID unget(c)
330 * int c value of last character
331 * read from input text line
333 * If (c) is not a NULL character then the global pointer ip
334 * is updated to point to the preceeding character in the
337 * NOTE: This function does not push the character (c)
338 * back into the input text line, only
339 * the pointer ip is changed.
342 * int c last character read
343 * from input text line
346 * char * ip position into the current
353 * ip decremented by 1 character position
364 /*)Function int getmap(d)
366 * int d value to compare with the
367 * input text line character
369 * The function getmap() converts the 'C' style characters \b, \f,
370 * \n, \r, and \t to their equivalent ascii values and also
371 * converts 'C' style octal constants '\123' to their equivalent
372 * numeric values. If the first character is equivalent to (d) then
373 * a (-1) is returned, if the end of the line is detected then
374 * a 'q' error terminates the parse for this line, or if the first
375 * character is not a \ then the character value is returned.
378 * int c value of character
379 * from input text line
380 * int n looping counter
381 * int v current value of numeric conversion
388 * VOID unget() lklex.c
391 * use of get() updates the global pointer ip the position
392 * in the current input text line
401 if ((c
= get()) == '\0')
439 while (++n
<=3 && c
>='0' && c
<='7') {
440 v
= (v
<<3) + c
- '0';
451 /*)Function int nxtline()
453 * The function nxtline() reads a line of input text from a
454 * .rel source text file, a .lnk command file or from stdin.
455 * Lines of text are processed from a single .lnk file or
456 * multiple .rel files until all files have been read.
457 * The input text line is copied into the global string ib[]
458 * and converted to a NULL terminated string. The function
459 * nxtline() returns a (1) after succesfully reading a line
460 * or a (0) if all files have been read.
461 * This function also opens each input .lst file and output
462 * .rst file as each .rel file is processed.
465 * int ftype file type
466 * char * fid file name
469 * lfile *cfp The pointer *cfp points to the
470 * current lfile structure
471 * lfile *filep The pointer *filep points to the
472 * beginning of a linked list of
474 * int gline get a line from the LST file
475 * to translate for the RST file
476 * char ib[NINPUT] REL file text line
477 * int pass linker pass number
478 * int pflag print linker command file flag
479 * FILE *rfp The file handle to the current
481 * FILE *sfp The file handle sfp points to the
482 * currently open file
483 * FILE * stdin c_library
484 * FILE * stdout c_library
485 * FILE *tfp The file handle to the current
486 * LST file being scanned
487 * int uflag update listing flag
488 * int obj_flag linked file/library object output flag
491 * VOID chopcrlf() lklex.c
492 * FILE * afile() lkmain.c
493 * int fclose() c_library
494 * char * fgets() c_library
495 * int fprintf() c_library
496 * VOID lkulist() lklist.c
497 * VOID lkexit() lkmain.c
500 * The input stream is scanned. The .rel files will be
501 * opened and closed sequentially scanning each in turn.
510 loop
: if (pflag
&& cfp
&& cfp
->f_type
== F_STD
)
511 fprintf(stdout
, "ASlink >> ");
513 if (sfp
== NULL
|| fgets(ib
, sizeof(ib
), sfp
) == NULL
) {
530 if (ftype
== F_STD
) {
533 if (ftype
== F_LNK
) {
534 sfp
= afile(fid
, strrchr(fid
, FSEPX
) ? "" : "lnk", 0);
536 if (ftype
== F_REL
) {
537 obj_flag
= cfp
->f_obj
;
538 sfp
= afile(fid
, "", 0);
539 if (sfp
&& (obj_flag
== 0)) {
540 if (uflag
&& (pass
!= 0)) {
542 SaveLinkedFilePath(fid
); //Save the linked path for aomf51
543 if ((tfp
= afile(fid
, "lst", 0)) != NULL
) {
544 if ((rfp
= afile(fid
, "rst", 1)) == NULL
) {
553 if (sfp
&& (pass
== 0)) {
560 fprintf(stderr
, "Invalid file type\n");
576 /*)Function int more()
578 * The function more() scans the input text line
579 * skipping white space (SPACES and TABS) and returns a (0)
580 * if the end of the line or a comment delimeter (;) is found,
581 * or a (1) if their are additional characters in the line.
584 * int c next character from
585 * the input text line
591 * int getnb() lklex.c
592 * VOID unget() lklex.c
595 * use of getnb() and unget() updates the global pointer ip
596 * the position in the current input text line
599 static int isHex(int c
)
601 if ('0' <= c
&& c
<= '9')
603 else if ('A' <= c
&& c
<= 'F')
605 else if ('a' <= c
&& c
<= 'f')
617 if (c
!= '\0' && c
!= ';' && !isHex (c
))
620 return( (c
== '\0' || c
== ';') ? 0 : 1 );
623 /*)Function char endline()
625 * The function endline() scans the input text line
626 * skipping white space (SPACES and TABS) and returns the next
627 * character or a (0) if the end of the line is found or a
628 * comment delimiter (;) is found.
631 * int c next character from
632 * the input text line
638 * int getnb() lklex.c
641 * Use of getnb() updates the global pointer ip the
642 * position in the current input text line.
651 return( (c
== '\0' || c
== ';') ? 0 : c
);
654 /*)Function VOID chopcrlf(str)
656 * char *str string to chop
658 * The function chop_crlf() removes trailing LF or CR/LF from
662 * int i string length
681 if (i
>= 1 && str
[i
-1] == '\n') str
[i
-1] = 0;
682 if (i
>= 2 && str
[i
-2] == '\r') str
[i
-2] = 0;