home *** CD-ROM | disk | FTP | other *** search
- /*
-
-
- Copyright (C) 1990 Texas Instruments Incorporated.
-
- Permission is granted to any individual or institution to use, copy, modify,
- and distribute this software, provided that this complete copyright and
- permission notice is maintained, intact, in all copies and supporting
- documentation.
-
- Texas Instruments Incorporated provides this software "as is" without
- express or implied warranty.
-
-
- *
- * Utility functions used by defmacros.
- *
- * Edit history
- * Created: LGO 30-Mar-89 -- Initial design and implementation.
- *
- */
-
- #include "defmacio.h"
-
- /*
- * Put a string in the input buffer used by getchar
- * This lets us use scan_next for arbitrary strings.
- */
- void set_inbuffer(instring)
- char* instring;
- {
- static FILEINFO inbuf = {0, 0, 0, 0, 0, 0, 0, 0};
- inbuf.bptr = inbuf.buffer = instring;
- MacInFile = &inbuf;
- }
-
- /*
- // Skip whitespace characters and comments, returning the next character
- */
- char
- skip_blanks()
- {
- register char c;
- again:
- while ((c = getchar()) != EOF && isspace(c));
- if (c == '/') {
- char nc = getchar();
- if (nc == '/') { /* If // comment, skip to end of line */
- while ((c = getchar()) != EOF && c != '\n');
- goto again;
- } else if (nc == '*') { /* If / * comment, skip to */
- char p = getchar();
- while ((c = getchar()) != EOF) {
- if (c == '/' && p == '*') break;
- p = c;
- }
- goto again;
- } else /* Else putback character after / */
- unget();
- } else if (c == '\\') {
- char nc = getchar();
- if (nc == '\n') goto again; /* If \\\n, ignore */
- unget();
- }
- return(c);
- }
-
- /*
- * Skip to next newline
- */
- char
- skip_line()
- {
- char c;
- while ((c = getchar()) != EOF)
- if (c == '\n') break;
- return(c);
- }
-
- /*
- * Copy the next alphanumeric token
- * the argument, str is a pointer to a string where the token is to be copied.
- * Returns a pointer to the END of the token, which contains the NEXT character.
- */
- char*
- copytoken(str)
- char* str;
- {
- int is_bad = TRUE;
- char c = skip_blanks();
- while (isalnum(c) ||
- (c == '$') ||
- (c == '_')) {
- *str++ = c;
- c = getchar();
- is_bad = FALSE;
- }
- if(is_bad) {
- if (c == EOF)
- fprintf(stderr, "End of file while scanning for token\n");
- else
- fprintf(stderr, "Illegal character in token: '%c'\n", c);
- return NULL;
- }
- unget();
- *str = EOS;
- return(str);
- }
-
- STRING work_string = NULL;
-
- static char*
- scan_next_string(delim)
- char delim; /* Current delimiter */
- {
- char c; /* Current character */
- char p; /* Previous character */
- char* workp = work_string->buffp; /* result buffer */
- char* workend = work_string->buffend; /* end of result buffer */
-
- for (p = EOS; (c = getchar()) != EOF; p = c) {
- if (workp >= workend-1) {
- work_string->buffp = workp;
- grow_STRING(work_string, 0);
- workp = work_string->buffp;
- workend = work_string->buffend;
- }
- *workp++ = c;
- if (delim == c && /* Quit when delimeter found */
- p != '\\' && /* and it's not quoted */
- (delim != '/' || p == '*')) { /* Special test for end of comment */
- *workp = EOS;
- work_string->buffp = workp;
- return workp;
- }
- }
- /* end of file when we get here */
- *workp = EOS;
- work_string->buffp = workp;
- return workp;
- }
-
-
- char*
- scan_next_internal(delim, is_top_level)
- char delim; /* Current delimiter */
- int is_top_level; /* flag */
- {
- char newdelim; /* New delimiter to look for */
- int is_string = FALSE; /* New is_string flag */
- register char c; /* Current character */
- register char* workp = work_string->buffp; /* result buffer */
- register char* workend = work_string->buffend; /* end of result buffer */
-
- while ((c = getchar()) != EOF) {
- if (workp >= workend-1) {
- work_string->buffp = workp;
- grow_STRING(work_string, 0);
- workp = work_string->buffp;
- workend = work_string->buffend;
- }
- *workp++ = c;
- if (delim == c) { /* Quit when delimeter found */
- *workp = EOS;
- work_string->buffp = workp;
- return workp;
- }
- switch (c) { /* Look for new delimeters when not is_string */
- case '{': newdelim = '}'; break;
- case '[': newdelim = ']'; break;
- case '(': newdelim = ')'; break;
- case '<':
- if (delim != '>')
- continue;
- newdelim = '>'; break;
- case '\'': newdelim = '\''; is_string = TRUE; break;
- case '\"': newdelim = '\"'; is_string = TRUE; break;
- case '/': /* start of comment? */
- c = getchar();
- unget();
- if (c == '/') { /* standard comment */
- newdelim = '\n';
- is_string = TRUE;
- break;
- } else if (c == '*') { /* c++ comment */
- newdelim = '/';
- is_string = TRUE;
- break;
- }
- continue;
- default: /* comma grabs args */
- continue;
- } /* end switch */
- if (is_top_level && newdelim == delim) {
- is_top_level = FALSE;
- continue; /* at top_level, with left side of delimiter */
- }
- work_string->buffp = workp;
- if (is_string)
- workp = scan_next_string(newdelim);
- else
- workp = scan_next_internal(newdelim, FALSE);
- workend = work_string->buffend;
- is_string = FALSE;
- } /* end while */
- /* end of file when we get here */
- *workp = EOS;
- work_string->buffp = workp;
- return workp;
- }
-
- void scan_start() {
- if(work_string == NULL) /* Setup buffer */
- work_string = make_STRING(4096);
- work_string->buffp = work_string->buff;
- }
-
- /*
- * Get the next token, stopping at delim
- */
- char* scan_next(delim)
- char delim; /* delimiter */
- {
- scan_start();
- skip_blanks(); /* skip leading whitespace */
- unget();
- if (delim == ' ') { /* ' ' means grab token */
- work_string->buffp = copytoken(work_string->buffp);
- if ((delim = getchar()) != '<') { /* Grab <...> */
- unget();
- } else {
- *work_string->buffp++ = delim;
- scan_next_internal('>', FALSE);
- }
- } else {
- scan_next_internal(delim, TRUE);
- }
- work_string->buffp++;
- return work_string->buff;
- }
- /*
- * Get the next token, stopping at delim
- * Call scan_start before using this function
- * The string returned is inside work_string, and
- * will be clobbered on the next call to scan_start.
- */
- char* scan_list(delim)
- char delim; /* delimiter */
- {
- unsigned int start = work_string->buffp - work_string->buff;
- skip_blanks(); /* skip leading whitespace */
- unget();
- if (delim == ' ') { /* ' ' means grab token */
- if (work_string->buffend - work_string->buffp <= 128)
- grow_STRING(work_string, 128); /* Ensure at least 128 chars */
- work_string->buffp = copytoken(work_string->buffp);
- }
- else
- scan_next_internal(delim, TRUE);
- work_string->buffp++;
- return (work_string->buff+start);
- }
-
- char*
- scan_token(delims)
- char* delims; /* delimiters */
- {
- register char* workp;
- char* work;
- register char c;
- if(work_string == NULL) /* Setup buffer */
- work_string = make_STRING(3000);
- workp = work_string->buff;
- c = skip_blanks(); /* skip leading whitespace */
- while(c != EOF) {
- register char* p;
- for(p=delims; *p!=EOS; p++)
- if (*p == c) goto done;
- *workp++ = c;
- if (ispunct(c)) /* If {([<'" Use scan_next_internal */
- for(p="{}()[]<>\'\'\"\""; *p!=EOS; p++)
- if (*p++ == c) {
- work_string->buffp = workp;
- if (*p == '\'' || *p == '\"')
- workp = scan_next_string(*p);
- else
- workp = scan_next_internal(*p, FALSE);
- break;
- }
- c = getchar();
- }
- done:
- unget();
- work = work_string->buff;
- while(workp>work && isspace(*(workp-1))) workp--;
- *workp = EOS; /* trim trailing blanks */
- return savestring(work);
- }
-
- void
- put_string(string)
- char* string;
- {
- char c;
- putchar('\"');
- while ((c=*string++) != EOS)
- switch (c) {
- case '\"': putchar('\\');
- default: putchar(c);
- }
- putchar('\"');
- }
-
- /* c_upcase -- Convert all alphabetical characters to uppercase
- * Input: Character string
- * Output: Updated string
- */
- char*
- c_upcase (s)
- char* s;
- {
- char* p = s; /* Point to beginning of string */
- while (*p != EOS) { /* While there are still valid characters */
- if (islower (*p)) /* if this is lower case */
- *p = toupper (*p); /* convert to uppercase */
- p++; /* Advance pointer */
- }
- return s; /* Return reference to modified string */
- }
-
-
- /* c_downcase -- Convert all alphabetical characters to lowercase
- * Input: Character string
- * Output: Updated string
- */
-
- char*
- c_downcase (s)
- char* s;
- {
- char* p = s; /* Point to beginning of string */
- while (*p != EOS) { /* While there are still valid characters */
- if (isupper (*p)) /* if this is upper case */
- *p = tolower (*p); /* convert to lowercase */
- p++; /* Advance pointer */
- }
- return s; /* Return reference to modified string */
- }
-
- /* c_capitalize -- Capitalize all words in a string. A word is defined as
- * a sequence of characters separated by white space
- * Input: Character string
- * Output: Updated string
- */
-
- char*
- c_capitalize (s)
- char* s;
- {
- char* p = s; /* Point to beginning of string */
- while (TRUE) { /* Infinite loop */
- for ( ; *p && isspace(*p); p++); /* Skip white space */
- if (*p == EOS) /* If end of string */
- return s; /* Return string */
- if (islower (*p)) /* If lower case */
- *p = toupper (*p); /* Convert character */
- for ( ; *p && !isspace (*p); p++); /* Search for white space */
- }
- }
-
- /*
- * c_trim_all -- Removes any occurrence of the character(s) in "c" from "s"
- * Input: Source string and token string
- * Output: Modified string "s"
- */
- char* c_trim_all (s, c)
- char* s;
- char* c;
- {
- char* t0;
- int old_length = strlen (s); /* Old string "s" length */
- int new_length = 0; /* Counts characters in result */
- char* p = getmem(old_length+1); /* Temporary holding array */
- int i;
- for (i = 0; i < old_length; i++) { /* For each character in string */
- for (t0 = c; *t0 && s[i] != *t0; t0++); /* Scan for match */
- if (*t0 == EOS) /* If no match found */
- p[new_length++] = s[i]; /* Copy character */
- }
- p[new_length] = EOS; /* NULL terminate string */
- strcpy (s, p); /* Copy new string */
- free(p); /* Deallocate temporary memory */
- return s; /* Return pointer to new string */
- }
-
- /*
- * Primitive dynamic string support
- */
-
- STRING make_STRING(size)
- int size;
- { STRING result = (STRING) getmem(sizeof(struct buf_string));
- char* buff = getmem(size);
- *buff = EOS;
- result->buff = buff;
- result->buffp = buff;
- result->buffend = buff+size;
- return result;
- }
-
- void destroy_STRING(string)
- STRING string;
- {
- free(string->buff);
- free(string);
- }
-
- void grow_STRING(string, len)
- STRING string;
- unsigned int len;
- {
- extern char* realloc(/* char*, int */);
- char* old = string->buff;
- unsigned int size = len + ((string->buffend - old) * 2);
- char* new;
- new = realloc(old, size);
- if (new == NULL) cfatal("Heap exausted while growing string", "");
- string->buffp = new + (string->buffp - old);
- string->buff = new;
- string->buffend = new + size;
- }
-
- void append_STRING(string, chars)
- STRING string;
- char* chars;
- { unsigned int len = strlen(chars);
- if (string->buffend - string->buffp <= len)
- grow_STRING(string, len);
- strcpy(string->buffp, chars);
- string->buffp += len;
- }
-
- /*
- // Copy whitespace and comments into a string, returning the next character
- */
- char
- append_blanks(string)
- STRING string;
- {
- register char c;
- again:
- while ((c = getchar()) != EOF && isspace(c))
- append_char(string, c);
- if (c == '/') {
- char nc = getchar();
- if (nc == '/') { /* If // comment, skip to end of line */
- append_STRING(string, "//");
- while ((c = getchar()) != EOF) {
- append_char(string, c);
- if (c == '\n') break;
- }
- goto again;
- } else if (nc == '*') { /* If / * comment, skip to */
- char p = getchar();
- append_STRING(string, "/*");
- append_char(string, p);
- while ((c = getchar()) != EOF) {
- append_char(string, c);
- if (c == '/' && p == '*') break;
- p = c;
- }
- goto again;
- } else /* Else putback character after / */
- unget();
- } else if (c == '\\') {
- char nc = getchar();
- if (nc == '\n') goto again; /* If \\\n, ignore */
- unget();
- }
- *(string->buffp) = EOS;
- return(c);
- }
-