Annotation of GNUtools/cctools/as/app.c, revision 1.1

1.1     ! root        1: /* This is the Assembler Pre-Processor
        !             2:    Copyright (C) 1987 Free Software Foundation, Inc.
        !             3: 
        !             4: This file is part of GAS, the GNU Assembler.
        !             5: 
        !             6: GAS 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 1, or (at your option)
        !             9: any later version.
        !            10: 
        !            11: GAS 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.
        !            15: 
        !            16: You should have received a copy of the GNU General Public License
        !            17: along with GAS; see the file COPYING.  If not, write to
        !            18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
        !            19: 
        !            20: /* App, the assembler pre-processor.  This pre-processor strips out excess
        !            21:    spaces, turns single-quoted characters into a decimal constant, and turns
        !            22:    # <number> <filename> <garbage> into a .line <number>;.file <filename> pair.
        !            23:    This needs better error-handling.
        !            24:  */
        !            25: #include <stdio.h>
        !            26: #include <string.h>
        !            27: #include "as.h"
        !            28: #include "md.h"
        !            29: #include "app.h"
        !            30: #include "messages.h"
        !            31: 
        !            32: FILE *scrub_file = NULL;
        !            33: char *scrub_string = NULL;
        !            34: char *scrub_last_string = NULL;
        !            35: 
        !            36: #ifdef NeXT    /* .include feature */
        !            37: /* These are moved out of do_scrub() so save_scrub_context() can save them */
        !            38: static state;
        !            39: static old_state;
        !            40: static char *out_string;
        !            41: static char out_buf[20];
        !            42: static add_newlines = 0;
        !            43: #endif /* NeXT .include feature */
        !            44: 
        !            45: static char    lex [256];
        !            46: static char    symbol_chars[] = 
        !            47:        "$._ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        !            48: 
        !            49: #define LEX_IS_SYMBOL_COMPONENT                (1)
        !            50: #define LEX_IS_WHITESPACE              (2)
        !            51: #define LEX_IS_LINE_SEPERATOR          (4)
        !            52: #define LEX_IS_COMMENT_START           (8)     /* JF added these two */
        !            53: #define LEX_IS_LINE_COMMENT_START      (16)
        !            54: #define IS_SYMBOL_COMPONENT(c)         (lex [c] & LEX_IS_SYMBOL_COMPONENT)
        !            55: #define IS_WHITESPACE(c)               (lex [c] & LEX_IS_WHITESPACE)
        !            56: #define IS_LINE_SEPERATOR(c)           (lex [c] & LEX_IS_LINE_SEPERATOR)
        !            57: #define IS_COMMENT(c)                  (lex [c] & LEX_IS_COMMENT_START)
        !            58: #define IS_LINE_COMMENT(c)             (lex [c] & LEX_IS_LINE_COMMENT_START)
        !            59: 
        !            60: void
        !            61: do_scrub_begin(
        !            62: void)
        !            63: {
        !            64:     char *p;
        !            65:     const char *q;
        !            66: 
        !            67:        memset(lex, '\0', sizeof(lex));         /* Trust NOBODY! */
        !            68:        lex [' ']               |= LEX_IS_WHITESPACE;
        !            69:        lex ['\t']              |= LEX_IS_WHITESPACE;
        !            70:        for (p =symbol_chars;*p;++p)
        !            71:                lex [(int)*p] |= LEX_IS_SYMBOL_COMPONENT;
        !            72:        lex ['\n']              |= LEX_IS_LINE_SEPERATOR;
        !            73: #ifndef DONTDEF
        !            74: #ifdef NeXT
        !            75:        /*
        !            76:         * This DOES not cause ':' to be a LINE SEPERATOR but does make the
        !            77:         * second if logic after flushchar: in do_scrub_next_char() to handle
        !            78:         * "foo :" and strip the blanks.  This is the way has always been and
        !            79:         * must be this way to work.
        !            80:         */
        !            81: #endif /* NeXT */
        !            82:        lex [':']               |= LEX_IS_LINE_SEPERATOR;
        !            83: #endif /* !defined(DONTDEF) */
        !            84: 
        !            85: #if defined(M88K) || defined(M98K) || defined(HPPA)
        !            86:        lex ['@']               |= LEX_IS_LINE_SEPERATOR;
        !            87: #else
        !            88:        lex [';']               |= LEX_IS_LINE_SEPERATOR;
        !            89: #endif
        !            90:        for (q=md_comment_chars;*q;q++)
        !            91:                lex[(int)*q] |= LEX_IS_COMMENT_START;
        !            92:        for (q=md_line_comment_chars;*q;q++)
        !            93:                lex[(int)*q] |= LEX_IS_LINE_COMMENT_START;
        !            94: }
        !            95: 
        !            96: int
        !            97: scrub_from_file(
        !            98: void)
        !            99: {
        !           100:        return getc(scrub_file);
        !           101: }
        !           102: 
        !           103: void
        !           104: scrub_to_file(
        !           105: int ch)
        !           106: {
        !           107:        ungetc(ch, scrub_file);
        !           108: }
        !           109: 
        !           110: int
        !           111: scrub_from_string(
        !           112: void)
        !           113: {
        !           114:        return scrub_string == scrub_last_string ? EOF : *scrub_string++;
        !           115: }
        !           116: 
        !           117: void
        !           118: scrub_to_string(
        !           119: int ch)
        !           120: {
        !           121:        *--scrub_string = ch;
        !           122: }
        !           123: 
        !           124: int
        !           125: do_scrub_next_char(
        !           126: int (*get)(void),
        !           127: void (*unget)(int ch))
        !           128: /* FILE *fp; */
        !           129: {
        !           130:        /* State 0: beginning of normal line
        !           131:                1: After first whitespace on normal line (flush more white)
        !           132:                2: After first non-white on normal line (keep 1white)
        !           133:                3: after second white on normal line (flush white)
        !           134:                4: after putting out a .line, put out digits
        !           135:                5: parsing a string, then go to old-state
        !           136:                6: putting out \ escape in a "d string.
        !           137:                7: After putting out a .file, put out string.
        !           138:                8: After putting out a .file string, flush until newline.
        !           139:                -1: output string in out_string and go to the state in old_state
        !           140:                -2: flush text until a '*' '/' is seen, then go to state old_state
        !           141:        */
        !           142: 
        !           143: #ifndef NeXT   /* .include feature */
        !           144:        static state;
        !           145:        static old_state;
        !           146:        static char *out_string;
        !           147:        static char out_buf[20];
        !           148:        static add_newlines = 0;
        !           149: #endif /* NeXT .include feature */
        !           150:        int ch;
        !           151: 
        !           152:        if(state==-1) {
        !           153:                ch= *out_string++;
        !           154:                if(*out_string==0) {
        !           155:                        state=old_state;
        !           156:                        old_state=3;
        !           157:                }
        !           158:                return ch;
        !           159:        }
        !           160:        if(state==-2) {
        !           161:                for(;;) {
        !           162:                        do ch=(*get)();
        !           163:                        while(ch!=EOF && ch!='\n' && ch!='*');
        !           164:                        if(ch=='\n' || ch==EOF)
        !           165:                                return ch;
        !           166:                         ch=(*get)();
        !           167:                         if(ch==EOF || ch=='/')
        !           168:                                break;
        !           169:                        (*unget)(ch);
        !           170:                }
        !           171:                state=old_state;
        !           172:                return ' ';
        !           173:        }
        !           174:        if(state==4) {
        !           175:                ch=(*get)();
        !           176:                if(ch==EOF || (ch>='0' && ch<='9'))
        !           177:                        return ch;
        !           178:                else {
        !           179:                        while(ch!=EOF && IS_WHITESPACE(ch))
        !           180:                                ch=(*get)();
        !           181:                        if(ch=='"') {
        !           182:                                (*unget)(ch);
        !           183: #if defined(M88K) || defined(M98K) || defined(HPPA)
        !           184:                                out_string="@ .file ";
        !           185: #else
        !           186:                                out_string="; .file ";
        !           187: #endif
        !           188:                                old_state=7;
        !           189:                                state= -1;
        !           190:                                return *out_string++;
        !           191:                        } else {
        !           192:                                while(ch!=EOF && ch!='\n')
        !           193:                                        ch=(*get)();
        !           194: #ifdef NeXT
        !           195:                                /* bug fix for bug #8918, which was when
        !           196:                                 * a full line comment line this:
        !           197:                                 * # 40 MP1 = M + 1
        !           198:                                 * got confused with a cpp output like:
        !           199:                                 * # 1 "hello.c" 1
        !           200:                                 */
        !           201:                                state = 0;
        !           202: #endif /* NeXT */
        !           203:                                return ch;
        !           204:                        }
        !           205:                }
        !           206:        }
        !           207:        if(state==5) {
        !           208:                ch=(*get)();
        !           209:                if(ch=='"') {
        !           210:                        state=old_state;
        !           211:                        return '"';
        !           212:                } else if(ch=='\\') {
        !           213:                        state=6;
        !           214:                        return ch;
        !           215:                } else if(ch==EOF) {
        !           216:                        as_warn("End of file in string: inserted '\"'");
        !           217:                        state=old_state;
        !           218:                        (*unget)('\n');
        !           219:                        return '"';
        !           220:                } else {
        !           221:                        return ch;
        !           222:                }
        !           223:        }
        !           224:        if(state==6) {
        !           225:                state=5;
        !           226:                ch=(*get)();
        !           227:                switch(ch) {
        !           228:                        /* This is neet.  Turn "string
        !           229:                           more string" into "string\n  more string"
        !           230:                         */
        !           231:                case '\n':
        !           232:                        (*unget)('n');
        !           233:                        add_newlines++;
        !           234:                        return '\\';
        !           235: 
        !           236:                case '"':
        !           237:                case '\\':
        !           238:                case 'b':
        !           239:                case 'f':
        !           240:                case 'n':
        !           241:                case 'r':
        !           242:                case 't':
        !           243:                case '0':
        !           244:                case '1':
        !           245:                case '2':
        !           246:                case '3':
        !           247:                case '4':
        !           248:                case '5':
        !           249:                case '6':
        !           250:                case '7':
        !           251:                        break;
        !           252:                default:
        !           253:                        as_warn("Unknown escape '\\%c' in string: Ignored",ch);
        !           254:                        break;
        !           255: 
        !           256:                case EOF:
        !           257:                        as_warn("End of file in string: '\"' inserted");
        !           258:                        return '"';
        !           259:                }
        !           260:                return ch;
        !           261:        }
        !           262: 
        !           263:        if(state==7) {
        !           264:                ch=(*get)();
        !           265:                state=5;
        !           266:                old_state=8;
        !           267:                return ch;
        !           268:        }
        !           269: 
        !           270:        if(state==8) {
        !           271:                do ch= (*get)();
        !           272:                while(ch!='\n');
        !           273:                state=0;
        !           274:                return ch;
        !           275:        }
        !           276: 
        !           277:  flushchar:
        !           278:        ch=(*get)();
        !           279:        switch(ch) {
        !           280:        case ' ':
        !           281:        case '\t':
        !           282:                do ch=(*get)();
        !           283:                while(ch!=EOF && IS_WHITESPACE(ch));
        !           284:                if(ch==EOF)
        !           285:                        return ch;
        !           286:                if(IS_COMMENT(ch) || (state==0 && IS_LINE_COMMENT(ch)) || ch=='/' || IS_LINE_SEPERATOR(ch)) {
        !           287:                        (*unget)(ch);
        !           288:                        goto flushchar;
        !           289:                }
        !           290:                (*unget)(ch);
        !           291:                if(state==0 || state==2) {
        !           292:                        state++;
        !           293:                        return ' ';
        !           294:                } else goto flushchar;
        !           295: 
        !           296:        case '/':
        !           297:                ch=(*get)();
        !           298:                if(ch=='*') {
        !           299:                        for(;;) {
        !           300:                                do {
        !           301:                                        ch=(*get)();
        !           302:                                        if(ch=='\n')
        !           303:                                                add_newlines++;
        !           304:                                } while(ch!=EOF && ch!='*');
        !           305:                                ch=(*get)();
        !           306:                                if(ch==EOF || ch=='/')
        !           307:                                        break;
        !           308:                                (*unget)(ch);
        !           309:                        }
        !           310:                        if(ch==EOF)
        !           311:                                as_warn("End of file in '/' '*' string: */ inserted");
        !           312: 
        !           313:                        (*unget)(' ');
        !           314:                        goto flushchar;
        !           315:                } else {
        !           316: #if defined(I860) || defined(M88K) || defined(M98K) || defined(I386) || \
        !           317:     defined(HPPA) || defined (SPARC)
        !           318:                  if (ch == '/') {
        !           319:                    do {
        !           320:                      ch=(*get)();
        !           321:                    } while (ch != EOF && (ch != '\n'));
        !           322:                    if (ch == EOF)
        !           323:                      as_warn("End of file before newline in // comment");
        !           324:                    if ( ch == '\n' )   /* Push NL back so we can complete state */
        !           325:                        (*unget)(ch);
        !           326:                    goto flushchar;
        !           327:                  }
        !           328: #endif
        !           329:                        if(IS_COMMENT('/') || (state==0 && IS_LINE_COMMENT('/'))) {
        !           330:                                (*unget)(ch);
        !           331:                                ch='/';
        !           332:                                goto deal_misc;
        !           333:                        }
        !           334:                        if(ch!=EOF)
        !           335:                                (*unget)(ch);
        !           336:                        return '/';
        !           337:                }
        !           338:                break;
        !           339: 
        !           340:        case '"':
        !           341:                old_state=state;
        !           342:                state=5;
        !           343:                return '"';
        !           344:                break;
        !           345: 
        !           346:        case '\'':
        !           347:                ch=(*get)();
        !           348:                if(ch==EOF) {
        !           349:                        as_warn("End-of-file after a ': \\000 inserted");
        !           350:                        ch=0;
        !           351:                }
        !           352:                sprintf(out_buf,"(%d)",ch&0xff);
        !           353:                old_state=state;
        !           354:                state= -1;
        !           355:                out_string=out_buf;
        !           356:                return *out_string++;
        !           357: 
        !           358:        case ':':
        !           359:                if(state!=3)
        !           360:                        state=0;
        !           361:                return ch;
        !           362: 
        !           363:        case '\n':
        !           364:                if(add_newlines) {
        !           365:                        --add_newlines;
        !           366:                        (*unget)(ch);
        !           367:                }
        !           368:        /* Fall through.  */
        !           369: #if defined(M88K) || defined(M98K) || defined(HPPA)
        !           370:        case '@':
        !           371: #else
        !           372:        case ';':
        !           373: #endif
        !           374:                state=0;
        !           375:                return ch;
        !           376: 
        !           377:        default:
        !           378:        deal_misc:
        !           379:                if(state==0 && IS_LINE_COMMENT(ch)) {
        !           380:                        do ch=(*get)();
        !           381:                        while(ch!=EOF && IS_WHITESPACE(ch));
        !           382:                        if(ch==EOF) {
        !           383:                                as_warn("EOF in comment:  Newline inserted");
        !           384:                                return '\n';
        !           385:                        }
        !           386:                        if(ch<'0' || ch>'9') {
        !           387:                                do ch=(*get)();
        !           388:                                while(ch!=EOF && ch!='\n');
        !           389:                                if(ch==EOF)
        !           390:                                        as_warn("EOF in Comment: Newline inserted");
        !           391:                                state=0;
        !           392:                                return '\n';
        !           393:                        }
        !           394:                        (*unget)(ch);
        !           395:                        old_state=4;
        !           396:                        state= -1;
        !           397:                        out_string=".line ";
        !           398:                        return *out_string++;
        !           399: 
        !           400:                } else if(IS_COMMENT(ch)) {
        !           401:                        do ch=(*get)();
        !           402:                        while(ch!=EOF && ch!='\n');
        !           403:                        if(ch==EOF)
        !           404:                                as_warn("EOF in comment:  Newline inserted");
        !           405:                        state=0;
        !           406:                        return '\n';
        !           407: 
        !           408:                } else if(state==0) {
        !           409:                        state=2;
        !           410:                        return ch;
        !           411:                } else if(state==1) {
        !           412:                        state=2;
        !           413:                        return ch;
        !           414:                } else {
        !           415:                        return ch;
        !           416: 
        !           417:                }
        !           418:        case EOF:
        !           419:                if(state==0)
        !           420:                        return ch;
        !           421:                as_warn("End-of-File not at end of a line");
        !           422:        }
        !           423:        return -1;
        !           424: }
        !           425: 
        !           426: #ifdef NeXT    /* .include feature */
        !           427: void
        !           428: save_scrub_context(
        !           429: scrub_context_data *save_buffer_ptr)
        !           430: {
        !           431:        save_buffer_ptr->last_scrub_file = scrub_file;
        !           432:        save_buffer_ptr->last_state = state;
        !           433:        save_buffer_ptr->last_old_state = old_state;
        !           434:        save_buffer_ptr->last_out_string = out_string;
        !           435:        memcpy(save_buffer_ptr->last_out_buf, out_buf, sizeof(out_buf));
        !           436:        save_buffer_ptr->last_add_newlines = add_newlines;
        !           437: 
        !           438:        state = 0;
        !           439:        old_state = 0;
        !           440:        out_string = NULL;
        !           441:        memset(out_buf, '\0', sizeof(out_buf));
        !           442:        add_newlines = 0;
        !           443: }
        !           444: 
        !           445: void
        !           446: restore_scrub_context(
        !           447: scrub_context_data *save_buffer_ptr)
        !           448: {
        !           449:        scrub_file = save_buffer_ptr->last_scrub_file;
        !           450:        state = save_buffer_ptr->last_state;
        !           451:        old_state = save_buffer_ptr->last_old_state;
        !           452:        out_string = save_buffer_ptr->last_out_string;
        !           453:        memcpy(out_buf, save_buffer_ptr->last_out_buf, sizeof(out_buf));
        !           454:        add_newlines = save_buffer_ptr->last_add_newlines;
        !           455: }
        !           456: #endif /* NeXT .include feature */
        !           457: 
        !           458: #ifdef TEST
        !           459: 
        !           460: const char md_comment_chars[] = "|";
        !           461: const char md_line_comment_chars[] = "#";
        !           462: 
        !           463: int
        !           464: get(
        !           465: void)
        !           466: {
        !           467:        return(getc(stdin));
        !           468: }
        !           469: 
        !           470: void
        !           471: unget(
        !           472: int ch)
        !           473: {
        !           474:        ungetc(ch, stdin);
        !           475: }
        !           476: 
        !           477: void
        !           478: main(
        !           479: int argc,
        !           480: char *argv[],
        !           481: char *envp[])
        !           482: {
        !           483:     int ch;
        !           484: 
        !           485:        while((ch = do_scrub_next_char(get, unget)) != EOF)
        !           486:            putc(ch, stdout);
        !           487: }
        !           488: 
        !           489: void
        !           490: as_warn(
        !           491: const char *format,
        !           492: ...)
        !           493: {
        !           494:     va_list ap;
        !           495: 
        !           496:        va_start(ap, format);
        !           497:        vfprintf(stderr, format, ap);
        !           498:        fprintf(stderr, "\n");
        !           499:        va_end(ap);
        !           500: }
        !           501: #endif /* TEST */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.