]> git.gag.com Git - fw/sdcc/blob - as/mcs51/lklex.c
Cleaned up MSVC specific stuff
[fw/sdcc] / as / mcs51 / lklex.c
1 /* lklex.c */
2
3 /*
4  * (C) Copyright 1989-1995
5  * All Rights Reserved
6  *
7  * Alan R. Baldwin
8  * 721 Berkeley St.
9  * Kent, Ohio  44240
10  */
11
12 #include <stdio.h>
13 #include <string.h>
14 #include "aslink.h"
15
16 /*)Module       lklex.c
17  *
18  *      The module lklex.c contains the general lexical analysis
19  *      functions used to scan the text lines from the .rel files.
20  *
21  *      lklex.c contains the fllowing functions:
22  *              char    endline()
23  *              char    get()
24  *              VOID    getfid()
25  *              VOID    getid()
26  *              int     getline()
27  *              int     getmap()
28  *              char    getnb()
29  *              int     more()
30  *              VOID    skip()
31  *              VOID    unget()
32  *
33  *      lklex.c contains no local variables.
34  */
35
36 /*)Function     VOID    getid(id,c)
37  *
38  *              char *  id              a pointer to a string of
39  *                                      maximum length NCPS
40  *              int     c               mode flag
41  *                                      >=0     this is first character to
42  *                                              copy to the string buffer
43  *                                      <0      skip white space
44  *
45  *      The function getid() scans the current input text line
46  *      from the current position copying the next LETTER | DIGIT string
47  *      into the external string buffer (id).  The string ends when a non
48  *      LETTER or DIGIT character is found. The maximum number of
49  *      characters copied is NCPS.  If the input string is larger than
50  *      NCPS characters then the string is truncated, if the input string
51  *      is shorter than NCPS characters then the string is NULL filled.
52  *      If the mode argument (c) is >=0 then (c) is the first character
53  *      copied to the string buffer, if (c) is <0 then intervening white
54  *      space (SPACES and TABS) are skipped.
55  *
56  *      local variables:
57  *              char *  p               pointer to external string buffer
58  *              int     c               current character value
59  *
60  *      global variables:
61  *              char    ctype[]         a character array which defines the
62  *                                      type of character being processed.
63  *                                      This index is the character
64  *                                      being processed.
65  *
66  *      called functions:
67  *              char    get()           lklex.c
68  *              char    getnb()         lklex.c
69  *              VOID    unget()         lklex.c
70  *
71  *      side effects:
72  *              use of getnb(), get(), and unget() updates the
73  *              global pointer ip the position in the current
74  *              input text line.
75  */
76
77 VOID
78 getid(id, c)
79 register int c;
80 char *id;
81 {
82         register char *p;
83
84         if (c < 0) {
85                 c = getnb();
86         }
87         p = id;
88         do {
89                 if (p < &id[NCPS])
90                         *p++ = c;
91         } while (ctype[c=get()] & (LETTER|DIGIT));
92         unget(c);
93         while (p < &id[NCPS])
94                 *p++ = 0;
95 }
96
97 /*)Function     VOID    getfid(fid,c)
98  *
99  *              char *  str             a pointer to a string of
100  *                                      maximum length FILSPC
101  *              int     c               this is first character to
102  *                                      copy to the string buffer
103  *
104  *      The function getfid() scans the current input text line
105  *      from the current position copying the next string
106  *      into the external string buffer (str).  The string ends when a
107  *      non SPACE type character is found. The maximum number of
108  *      characters copied is FILSPC. If the input string is larger than
109  *      FILSPC characters then the string is truncated, if the input string
110  *      is shorter than FILSPC characters then the string is NULL filled.
111  *
112  *      local variables:
113  *              char *  p               pointer to external string buffer
114  *              int     c               current character value
115  *
116  *      global variables:
117  *              char    ctype[]         a character array which defines the
118  *                                      type of character being processed.
119  *                                      This index is the character
120  *                                      being processed.
121  *
122  *      called functions:
123  *              char    get()           lklex.c
124  *
125  *      side effects:
126  *              use of get() updates the global pointer ip
127  *              the position in the current input text line.
128  */
129
130 VOID
131 getfid(str, c)
132 register int c;
133 char *str;
134 {
135         register char *p;
136
137         p = str;
138         do {
139                 if (p < &str[FILSPC-1])
140                         *p++ = c;
141                 c = get();
142         } while (c && ((ctype[c] != SPACE)||(c == ':')||(c == '\\')));
143         while (p < &str[FILSPC])
144                 *p++ = 0;
145 }
146
147 /*)Function     char    getnb()
148  *
149  *      The function getnb() scans the current input text
150  *      line returning the first character not a SPACE or TAB.
151  *
152  *      local variables:
153  *              int     c               current character from input
154  *
155  *      global variables:
156  *              none
157  *
158  *      called functions:
159  *              char    get()           lklex.c
160  *
161  *      side effects:
162  *              use of get() updates the global pointer ip, the position
163  *              in the current input text line
164  */
165
166 char
167 getnb()
168 {
169         register int c;
170
171         while ((c=get())==' ' || c=='\t')
172                 ;
173         return (c);
174 }
175
176 /*)Function     VOID    skip()
177  *
178  *      The function skip() scans the input text skipping all
179  *      letters and digits.
180  *
181  *      local variables:
182  *              none
183  *
184  *      global variables:
185  *              char    ctype[]         array of character types, one per
186  *                                      ASCII character
187  *              
188  *      functions called:
189  *              char    get()           lklex.c
190  *              char    getnb()         lklex.c
191  *              VOID    unget()         lklex.c
192  *
193  *      side effects:
194  *              Input letters and digits are skipped.
195  */
196
197 VOID
198 skip(c)
199 register int c;
200 {
201         if (c < 0)
202                 c = getnb();
203         while (ctype[c=get()] & (LETTER|DIGIT)) { ; }
204         unget(c);
205 }
206
207 /*)Function     char    get()
208  *
209  *      The function get() returns the next character in the
210  *      input text line, at the end of the line a
211  *      NULL character is returned.
212  *
213  *      local variables:
214  *              int     c               current character from
215  *                                      input text line
216  *
217  *      global variables:
218  *              char *  ip              pointer into the current
219  *                                      input text line
220  *
221  *      called functions:
222  *              none
223  *
224  *      side effects:
225  *              updates ip to the next character position in the
226  *              input text line.  If ip is at the end of the
227  *              line, ip is not updated.
228  */
229
230 char
231 get()
232 {
233         register int c;
234
235         if ((c = *ip) != 0)
236                 ++ip;
237         return (c);
238 }
239
240 /*)Function     VOID    unget(c)
241  *
242  *              int     c               value of last character
243  *                                      read from input text line
244  *
245  *      If (c) is not a NULL character then the global pointer ip
246  *      is updated to point to the preceeding character in the
247  *      input text line.
248  *
249  *      NOTE:   This function does not push the character (c)
250  *              back into the input text line, only
251  *              the pointer ip is changed.
252  *
253  *      local variables:
254  *              int     c               last character read
255  *                                      from input text line
256  *
257  *      global variables:
258  *              char *  ip              position into the current
259  *                                      input text line
260  *
261  *      called functions:
262  *              none
263  *
264  *      side effects:
265  *              ip decremented by 1 character position
266  */
267
268 VOID
269 unget(c)
270 {
271         if (c != 0)
272                 --ip;
273 }
274
275 /*)Function     int     getmap(d)
276  *
277  *              int     d               value to compare with the
278  *                                      input text line character
279  *
280  *      The function getmap() converts the 'C' style characters \b, \f,
281  *      \n, \r, and \t to their equivalent ascii values and also
282  *      converts 'C' style octal constants '\123' to their equivalent
283  *      numeric values.  If the first character is equivalent to (d) then
284  *      a (-1) is returned, if the end of the line is detected then
285  *      a 'q' error terminates the parse for this line, or if the first
286  *      character is not a \ then the character value is returned.
287  *
288  *      local variables:
289  *              int     c               value of character
290  *                                      from input text line
291  *              int     n               looping counter
292  *              int     v               current value of numeric conversion
293  *
294  *      global variables:
295  *              none
296  *
297  *      called functions:
298  *              char    get()           lklex.c
299  *              VOID    unget()         lklex.c
300  *
301  *      side effects:
302  *              use of get() updates the global pointer ip the position
303  *              in the current input text line
304  */
305
306 int
307 getmap(d)
308 {
309         register int c, n, v;
310
311         if ((c = get()) == '\0')
312                 return (-1);
313         if (c == d)
314                 return (-1);
315         if (c == '\\') {
316                 c = get();
317                 switch (c) {
318
319                 case 'b':
320                         c = '\b';
321                         break;
322
323                 case 'f':
324                         c = '\f';
325                         break;
326
327                 case 'n':
328                         c = '\n';
329                         break;
330
331                 case 'r':
332                         c = '\r';
333                         break;
334
335                 case 't':
336                         c = '\t';
337                         break;
338
339                 case '0':
340                 case '1':
341                 case '2':
342                 case '3':
343                 case '4':
344                 case '5':
345                 case '6':
346                 case '7':
347                         n = 0;
348                         v = 0;
349                         while (++n<=3 && c>='0' && c<='7') {
350                                 v = (v<<3) + c - '0';
351                                 c = get();
352                         }
353                         unget(c);
354                         c = v;
355                         break;
356                 }
357         }
358         return (c);
359 }
360
361 /*)Function     int     getline()
362  *
363  *      The function getline() reads a line of input text from a
364  *      .rel source text file, a .lnk command file or from stdin.
365  *      Lines of text are processed from a single .lnk file or
366  *      multiple .rel files until all files have been read.
367  *      The input text line is copied into the global string ib[]
368  *      and converted to a NULL terminated string.  The function
369  *      getline() returns a (1) after succesfully reading a line
370  *      or a (0) if all files have been read.
371  *      This function also opens each input .lst file and output
372  *      .rst file as each .rel file is processed.
373  *
374  *      local variables:
375  *              int     i               string length
376  *              int     ftype           file type
377  *              char *  fid             file name
378  *
379  *      global variables:
380  *              lfile   *cfp            The pointer *cfp points to the
381  *                                      current lfile structure
382  *              lfile   *filep          The pointer *filep points to the
383  *                                      beginning of a linked list of
384  *                                      lfile structures.
385  *              int     gline           get a line from the LST file
386  *                                      to translate for the RST file
387  *              char    ib[NINPUT]      REL file text line
388  *              int     pass            linker pass number
389  *              int     pflag           print linker command file flag
390  *              FILE    *rfp            The file handle to the current
391  *                                      output RST file
392  *              FILE    *sfp            The file handle sfp points to the
393  *                                      currently open file
394  *              FILE *  stdin           c_library
395  *              FILE *  stdout          c_library
396  *              FILE    *tfp            The file handle to the current
397  *                                      LST file being scanned
398  *              int     uflag           update listing flag
399  *
400  *      called functions:
401  *              FILE *  afile()         lkmain.c
402  *              int     fclose()        c_library
403  *              char *  fgets()         c_library
404  *              int     fprintf()       c_library
405  *              VOID    lkulist()       lklist.c
406  *              VOID    lkexit()        lkmain.c
407  *              int     strlen()        c_library
408  *
409  *      side effects:
410  *              The input stream is scanned.  The .rel files will be
411  *              opened and closed sequentially scanning each in turn.
412  */
413
414 int
415 getline()
416 {
417         register int ftype;
418         register char *fid;
419
420 loop:   if (pflag && cfp && cfp->f_type == F_STD)
421                 fprintf(stdout, "ASlink >> ");
422
423         if (sfp == NULL || fgets(ib, sizeof ib, sfp) == NULL) {
424                 if (sfp) {
425                         fclose(sfp);
426                         sfp = NULL;
427                         lkulist(0);
428                 }
429                 if (cfp == NULL) {
430                         cfp = filep;
431                 } else {
432                         cfp = cfp->f_flp;
433                 }
434                 if (cfp) {
435                         ftype = cfp->f_type;
436                         fid = cfp->f_idp;
437                         if (ftype == F_STD) {
438                                 sfp = stdin;
439                         } else
440                         if (ftype == F_LNK) {
441                                 sfp = afile(fid, "lnk", 0);
442                         } else
443                         if (ftype == F_REL) {
444                                 sfp = afile(fid, "rel", 0);
445                                 /* if a .cdb file exists then copy it over */
446                                 if (dflag && sfp && dfp && pass == 0) {
447                                     FILE *xfp = afile(fid,"cdb",0);
448                                     if (xfp) {
449                                         copyfile(dfp,xfp);
450                                         fclose(xfp);
451                                     }
452                                 }
453                                 if (uflag && pass != 0) {
454                                  if ((tfp = afile(fid, "lst", 0)) != NULL) {
455                                   if ((rfp = afile(fid, "rst", 1)) == NULL) {
456                                         fclose(tfp);
457                                         tfp = NULL;
458                                   }
459                                  }
460                                 }
461                                 gline = 1;
462                         } else {
463                                 fprintf(stderr, "Invalid file type\n");
464                                 lkexit(1);
465                         }
466                         if (sfp == NULL) {
467                                 lkexit(1);
468                         }
469                         goto loop;
470                 } else {
471                         filep = NULL;
472                         return(0);
473                 }
474         }
475         chop_crlf(ib);
476         return (1);
477 }
478
479 /*)Function     int     more()
480  *
481  *      The function more() scans the input text line
482  *      skipping white space (SPACES and TABS) and returns a (0)
483  *      if the end of the line or a comment delimeter (;) is found,
484  *      or a (1) if their are additional characters in the line.
485  *
486  *      local variables:
487  *              int     c               next character from
488  *                                      the input text line
489  *
490  *      global variables:
491  *              none
492  *
493  *      called functions:
494  *              char    getnb()         lklex.c
495  *              VOID    unget()         lklex.c
496  *
497  *      side effects:
498  *              use of getnb() and unget() updates the global pointer ip
499  *              the position in the current input text line
500  */
501
502 int
503 more()
504 {
505         register int c;
506
507         c = getnb();
508         unget(c);
509         return( (c == '\0' || c == ';') ? 0 : 1 );
510 }
511
512 /*)Function     char    endline()
513  *
514  *      The function endline() scans the input text line
515  *      skipping white space (SPACES and TABS) and returns the next
516  *      character or a (0) if the end of the line is found or a
517  *      comment delimiter (;) is found.
518  *
519  *      local variables:
520  *              int     c               next character from
521  *                                      the input text line
522  *
523  *      global variables:
524  *              none
525  *
526  *      called functions:
527  *              char    getnb()         lklex.c
528  *
529  *      side effects:
530  *              Use of getnb() updates the global pointer ip the
531  *              position in the current input text line.
532  */
533
534 char
535 endline()
536 {
537         register int c;
538
539         c = getnb();
540         return( (c == '\0' || c == ';') ? 0 : c );
541 }
542
543 /*)Function     VOID    chop_crlf(str)
544  *
545  *              char    *str            string to chop
546  *
547  *      The function chop_crlf() removes trailing LF or CR/LF from
548  *      str, if present.
549  *
550  *      local variables:
551  *              int     i               string length
552  *
553  *      global variables:
554  *              none
555  *
556  *      functions called:
557  *              none
558  *
559  *      side effects:
560  *              none
561  */
562
563 VOID
564 chop_crlf(str)
565 char *str;
566 {
567         register int i;
568
569         i = strlen(str);
570         if (i >= 1 && str[i-1] == '\n') str[i-1] = 0;
571         if (i >= 2 && str[i-2] == '\r') str[i-2] = 0;
572 }