--- /dev/null
+/* lklex.c */
+
+/*
+ * (C) Copyright 1989-1995
+ * All Rights Reserved
+ *
+ * Alan R. Baldwin
+ * 721 Berkeley St.
+ * Kent, Ohio 44240
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "aslink.h"
+
+/*)Module lklex.c
+ *
+ * The module lklex.c contains the general lexical analysis
+ * functions used to scan the text lines from the .rel files.
+ *
+ * lklex.c contains the fllowing functions:
+ * char endline()
+ * char get()
+ * VOID getfid()
+ * VOID getid()
+ * VOID getSid()
+ * int as_getline()
+ * int getmap()
+ * char getnb()
+ * int more()
+ * VOID skip()
+ * VOID unget()
+ *
+ * lklex.c contains no local variables.
+ */
+
+/*)Function VOID getid(id,c)
+ *
+ * char * id a pointer to a string of
+ * maximum length NCPS
+ * int c mode flag
+ * >=0 this is first character to
+ * copy to the string buffer
+ * <0 skip white space
+ *
+ * The function getid() scans the current input text line
+ * from the current position copying the next LETTER | DIGIT string
+ * into the external string buffer (id). The string ends when a non
+ * LETTER or DIGIT character is found. The maximum number of
+ * characters copied is NCPS. If the input string is larger than
+ * NCPS characters then the string is truncated, if the input string
+ * is shorter than NCPS characters then the string is NULL filled.
+ * If the mode argument (c) is >=0 then (c) is the first character
+ * copied to the string buffer, if (c) is <0 then intervening white
+ * space (SPACES and TABS) are skipped.
+ *
+ * local variables:
+ * char * p pointer to external string buffer
+ * int c current character value
+ *
+ * global variables:
+ * char ctype[] a character array which defines the
+ * type of character being processed.
+ * This index is the character
+ * being processed.
+ *
+ * called functions:
+ * char get() lklex.c
+ * char getnb() lklex.c
+ * VOID unget() lklex.c
+ *
+ * side effects:
+ * use of getnb(), get(), and unget() updates the
+ * global pointer ip the position in the current
+ * input text line.
+ */
+
+VOID
+getid(id, c)
+register int c;
+char *id;
+{
+ register char *p;
+
+ if (c < 0) {
+ c = getnb();
+ }
+ p = id;
+ do {
+ if (p < &id[NCPS])
+ *p++ = c;
+ } while (ctype[c=get()] & (LETTER|DIGIT));
+ unget(c);
+ while (p < &id[NCPS])
+ *p++ = 0;
+}
+
+/*)Function VOID getSid (char *id)
+ *
+ * char * id a pointer to a string of
+ * maximum length NCPS
+ *
+ * getSid is derived from getid. It is called from newsym()
+ * in lksym.c, when an S-record has to be scanned. getSid accepts
+ * much more characters than getid, which is necessary for SDCC.
+ *
+ * The function getSid() scans the current input text line
+ * from the current position copying the next string
+ * into the external string buffer (id). The string ends when a space
+ * character (space, tab, \0) is found. The maximum number of
+ * characters copied is NCPS. If the input string is larger than
+ * NCPS characters then the string is truncated, if the input string
+ * is shorter than NCPS characters then the string is NULL filled.
+ * Intervening white space (SPACES and TABS) are skipped.
+ *
+ * local variables:
+ * char * p pointer to external string buffer
+ * int c current character value
+ *
+ * global variables:
+ * char ctype[] a character array which defines the
+ * type of character being processed.
+ * This index is the character
+ * being processed.
+ *
+ * called functions:
+ * char get() lklex.c
+ * char getnb() lklex.c
+ * VOID unget() lklex.c
+ *
+ * side effects:
+ * use of getnb(), get(), and unget() updates the
+ * global pointer ip the position in the current
+ * input text line.
+ */
+
+VOID
+getSid (id)
+char *id;
+{
+ register int c;
+ register char *p;
+
+ c = getnb();
+ p = id;
+ do {
+ if (p < &id[NCPS])
+ *p++ = c;
+ c = get();
+ } while (c != '\0' && c != ' ' && c != '\t');
+ unget(c);
+ while (p < &id[NCPS])
+ *p++ = 0;
+}
+
+/*)Function VOID getfid(fid,c)
+ *
+ * char * str a pointer to a string of
+ * maximum length PATH_MAX
+ * int c this is first character to
+ * copy to the string buffer
+ *
+ * The function getfid() scans the current input text line from
+ * the current position copying the next string into the external
+ * string buffer (str). The string ends when end of line is found.
+ * Trailing spacers are removed. The maximum number of characters
+ * copied is PATH_MAX. If the input string is larger than PATH_MAX
+ * characters then the string is truncated. The string is NULL
+ * terminated.
+ *
+ * local variables:
+ * char * p pointer to external string buffer
+ * int c current character value
+ *
+ * global variables:
+ * char ctype[] a character array which defines the
+ * type of character being processed.
+ * This index is the character
+ * being processed.
+ *
+ * called functions:
+ * char get() lklex.c
+ *
+ * side effects:
+ * use of get() updates the global pointer ip
+ * the position in the current input text line.
+ */
+
+VOID
+getfid(str, c)
+register int c;
+char *str;
+{
+ register char *p;
+
+ p = str;
+ do
+ {
+ if (p < &str[PATH_MAX-1])
+ *p++ = c;
+ c = get();
+ if (c == ';')
+ while (c)
+ c = get();
+ } while (c);
+ /* trim trailing spaces */
+ --p;
+ while (p >= str && ctype[(int)*p] == SPACE)
+ --p;
+ /* terminate the string */
+ *(++p) = '\0';
+}
+
+/*)Function char getnb()
+ *
+ * The function getnb() scans the current input text
+ * line returning the first character not a SPACE or TAB.
+ *
+ * local variables:
+ * int c current character from input
+ *
+ * global variables:
+ * none
+ *
+ * called functions:
+ * char get() lklex.c
+ *
+ * side effects:
+ * use of get() updates the global pointer ip, the position
+ * in the current input text line
+ */
+
+char
+getnb()
+{
+ register int c;
+
+ while ((c=get())==' ' || c=='\t')
+ ;
+ return (c);
+}
+
+/*)Function VOID skip()
+ *
+ * The function skip() scans the input text skipping all
+ * letters and digits.
+ *
+ * local variables:
+ * none
+ *
+ * global variables:
+ * char ctype[] array of character types, one per
+ * ASCII character
+ *
+ * functions called:
+ * char get() lklex.c
+ * char getnb() lklex.c
+ * VOID unget() lklex.c
+ *
+ * side effects:
+ * Input letters and digits are skipped.
+ */
+
+VOID
+skip(c)
+register int c;
+{
+ if (c < 0)
+ c = getnb();
+ while (ctype[c=get()] & (LETTER|DIGIT)) { ; }
+ unget(c);
+}
+
+/*)Function char get()
+ *
+ * The function get() returns the next character in the
+ * input text line, at the end of the line a
+ * NULL character is returned.
+ *
+ * local variables:
+ * int c current character from
+ * input text line
+ *
+ * global variables:
+ * char * ip pointer into the current
+ * input text line
+ *
+ * called functions:
+ * none
+ *
+ * side effects:
+ * updates ip to the next character position in the
+ * input text line. If ip is at the end of the
+ * line, ip is not updated.
+ */
+
+char
+get()
+{
+ register int c;
+
+ if ((c = *ip) != 0)
+ ++ip;
+ return (c);
+}
+
+/*)Function VOID unget(c)
+ *
+ * int c value of last character
+ * read from input text line
+ *
+ * If (c) is not a NULL character then the global pointer ip
+ * is updated to point to the preceeding character in the
+ * input text line.
+ *
+ * NOTE: This function does not push the character (c)
+ * back into the input text line, only
+ * the pointer ip is changed.
+ *
+ * local variables:
+ * int c last character read
+ * from input text line
+ *
+ * global variables:
+ * char * ip position into the current
+ * input text line
+ *
+ * called functions:
+ * none
+ *
+ * side effects:
+ * ip decremented by 1 character position
+ */
+
+VOID
+unget(c)
+{
+ if (c != 0)
+ --ip;
+}
+
+/*)Function int getmap(d)
+ *
+ * int d value to compare with the
+ * input text line character
+ *
+ * The function getmap() converts the 'C' style characters \b, \f,
+ * \n, \r, and \t to their equivalent ascii values and also
+ * converts 'C' style octal constants '\123' to their equivalent
+ * numeric values. If the first character is equivalent to (d) then
+ * a (-1) is returned, if the end of the line is detected then
+ * a 'q' error terminates the parse for this line, or if the first
+ * character is not a \ then the character value is returned.
+ *
+ * local variables:
+ * int c value of character
+ * from input text line
+ * int n looping counter
+ * int v current value of numeric conversion
+ *
+ * global variables:
+ * none
+ *
+ * called functions:
+ * char get() lklex.c
+ * VOID unget() lklex.c
+ *
+ * side effects:
+ * use of get() updates the global pointer ip the position
+ * in the current input text line
+ */
+
+int
+getmap(d)
+{
+ register int c, n, v;
+
+ if ((c = get()) == '\0')
+ return (-1);
+ if (c == d)
+ return (-1);
+ if (c == '\\') {
+ c = get();
+ switch (c) {
+
+ case 'b':
+ c = '\b';
+ break;
+
+ case 'f':
+ c = '\f';
+ break;
+
+ case 'n':
+ c = '\n';
+ break;
+
+ case 'r':
+ c = '\r';
+ break;
+
+ case 't':
+ c = '\t';
+ break;
+
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ n = 0;
+ v = 0;
+ while (++n<=3 && c>='0' && c<='7') {
+ v = (v<<3) + c - '0';
+ c = get();
+ }
+ unget(c);
+ c = v;
+ break;
+ }
+ }
+ return (c);
+}
+
+/*)Function int as_getline()
+ *
+ * The function as_getline() reads a line of input text from a
+ * .rel source text file, a .lnk command file or from stdin.
+ * Lines of text are processed from a single .lnk file or
+ * multiple .rel files until all files have been read.
+ * The input text line is copied into the global string ib[]
+ * and converted to a NULL terminated string. The function
+ * as_getline() returns a (1) after succesfully reading a line
+ * or a (0) if all files have been read.
+ * This function also opens each input .lst file and output
+ * .rst file as each .rel file is processed.
+ *
+ * local variables:
+ * int i string length
+ * int ftype file type
+ * char * fid file name
+ *
+ * global variables:
+ * lfile *cfp The pointer *cfp points to the
+ * current lfile structure
+ * lfile *filep The pointer *filep points to the
+ * beginning of a linked list of
+ * lfile structures.
+ * int gline get a line from the LST file
+ * to translate for the RST file
+ * char ib[NINPUT] REL file text line
+ * int pass linker pass number
+ * int pflag print linker command file flag
+ * FILE *rfp The file handle to the current
+ * output RST file
+ * FILE *sfp The file handle sfp points to the
+ * currently open file
+ * FILE * stdin c_library
+ * FILE * stdout c_library
+ * FILE *tfp The file handle to the current
+ * LST file being scanned
+ * int uflag update listing flag
+ *
+ * called functions:
+ * FILE * afile() lkmain.c
+ * int fclose() c_library
+ * char * fgets() c_library
+ * int fprintf() c_library
+ * VOID lkulist() lklist.c
+ * VOID lkexit() lkmain.c
+ * int strlen() c_library
+ *
+ * side effects:
+ * The input stream is scanned. The .rel files will be
+ * opened and closed sequentially scanning each in turn.
+ */
+
+int
+as_getline()
+{
+ register int ftype;
+ register char *fid;
+
+loop: if (pflag && cfp && cfp->f_type == F_STD)
+ fprintf(stdout, "ASlink >> ");
+
+ if (sfp == NULL || fgets(ib, sizeof ib, sfp) == NULL) {
+ if (sfp) {
+ fclose(sfp);
+ sfp = NULL;
+ lkulist(0);
+ }
+ if (cfp == NULL) {
+ cfp = filep;
+ } else {
+ cfp = cfp->f_flp;
+ }
+ if (cfp) {
+ ftype = cfp->f_type;
+ fid = cfp->f_idp;
+ if (ftype == F_STD) {
+ sfp = stdin;
+ } else
+ if (ftype == F_LNK) {
+ sfp = afile(fid, "lnk", 0);
+ } else
+ if (ftype == F_REL) {
+ sfp = afile(fid, "rel", 0);
+ /* if a .cdb file exists then copy it over */
+ if (dflag && sfp && dfp && pass == 0) {
+ FILE *xfp = afile(fid,"adb",0); //JCF: Nov 30, 2002
+ if (xfp) {
+ copyfile(dfp,xfp);
+ fclose(xfp);
+ }
+ }
+ if (uflag && pass != 0) {
+ SaveLinkedFilePath(fid); //Save the linked path for aomf51
+ if ((tfp = afile(fid, "lst", 0)) != NULL) {
+ if ((rfp = afile(fid, "rst", 1)) == NULL) {
+ fclose(tfp);
+ tfp = NULL;
+ }
+ }
+ }
+ gline = 1;
+ } else {
+ fprintf(stderr, "Invalid file type\n");
+ lkexit(1);
+ }
+ if (sfp == NULL) {
+ lkexit(1);
+ }
+ goto loop;
+ } else {
+ filep = NULL;
+ return(0);
+ }
+ }
+ chop_crlf(ib);
+ return (1);
+}
+
+/*)Function int more()
+ *
+ * The function more() scans the input text line
+ * skipping white space (SPACES and TABS) and returns a (0)
+ * if the end of the line or a comment delimeter (;) is found,
+ * or a (1) if their are additional characters in the line.
+ *
+ * local variables:
+ * int c next character from
+ * the input text line
+ *
+ * global variables:
+ * none
+ *
+ * called functions:
+ * char getnb() lklex.c
+ * VOID unget() lklex.c
+ *
+ * side effects:
+ * use of getnb() and unget() updates the global pointer ip
+ * the position in the current input text line
+ */
+
+int
+more()
+{
+ register int c;
+
+ c = getnb();
+ unget(c);
+ return( (c == '\0' || c == ';') ? 0 : 1 );
+}
+
+/*)Function char endline()
+ *
+ * The function endline() scans the input text line
+ * skipping white space (SPACES and TABS) and returns the next
+ * character or a (0) if the end of the line is found or a
+ * comment delimiter (;) is found.
+ *
+ * local variables:
+ * int c next character from
+ * the input text line
+ *
+ * global variables:
+ * none
+ *
+ * called functions:
+ * char getnb() lklex.c
+ *
+ * side effects:
+ * Use of getnb() updates the global pointer ip the
+ * position in the current input text line.
+ */
+
+char
+endline()
+{
+ register int c;
+
+ c = getnb();
+ return( (c == '\0' || c == ';') ? 0 : c );
+}
+
+/*)Function VOID chop_crlf(str)
+ *
+ * char *str string to chop
+ *
+ * The function chop_crlf() removes trailing LF or CR/LF from
+ * str, if present.
+ *
+ * local variables:
+ * int i string length
+ *
+ * global variables:
+ * none
+ *
+ * functions called:
+ * none
+ *
+ * side effects:
+ * none
+ */
+
+VOID
+chop_crlf(str)
+char *str;
+{
+ register int i;
+
+ i = strlen(str);
+ if (i >= 1 && str[i-1] == '\n') str[i-1] = 0;
+ if (i >= 2 && str[i-2] == '\r') str[i-2] = 0;
+}