Exemple #1
0
int
assemble(char *file)
{
    char ofile[100], incfile[20], *p;
    int i, of;

    strcpy(ofile, file);
    if(p = strrchr(ofile, pathchar())) {
        include[0] = ofile;
        *p++ = 0;
    } else
        p = ofile;
    if(outfile == 0) {
        outfile = p;
        if(p = strrchr(outfile, '.'))
            if(p[1] == 's' && p[2] == 0)
                p[0] = 0;
        p = strrchr(outfile, 0);
        p[0] = '.';
        p[1] = thechar;
        p[2] = 0;
    }
    p = getenv("INCLUDE");
    if(p) {
        setinclude(p);
    } else {
        if(systemtype(Plan9)) {
            sprint(incfile,"/%s/include", thestring);
            setinclude(strdup(incfile));
        }
    }

    of = mycreat(outfile, 0664);
    if(of < 0) {
        yyerror("%ca: cannot create %s", thechar, outfile);
        errorexit();
    }
    Binit(&obuf, of, OWRITE);

    pass = 1;
    nosched = 0;
    pinit(file);
    for(i=0; i<nDlist; i++)
        dodefine(Dlist[i]);
    yyparse();
    if(nerrors) {
        cclean();
        return nerrors;
    }

    pass = 2;
    nosched = 0;
    outhist();
    pinit(file);
    for(i=0; i<nDlist; i++)
        dodefine(Dlist[i]);
    yyparse();
    cclean();
    return nerrors;
}
Exemple #2
0
Fichier : lex.c Projet : hfeeki/go
int
assemble(char *file)
{
	char *ofile, *p;
	int i, of;

	ofile = alloc(strlen(file)+3); // +3 for .x\0 (x=thechar)
	strcpy(ofile, file);
	p = utfrrune(ofile, pathchar());
	if(p) {
		include[0] = ofile;
		*p++ = 0;
	} else
		p = ofile;
	if(outfile == 0) {
		outfile = p;
		if(outfile){
			p = utfrrune(outfile, '.');
			if(p)
				if(p[1] == 's' && p[2] == 0)
					p[0] = 0;
			p = utfrune(outfile, 0);
			p[0] = '.';
			p[1] = thechar;
			p[2] = 0;
		} else
			outfile = "/dev/null";
	}

	of = create(outfile, OWRITE, 0664);
	if(of < 0) {
		yyerror("%ca: cannot create %s", thechar, outfile);
		errorexit();
	}
	Binit(&obuf, of, OWRITE);

	pass = 1;
	pinit(file);

	Bprint(&obuf, "go object %s %s %s\n", getgoos(), thestring, getgoversion());

	for(i=0; i<nDlist; i++)
		dodefine(Dlist[i]);
	yyparse();
	if(nerrors) {
		cclean();
		return nerrors;
	}

	Bprint(&obuf, "\n!\n");

	pass = 2;
	outhist();
	pinit(file);
	for(i=0; i<nDlist; i++)
		dodefine(Dlist[i]);
	yyparse();
	cclean();
	return nerrors;
}
Exemple #3
0
int preprocess()
{   
	++lptr;
    lastch = ' ';
    NextToken();               /* get first word on line */
    if( lastst != id ) {
            error(ERR_PREPROC);
            return getline(incldepth == 0);
            }
    if( strcmp(lastid,"include") == 0 )
            return doinclude();
    else if( strcmp(lastid,"define") == 0 )
            return dodefine();
    else if (strcmp(lastid,"ifdef")==0)
			return doifdef();
    else if (strcmp(lastid,"ifndef")==0)
			return doifndef();
    else if (strcmp(lastid,"endif")==0)
			return doendif();
	else
	{
        error(ERR_PREPROC);
        return getline(incldepth == 0);
    }
}
Exemple #4
0
int parse() { token=getlex(); do { if (token <= 0) return 1;
    if (istoken('#')) {
      if (istoken(T_DEFINE)) dodefine();
      else if (istoken(T_INCLUDE)) doinclude();
      else error1("define oder include erwartet");
      } else{ typeName();  if (token=='(') dofunc();  else doglob(); } 
    } while(1); 
}
Exemple #5
0
int do_sw_commands(char *cp)
{
    while(*cp) {
	switch(*cp++) {
	case 'D': dodefine(cp);  return 1;
	case 'I': EiC_insertpath(cp); return 1;
	case '\?':
	case 'h':
	case 'H': usage();
	case 'c':
	case 'C': EiC_TIMER = 1; break;
	#ifndef NO_HTML
	case 'e':
	    // connect stderr to stdout 
	    dup2(1,2); 
	    // setup stdout to behave like stderr 
	    if(setvbuf(stdout,NULL,_IONBF,0) != 0)
		EiC_error("failed to setup stdout\n");
	    // inform the browser 
	    puts("Content-type: text/plain\n\n");
	    break;
	#endif
	case 'v':
	case 'V': puts(Version); exit(1);

	case 'R': prompt = 1;
	case 'r': reStart = 1;  break;

	case 's': 
	case 'S': silent = 1; break; 

	case 'f': ScriptMode = 1; break;
	case 'p': EiC_SHOWLINE = 1; break;
	case 'P': EiC_showIncludes = 1; break;
	case 't':
	case 'T': EiC_traceON = 1; break;
	case 'n': HistoryFile = 0; break;
	case 'N': StartUpH = 0; break;
	case 'A': EiC_Interact = 0; break;
	default:
	    while(isspace(*cp)) cp++;
	    if(*cp == '-')  /* assume script mode */
		while(isspace(*++cp));
	    else if(*cp)  /* catch for lines ending with whitespace */
		return 0;
	}
    }
    return 1;
}
Exemple #6
0
/**
 * process all input text
 * at this level, only static declarations, defines, includes,
 * and function definitions are legal.
 */
void parse(void) {
    while (!input_eof) {
        if (match("#")) {
            if (match("asm"))
                doasm();
            else if (match("include"))
                doinclude();
            else if (match("define"))
                dodefine();
            else if (match("undef"))
                doundef();
        }
        else if (amatch("extern", 6))
            do_declarations(EXTERN, NULL_TAG, 0);
        else if (amatch("static", 6))
            do_declarations(STATIC, NULL_TAG, 0);
        else if (do_declarations(PUBLIC, NULL_TAG, 0))
            ;
        else {
            newfunc();
        }
        blanks();
    }
}
Exemple #7
0
void
control(Tokenrow *trp)
{
	Nlist *np;
	Token *tp;

	tp = trp->tp;
	if (tp->type!=NAME) {
		if (tp->type==NUMBER)
			goto kline;
		if (tp->type != NL)
			error(ERROR, "Unidentifiable control line");
		return;			/* else empty line */
	}
	if ((np = lookup(tp, 0))==NULL || (np->flag&ISKW)==0 && !skipping) {
		error(WARNING, "Unknown preprocessor control %t", tp);
		return;
	}
	if (skipping) {
		if ((np->flag&ISKW)==0)
			return;
		switch (np->val) {
		case KENDIF:
			if (--ifdepth<skipping)
				skipping = 0;
			--cursource->ifdepth;
			setempty(trp);
			return;

		case KIFDEF:
		case KIFNDEF:
		case KIF:
			if (++ifdepth >= NIF)
				error(FATAL, "#if too deeply nested");
			++cursource->ifdepth;
			return;

		case KELIF:
		case KELSE:
			if (ifdepth<=skipping)
				break;
			return;

		default:
			return;
		}
	}
	switch (np->val) {
	case KDEFINE:
		dodefine(trp);
		break;

	case KUNDEF:
		tp += 1;
		if (tp->type!=NAME || trp->lp - trp->bp != 4) {
			error(ERROR, "Syntax error in #undef");
			break;
		}
		if ((np = lookup(tp, 0)) != NULL)
			np->flag &= ~ISDEFINED;
		break;

	case KPRAGMA:
		return;

	case KIFDEF:
	case KIFNDEF:
	case KIF:
		if (++ifdepth >= NIF)
			error(FATAL, "#if too deeply nested");
		++cursource->ifdepth;
		ifsatisfied[ifdepth] = 0;
		if (eval(trp, np->val))
			ifsatisfied[ifdepth] = 1;
		else
			skipping = ifdepth;
		break;

	case KELIF:
		if (ifdepth==0) {
			error(ERROR, "#elif with no #if");
			return;
		}
		if (ifsatisfied[ifdepth]==2)
			error(ERROR, "#elif after #else");
		if (eval(trp, np->val)) {
			if (ifsatisfied[ifdepth])
				skipping = ifdepth;
			else {
				skipping = 0;
				ifsatisfied[ifdepth] = 1;
			}
		} else
			skipping = ifdepth;
		break;

	case KELSE:
		if (ifdepth==0 || cursource->ifdepth==0) {
			error(ERROR, "#else with no #if");
			return;
		}
		if (ifsatisfied[ifdepth]==2)
			error(ERROR, "#else after #else");
		if (trp->lp - trp->bp != 3)
			error(ERROR, "Syntax error in #else");
		skipping = ifsatisfied[ifdepth]? ifdepth: 0;
		ifsatisfied[ifdepth] = 2;
		break;

	case KENDIF:
		if (ifdepth==0 || cursource->ifdepth==0) {
			error(ERROR, "#endif with no #if");
			return;
		}
		--ifdepth;
		--cursource->ifdepth;
		if (trp->lp - trp->bp != 3)
			error(WARNING, "Syntax error in #endif");
		break;

	case KERROR:
		trp->tp = tp+1;
		error(WARNING, "#error directive: %r", trp);
		break;

	case KLINE:
		trp->tp = tp+1;
		expandrow(trp, "<line>");
		tp = trp->bp+2;
	kline:
		if (tp+1>=trp->lp || tp->type!=NUMBER || tp+3<trp->lp
		 || (tp+3==trp->lp && ((tp+1)->type!=STRING)||*(tp+1)->t=='L')){
			error(ERROR, "Syntax error in #line");
			return;
		}
		cursource->line = atol((char*)tp->t)-1;
		if (cursource->line<0 || cursource->line>=32768)
			error(WARNING, "#line specifies number out of range");
		tp = tp+1;
		if (tp+1<trp->lp)
			cursource->filename=(char*)newstring(tp->t+1,tp->len-2,0);
		return;

	case KDEFINED:
		error(ERROR, "Bad syntax for control line");
		break;

	case KINCLUDE:
		doinclude(trp);
		trp->lp = trp->bp;
		return;

	case KEVAL:
		eval(trp, np->val);
		break;

	default:
		error(ERROR, "Preprocessor control `%t' not yet implemented", tp);
		break;
	}
	setempty(trp);
	return;
}
Exemple #8
0
int
main(int argc, char *argv[])
{
	int c;
	int n;
	int rval;
	char *p;

	setlocale(LC_ALL, "");

	traceout = stderr;

	if (signal(SIGINT, SIG_IGN) != SIG_IGN)
		signal(SIGINT, onintr);

	initkwds();
	initspaces();
	STACKMAX = INITSTACKMAX;

	mstack = (stae *)xalloc(sizeof(stae) * STACKMAX);
	sstack = (char *)xalloc(STACKMAX);

	maxout = 0;
	outfile = NULL;
	resizedivs(MAXOUT);

	while ((c = getopt(argc, argv, "gst:d:D:U:o:I:")) != -1)
		switch(c) {
		case 'D':               /* define something..*/
			for (p = optarg; *p; p++)
				if (*p == '=')
					break;
			if (p == optarg)
				errx(1, "null variable cannot be defined");
			if (*p)
				*p++ = EOS;
			dodefine(optarg, p);
			break;
		case 'I':
			addtoincludepath(optarg);
			break;
		case 'U':               /* undefine...       */
			remhash(optarg, TOP);
			break;
		case 'g':
			mimic_gnu = 1;
			break;
		case 'd':
			set_trace_flags(optarg);
			break;
		case 's':
			synccpp = 1;
			break;
		case 't':
			mark_traced(optarg, 1);
			break;
		case 'o':
			trace_file(optarg);
                        break;
		case '?':
		default:
			usage();
		}

        argc -= optind;
        argv += optind;

	rval = 0;
	active = stdout;		/* default active output     */
	bbase[0] = bufbase;
        if (!argc) {
 		sp = -1;		/* stack pointer initialized */
		fp = 0; 		/* frame pointer initialized */
		set_input(infile+0, stdin, "stdin");
					/* default input (naturally) */
		if ((inname[0] = strdup("-")) == NULL)
			err(1, NULL);
		inlineno[0] = 1;
		emitline();
		macro();
	} else
		for (; argc--; ++argv) {
			p = *argv;
			if (p[0] == '-' && p[1] == EOS)
				set_input(infile, stdin, "stdin");
			else if (fopen_trypath(infile, p) == NULL) {
				warn("%s", p);
				rval = 1;
				continue;
			}
			sp = -1;
			fp = 0;
			if ((inname[0] = strdup(p)) == NULL)
				err(1, NULL);
			inlineno[0] = 1;
			emitline();
			macro();
		    	release_input(infile);
		}

	if (*m4wraps) { 		/* anything for rundown ??   */
		ilevel = 0;		/* in case m4wrap includes.. */
		bufbase = bp = buf;	/* use the entire buffer   */
		pbstr(m4wraps); 	/* user-defined wrapup act   */
		macro();		/* last will and testament   */
	}

	if (active != stdout)
		active = stdout;	/* reset output just in case */
	for (n = 1; n < maxout; n++)	/* default wrap-up: undivert */
		if (outfile[n] != NULL)
			getdiv(n);
					/* remove bitbucket if used  */
	if (outfile[0] != NULL) {
		(void) fclose(outfile[0]);
	}

	exit(rval);
}
Exemple #9
0
int
main(int argc, char *argv[])
{
	int c;
	int n;
	char *p;

	if (signal(SIGINT, SIG_IGN) != SIG_IGN)
		signal(SIGINT, onintr);

	init_macros();
	initspaces();
	STACKMAX = INITSTACKMAX;

	mstack = xreallocarray(NULL, STACKMAX, sizeof(stae), NULL);
	sstack = xalloc(STACKMAX, NULL);

	maxout = 0;
	outfile = NULL;
	resizedivs(MAXOUT);

	while ((c = getopt(argc, argv, "gst:d:D:U:o:I:P")) != -1)
		switch(c) {

		case 'D':               /* define something..*/
			for (p = optarg; *p; p++)
				if (*p == '=')
					break;
			if (*p)
				*p++ = EOS;
			dodefine(optarg, p);
			break;
		case 'I':
			addtoincludepath(optarg);
			break;
		case 'P':
			prefix_builtins = 1;
			break;
		case 'U':               /* undefine...       */
			macro_popdef(optarg);
			break;
		case 'g':
			mimic_gnu = 1;
			break;
		case 'd':
			set_trace_flags(optarg);
			break;
		case 's':
			synch_lines = 1;
			break;
		case 't':
			mark_traced(optarg, 1);
			break;
		case 'o':
			trace_file(optarg);
                        break;
		case '?':
			usage();
		}

        argc -= optind;
        argv += optind;

	initkwds();
	if (mimic_gnu)
		setup_builtin("format", FORMATTYPE);

	active = stdout;		/* default active output     */
	bbase[0] = bufbase;
        if (!argc) {
		sp = -1;		/* stack pointer initialized */
		fp = 0;			/* frame pointer initialized */
		set_input(infile+0, stdin, "stdin");
					/* default input (naturally) */
		macro();
	} else
		for (; argc--; ++argv) {
			p = *argv;
			if (p[0] == '-' && p[1] == EOS)
				set_input(infile, stdin, "stdin");
			else if (fopen_trypath(infile, p) == NULL)
				err(1, "%s", p);
			sp = -1;
			fp = 0;
			macro();
			release_input(infile);
		}

	if (wrapindex) {
		int i;

		ilevel = 0;		/* in case m4wrap includes.. */
		bufbase = bp = buf;	/* use the entire buffer   */
		if (mimic_gnu) {
			while (wrapindex != 0) {
				for (i = 0; i < wrapindex; i++)
					pbstr(m4wraps[i]);
				wrapindex =0;
				macro();
			}
		} else {
			for (i = 0; i < wrapindex; i++) {
				pbstr(m4wraps[i]);
				macro();
			}
		}
	}

	if (active != stdout)
		active = stdout;	/* reset output just in case */
	for (n = 1; n < maxout; n++)	/* default wrap-up: undivert */
		if (outfile[n] != NULL)
			getdiv(n);
					/* remove bitbucket if used  */
	if (outfile[0] != NULL) {
		(void) fclose(outfile[0]);
	}

	return exit_code;
}
Exemple #10
0
int
control(int counter)
/*
 * Process #control lines.  Simple commands are processed inline,
 * while complex commands have their own subroutines.
 *
 * The counter is used to force out a newline before #line, and
 * #pragma commands.  This prevents these commands from ending up at
 * the end of the previous line if cpp is invoked with the -C option.
 */
{
        register int            c;
        register char           *tp;
        register int            hash;
        char                    *ep;

        c = skipws();
        if (c == '\n' || c == EOF_CHAR)
            return (counter + 1);
        if (!isdigit(c))
            scanid(c);                  /* Get #word to token[]         */
        else {
            unget();                    /* Hack -- allow #123 as a      */
            strcpy(token, "line");      /* synonym for #line 123        */
        }
        hash = (token[1] == EOS) ? L_nogood : (token[0] + (token[2] << 1));
        switch (hash) {
        case L_assert:  tp = "assert";          break;
        case L_define:  tp = "define";          break;
        case L_elif:    tp = "elif";            break;
        case L_else:    tp = "else";            break;
        case L_endif:   tp = "endif";           break;
        case L_if:      tp = "if";              break;
        case L_ifdef:   tp = "ifdef";           break;
        case L_ifndef:  tp = "ifndef";          break;
        case L_include: tp = "include";         break;
        case L_line:    tp = "line";            break;
        case L_pragma:  tp = "pragma";          break;
        case L_undef:   tp = "undef";           break;
        case L_error:   tp = "error";           break;
#if OSL_DEBUG_LEVEL > 1
        case L_debug:   tp = "debug";           break;
        case L_nodebug: tp = "nodebug";         break;
#endif
        default:        hash = L_nogood;
        case L_nogood:  tp = "";                break;
        }
        if (!streq(tp, token))
            hash = L_nogood;
        /*
         * hash is set to a unique value corresponding to the
         * control keyword (or L_nogood if we think it's nonsense).
         */
        if (infile->fp == NULL)
            cwarn("Control line \"%s\" within macro expansion", token);
        if (!compiling) {                       /* Not compiling now    */
            switch (hash) {
            case L_if:                          /* These can't turn     */
            case L_ifdef:                       /*  compilation on, but */
            case L_ifndef:                      /*   we must nest #if's */
                if (++ifptr >= &ifstack[BLK_NEST])
                    goto if_nest_err;
                *ifptr = 0;                     /* !WAS_COMPILING       */
            case L_line:                        /* Many                 */
            /*
             * Are pragma's always processed?
             */
            case L_pragma:                      /*  options             */
            case L_include:                     /*   are uninteresting  */
            case L_define:                      /*    if we             */
            case L_undef:                       /*     aren't           */
            case L_assert:                      /*      compiling.      */
            case L_error:                       /* BP 5.3.92, #error */
dump_line:      skipnl();                       /* Ignore rest of line  */
                return (counter + 1);
            }
        }
        /*
         * Make sure that #line and #pragma are output on a fresh line.
         */
        if (counter > 0 && (hash == L_line || hash == L_pragma)) {
            PUTCHAR('\n');
            counter--;
        }
        switch (hash) {
        case L_line:
            /*
             * Parse the line to update the line number and "progname"
             * field and line number for the next input line.
             * Set wrongline to force it out later.
             */
            c = skipws();
            workp = work;                       /* Save name in work    */
            while (c != '\n' && c != EOF_CHAR) {
                save(c);
                c = get();
            }
            unget();
            save(EOS);
            /*
             * Split #line argument into <line-number> and <name>
             * We subtract 1 as we want the number of the next line.
             */
            line = atoi(work) - 1;              /* Reset line number    */
            for (tp = work; isdigit(*tp) || type[(int)*tp] == SPA; tp++)
                ;                               /* Skip over digits     */
            if (*tp != EOS) {                   /* Got a filename, so:  */
                if (*tp == '"' && (ep = strrchr(tp + 1, '"')) != NULL) {
                    tp++;                       /* Skip over left quote */
                    *ep = EOS;                  /* And ignore right one */
                }
                if (infile->progname != NULL)   /* Give up the old name */
                    free(infile->progname);     /* if it's allocated.   */
                infile->progname = savestring(tp);
            }
            wrongline = TRUE;                   /* Force output later   */
            break;

        case L_include:
            doinclude();
            break;

        case L_define:
            dodefine();
            break;

        case L_undef:
            doundef();
            break;

        case L_else:
            if (ifptr == &ifstack[0])
                goto nest_err;
            else if ((*ifptr & ELSE_SEEN) != 0)
                goto else_seen_err;
            *ifptr |= ELSE_SEEN;
            if ((*ifptr & WAS_COMPILING) != 0) {
                if (compiling || (*ifptr & TRUE_SEEN) != 0)
                    compiling = FALSE;
                else {
                    compiling = TRUE;
                }
            }
            break;

        case L_elif:
            if (ifptr == &ifstack[0])
                goto nest_err;
            else if ((*ifptr & ELSE_SEEN) != 0) {
else_seen_err:  cerror("#%s may not follow #else", token);
                goto dump_line;
            }
            if ((*ifptr & (WAS_COMPILING | TRUE_SEEN)) != WAS_COMPILING) {
                compiling = FALSE;              /* Done compiling stuff */
                goto dump_line;                 /* Skip this clause     */
            }
            doif(L_if);
            break;

        case L_if:
        case L_ifdef:
        case L_ifndef:
            if (++ifptr >= &ifstack[BLK_NEST])
if_nest_err:    cfatal("Too many nested #%s statements", token);
            *ifptr = WAS_COMPILING;
            doif(hash);
            break;

        case L_endif:
            if (ifptr == &ifstack[0]) {
nest_err:       cerror("#%s must be in an #if", token);
                goto dump_line;
            }
            if (!compiling && (*ifptr & WAS_COMPILING) != 0)
                wrongline = TRUE;
            compiling = ((*ifptr & WAS_COMPILING) != 0);
            --ifptr;
            break;

        case L_assert:
            if (eval() == 0)
                cerror("Preprocessor assertion failure", NULLST);
            break;

        case L_pragma:
            /*
             * #pragma is provided to pass "options" to later
             * passes of the compiler.  cpp doesn't have any yet.
             */
            fprintf( pCppOut, "#pragma ");
            while ((c = get()) != '\n' && c != EOF_CHAR)
                cput(c);
            unget();
            break;

#if OSL_DEBUG_LEVEL > 1
        case L_debug:
            if (debug == 0)
                dumpdef("debug set on");
            debug++;
            break;

        case L_nodebug:
            debug--;
            break;
#endif
        case L_error:                       /* BP 5.3.92, #error */
        {
            fprintf( pCppOut, "cpp: line %u, Error directive: ", line );
            while ((c = get()) != '\n' && c != EOF_CHAR)
                cput(c);
            fprintf( pCppOut, "\n" );
            exit( 1 );
            break;
        }
        default:
            /*
             * Undefined #control keyword.
             * Note: the correct behavior may be to warn and
             * pass the line to a subsequent compiler pass.
             * This would allow #asm or similar extensions.
             */
            cerror("Illegal # command \"%s\"", token);
            break;
        }
        if (hash != L_include) {
#if OLD_PREPROCESSOR
            /*
             * Ignore the rest of the #control line so you can write
             *          #if     foo
             *          #endif  foo
             */
            goto dump_line;                     /* Take common exit     */
#else
            if (skipws() != '\n') {
                cwarn("Unexpected text in #control line ignored", NULLST);
                skipnl();
            }
#endif
        }
        return (counter + 1);
}
Exemple #11
0
int
prep (void)                     /* Check for preprocessor commands */
{
    int b, c;
    char *ln;

    ln = line;

    while (*(++ln) == '#' || *ln == ' ') /* locate first directive character */
        ;
    
    if ( ! *ln)                   /* NULL directive */
        return (killine ());
    
    /* fprintf(stderr,"prep - line=%s\n",ln); */

    if (strcmp2 (ln, "if ") || strcmp2 (ln, "ifdef ") ||
                                strcmp2 (ln, "ifndef "))
    {
        /* fprintf(stderr,"prep - calling doif(%s)\n",ln); */
        doif (ln);
        return (killine ());
    }

    if (strcmp2 (ln, "else"))
    {
        doelse ();
        return (killine ());
    }

    if (strcmp2 (ln, "endif"))
    {
        doendif ();
        return (killine ());
    }
    
    if (strcmp2 (ln, "elif "))
    {
        doelif (ln);
        return (killine ());
    }
    
    if (procsw)
    {
        if (strcmp2 (ln, "define "))
        {
            c = getident (ln, 7) + 2;   /* get end of identifier */
            splittok (ln, c);   /* tokenize rest of line */
            dodefine (strlen (line), &ln[7] - line);    /* store #define info */
/*          fprintf(stderr,"PREP (after dodef): line=|%s|\n",line); */
            tstdupdef ();       /* Check for def duplication and fix */
            return (killine ());        /* Discard #define line */
        }
        
        if (strcmp2 (ln, "include "))
        {
            doinclude (&ln[8]); /* open include file */
            return (killine ());        /* Discard #include line */
        }
        
        if (strcmp2 (ln, "undef "))
        {
            /* fprintf(stderr,"prep - undef found %s\n",ln); */
            doundef (&ln[6]);   /* remove undef identifier from def table */
            /* fprintf(stderr,"prep - doundef done\n"); */
            return (killine ());        /* Discard #undef line */
        }
        
        if (strcmp2 (ln, "error "))
        {
            fprintf (stderr, "User error - %s\n", &ln[6]);      /* print error */
            return (killine ());        /* Discard #error line */
        }
        
        if (strcmp2 (ln, "asm"))
        {
            for (;;)            /* send all following lines through for assembler */
            {
                getln (0);
                if (eflag)
                    break;
                if (findstr (1, line, "#endasm"))
                    break;
                if (cflag)
                    puts ("#2");
                else
                    printf ("#pragma asm ");
                printf ("%s\n", line);
            }
            if (eflag && cflag) /* error only in Microware mode (no #endasm) */
                doerr (18, 1);
            return (killine ());
        }
        if (strcmp2 (ln, "pragma "))
        {
            dopragma (ln + 7);
            return (killine ());
        }
        if (strcmp2 (ln, "line "))
        {
            doline (ln + 5);
            return (killine ());
        }
        doerr (17, 1);          /* Illegal preprocessor directive */
        return (killine ());
    }
}
Exemple #12
0
int  main(int argc, char ** argv)
{

    EiC_init_EiC();

    /* the macro PLATFORM 
     * is passed in by the 
     * compiler
     */

    dodefine("_EiC");
    dodefine(&(xstr(PLATFORM)[1]));

    #ifdef PPCLIB
    prs("Starting EiC...\n");
    setvbuf(stdout,NULL,_IONBF,0);
    EiC_add_builtinfunc("puts",eic_puts);
    EiC_add_builtinfunc("gets",eic_gets);
    EiC_add_builtinfunc("putch",eic_putch);
    EiC_add_builtinfunc("getch",eic_getch);
    EiC_add_builtinfunc("getchq",eic_getchq);
    EiC_add_builtinfunc("in",eic_in);
    EiC_add_builtinfunc("out",eic_out);
    EiC_add_builtinfunc("load",eic_load);
    
    EiC_add_builtinfunc("printf",eic_printf);
    EiC_add_builtinfunc("sprintf",eic_sprintf);
    EiC_add_builtinfunc("scanf",eic_scanf);
    EiC_add_builtinfunc("sscanf",eic_sscanf);
    EiC_add_builtinfunc("setvbuf",eic_setvbuf);
    
      /* string .h */
    EiC_add_builtinfunc("memcpy",eic_memcpy);
    EiC_add_builtinfunc("memmove",eic_memmove);
    EiC_add_builtinfunc("strcpy",eic_strcpy);
    EiC_add_builtinfunc("strncpy",eic_strncpy);
    EiC_add_builtinfunc("strcat",eic_strcat);
    EiC_add_builtinfunc("strncat",eic_strncat);
    EiC_add_builtinfunc("memcmp",eic_memcmp);
    EiC_add_builtinfunc("strcmp",eic_strcmp);
    EiC_add_builtinfunc("strcoll",eic_strcoll);
    EiC_add_builtinfunc("strncmp",eic_strncmp);
    EiC_add_builtinfunc("strxfrm",eic_strxfrm);
    EiC_add_builtinfunc("memchr",eic_memchr);
    EiC_add_builtinfunc("strchr",eic_strchr);
    EiC_add_builtinfunc("strcspn",eic_strcspn);
    EiC_add_builtinfunc("strpbrk",eic_strpbrk);
    EiC_add_builtinfunc("strrchr",eic_strrchr);
    EiC_add_builtinfunc("strspn",eic_strspn);
    EiC_add_builtinfunc("strstr",eic_strstr);
    EiC_add_builtinfunc("strtok",eic_strtok);
    EiC_add_builtinfunc("memset",eic_memset);
    EiC_add_builtinfunc("strerror",eic_strerror);
    EiC_add_builtinfunc("strlen",eic_strlen);  
    EiC_add_builtinfunc("strrev", eic_strrev);
    
     /* stdlib.h */
    EiC_add_builtinfunc("_itoa", eic_itoa);
    EiC_add_builtinfunc("_ltoa", eic_ltoa);
    EiC_add_builtinfunc("fftoa", eic_fftoa);
    EiC_add_builtinfunc("malloc", eic_malloc);
    EiC_add_builtinfunc("calloc", eic_calloc);
    EiC_add_builtinfunc("realloc", eic_realloc);
    EiC_add_builtinfunc("free", eic_free);
    EiC_add_builtinfunc("strtod", eic_strtod);
    EiC_add_builtinfunc("strtol", eic_strtol);
    EiC_add_builtinfunc("strtoul", eic_strtoul);
    EiC_add_builtinfunc("rand", eic_rand);
    EiC_add_builtinfunc("srand", eic_srand);
    EiC_add_builtinfunc("atoi", eic_atoi);
    EiC_add_builtinfunc("atof", eic_atof);
    EiC_add_builtinfunc("atol", eic_atol);
    EiC_add_builtinfunc("abort",eic_exit);

    EiC_add_builtinfunc("eic_exit",eic_exit);

    EiC_add_builtinfunc("div",eic_div);
    EiC_add_builtinfunc("ldiv",eic_ldiv);
    EiC_add_builtinfunc("acos",eic_acos);
    EiC_add_builtinfunc("asin",eic_asin);
    EiC_add_builtinfunc("atan",eic_atan);
    EiC_add_builtinfunc("atan2",eic_atan2);
    EiC_add_builtinfunc("cos",eic_cos);
    EiC_add_builtinfunc("sin",eic_sin);
    EiC_add_builtinfunc("tan",eic_tan);
    EiC_add_builtinfunc("cosh",eic_cosh);
    EiC_add_builtinfunc("sinh",eic_sinh);
    EiC_add_builtinfunc("tanh",eic_tanh);
    EiC_add_builtinfunc("exp",eic_exp);
    EiC_add_builtinfunc("frexp",eic_frexp);
    EiC_add_builtinfunc("ldexp",eic_ldexp);
    EiC_add_builtinfunc("log",eic_log);
    EiC_add_builtinfunc("log10",eic_log10);
    EiC_add_builtinfunc("modf",eic_modf);
    EiC_add_builtinfunc("pow",eic_pow);
    EiC_add_builtinfunc("sqrt",eic_sqrt);
    EiC_add_builtinfunc("ceil",eic_ceil);
    EiC_add_builtinfunc("fabs",eic_fabs);
    EiC_add_builtinfunc("floor",eic_floor);
    EiC_add_builtinfunc("fmod",eic_fmod);


    startstr=loadstring; /* load defines */
    
    /* strcat(startstr,"typedef struct {void *p, *sp, *ep;} ptr_t;\n");
    strcat(startstr,"typedef struct { ptr_t _ptr; int _cnt; ptr_t _base;\\\n");
    strcat(startstr,"unsigned short _flag; short _fd; unsigned long _pid;\\\n");
    strcat(startstr,"unsigned  _bsize; ptr_t _tmpnam; char _sbuf[4];\\\n");
    strcat(startstr,"unsigned _entry; }FILE;\n");

    strcat(startstr,"int fgetc(FILE * fp);\n");
    strcat(startstr,"int fputc(int c, FILE * fp);\n");
    strcat(startstr,"char * fgets(char *s, int n, FILE *fp);\n");
    strcat(startstr,"int fputs(const char *s, FILE *fp);\n");  */

    #endif
    EiC_startEiC(argc, argv);
    return 0;
}
Exemple #13
0
/**
 * control - 处理预处理控制指令(头文件包含指令,行控制指令,条件编译指令)
 * @trp: 一行源程序的Token
 * 返回值:无
 */
void control(Tokenrow *trp) {
	Nlist *np;
	Token *tp;

	tp = trp->tp; /* 获得Tokenrow中的当前Token(指向预处理控制指令关键字) */
	if (tp->type!=NAME) { /* 如果当前Token不是标识符 */
		if (tp->type==NUMBER) /* 如果当前Token是数字 */
			goto kline; /* 跳转,处理行控制指令 */
		if (tp->type != NL) /* 如果该Token既不是标识符,也不是数字 */
			error(ERROR, "Unidentifiable control line"); /* 则,打印信息`无法识别的控制指令行' */
		return; /* 该行处理完毕,函数返回(该行为空行,无控制信息,else empty line) */
	}
	/* 如果当前Token是标识符但标识符不在标识符hash表中 或 标识符在hash表中但不是关键字且不能略过(TODO:啥是略过?) */
	if ((np = lookup(tp, 0))==NULL || (np->flag&ISKW)==0 && !skipping) {
		error(WARNING, "Unknown preprocessor control %t", tp); /* 打印信息,无法识别的预处理控制指令 */
		return; /* 该行处理完毕 */
	}
	if (skipping) { /* TODO: 啥是skipping? */
		if ((np->flag&ISKW)==0) /* 如果np不是关键字 */
			return; /* 函数返回 */
		switch (np->val) {
		case KENDIF:
			if (--ifdepth<skipping)
				skipping = 0;
			--cursource->ifdepth;
			setempty(trp);
			return;

		case KIFDEF:
		case KIFNDEF:
		case KIF:
			if (++ifdepth >= NIF)
				error(FATAL, "#if too deeply nested");
			++cursource->ifdepth;
			return;

		case KELIF:
		case KELSE:
			if (ifdepth<=skipping)
				break;
			return;

		default:
			return;
		}
	}
	switch (np->val) {
	case KDEFINE: /* #define,定义宏 */
		dodefine(trp); /* 定义宏 */
		break;

	case KUNDEF: /* #undef */
		tp += 1; /* tp指向宏名 */
		if (tp->type!=NAME || trp->lp - trp->bp != 4) { /* 如果tp不是标识符类型 或者 lp-bp!=4 (lp和bp之间有4个Token) */
			error(ERROR, "Syntax error in #undef"); /* 打印错误信息 */
			break;
		}
		if ((np = lookup(tp, 0)) != NULL) /* 如果在hash表中找到了tp所指向的宏名 */
			np->flag &= ~ISDEFINED; /* 清零ISDEFINED标志位 */
		break;

	case KPRAGMA: /* #pragma */
		return;

	case KIFDEF: /* #ifdef */
	case KIFNDEF: /* #ifndef */
	case KIF: /* #if */
		if (++ifdepth >= NIF) /* 全局条件编译语句的嵌套深度值加1 */
			error(FATAL, "#if too deeply nested"); /* 如果嵌套深度值大于NIF,则打印错误信息 `#if中嵌入太深' */
		++cursource->ifdepth; /* 当前输入源的条件编译语句的嵌套深度值加1 */
		ifsatisfied[ifdepth] = 0; /* 设定条件编译语句的嵌套深度值对应的if语句还未被满足 */
		if (eval(trp, np->val))
			ifsatisfied[ifdepth] = 1;
		else
			skipping = ifdepth;
		break;

	case KELIF: /* #elif */
		if (ifdepth==0) {
			error(ERROR, "#elif with no #if");
			return;
		}
		if (ifsatisfied[ifdepth]==2)
			error(ERROR, "#elif after #else");
		if (eval(trp, np->val)) {
			if (ifsatisfied[ifdepth])
				skipping = ifdepth;
			else {
				skipping = 0;
				ifsatisfied[ifdepth] = 1;
			}
		} else
			skipping = ifdepth;
		break;

	case KELSE: /* #else */
		if (ifdepth==0 || cursource->ifdepth==0) {
			error(ERROR, "#else with no #if");
			return;
		}
		if (ifsatisfied[ifdepth]==2)
			error(ERROR, "#else after #else");
		if (trp->lp - trp->bp != 3)
			error(ERROR, "Syntax error in #else");
		skipping = ifsatisfied[ifdepth]? ifdepth: 0;
		ifsatisfied[ifdepth] = 2;
		break;

	case KENDIF: /* #endif */
		if (ifdepth==0 || cursource->ifdepth==0) {
			error(ERROR, "#endif with no #if");
			return;
		}
		--ifdepth;
		--cursource->ifdepth;
		if (trp->lp - trp->bp != 3)
			error(WARNING, "Syntax error in #endif");
		break;

	case KERROR: /* #error */
		trp->tp = tp+1;
		error(WARNING, "#error directive: %r", trp);
		break;

	case KLINE: /* #line */
		trp->tp = tp+1;
		expandrow(trp, "<line>");
		tp = trp->bp+2;
	kline: /* 行控制信息处理(line control)*/
		if (tp+1>=trp->lp || tp->type!=NUMBER || tp+3<trp->lp
		 || (tp+3==trp->lp && ((tp+1)->type!=STRING)||*(tp+1)->t=='L')) { /* 如果行控制语法有误 */
			/* 上面的if判断中共有5种语法错误检查:
			 * 1. 如果只有`# 123\n'
			 * 2. 如果当前token不是数字类型
			 * 3. 如果有类似`# 123 "file.c" 2 3'的行,那么这种行不被lcc的预处理程序支持。TODO:lcc不支持行控制中的flag语法.
			 * 4. 如果在`# linenum filename'中,filename不是字符串
			 * 5. 如果filename是宽字符字符串
			 */
			error(ERROR, "Syntax error in #line"); /* 打印错误信息 */
			return; /* 该函数返回 */
		}
		cursource->line = atol((char*)tp->t)-1; /* 更新当前输入源的行号信息 */
		if (cursource->line<0 || cursource->line>=32768) /* 如果转化后的行号小于0或者行号大于32768 */
			error(WARNING, "#line specifies number out of range"); /* 打印错误信息 */
		tp = tp+1; /* 指针移动到filename位置 */
		if (tp+1<trp->lp) /* 如果filename存在(因为filename后通常紧跟一个换行符token) */
			cursource->filename=(char*)newstring(tp->t+1,tp->len-2,0); /* 保存输入源的文件名 */
		return; /* 该行处理完毕,函数返回 */

	case KDEFINED: /* #defined */
		error(ERROR, "Bad syntax for control line"); /* 打印语法错误提示 */
		break;

	case KINCLUDE: /* #include */
		doinclude(trp);
		trp->lp = trp->bp;
		return;

	case KEVAL: /* #eval */
		eval(trp, np->val);
		break;

	default: /* # other */
		error(ERROR, "Preprocessor control `%t' not yet implemented", tp); /* 未实现的预处理控制指令 */
		break;
	}
	setempty(trp); /* 置空Tokenrow */
	return;
}
Exemple #14
0
ReturnCode control( struct Global *global,
    int *counter )  /* Pending newline counter */
{
    /*
     * Process #control lines.  Simple commands are processed inline,
     * while complex commands have their own subroutines.
     *
     * The counter is used to force out a newline before #line, and
     * #pragma commands.  This prevents these commands from ending up at
     * the end of the previous line if cpp is invoked with the -C option.
     */

    int c;
    char *tp;
    int hash;
    char *ep;
    ReturnCode ret;

    c = skipws( global );

    if( c == '\n' || c == EOF_CHAR )
        {
        (*counter)++;

        return(FPP_OK);
        }

    if( !isdigit(c) )
        scanid( global, c );                  /* Get #word to tokenbuf        */
    else
        {
        unget( global );                    /* Hack -- allow #123 as a      */

        strcpy( global->tokenbuf, "line" );   /* synonym for #line 123        */
        }

    hash = (global->tokenbuf[1] == EOS) ? L_nogood : (global->tokenbuf[0] + (global->tokenbuf[2] << 1));

    switch( hash )
        {
        case L_assert:
            tp = "assert";
            break;
        case L_define:
            tp = "define";
            break;
        case L_elif:
            tp = "elif";
            break;
        case L_else:
            tp = "else";
            break;
        case L_endif:
            tp = "endif";
            break;
        case L_error:
            tp = "error";
            break;
        case L_if:
            tp = "if";
            break;
        case L_ifdef:
            tp = "ifdef";
            break;
        case L_ifndef:
            tp = "ifndef";
            break;
        case L_include:
            tp = "include";
            break;
        case L_line:
            tp = "line";
            break;
        case L_pragma:
            tp = "pragma";
            break;
        case L_undef:
            tp = "undef";
            break;
        default:
            hash = L_nogood;
        case L_nogood:
            tp = "";
            break;
        }

    if( !streq( tp, global->tokenbuf ) )
        hash = L_nogood;

    /*
     * hash is set to a unique value corresponding to the
     * control keyword (or L_nogood if we think it's nonsense).
     */
    if( global->infile->fp == NULL )
        cwarn( global, WARN_CONTROL_LINE_IN_MACRO, global->tokenbuf );

    if( !compiling )
        {                       /* Not compiling now    */
        switch( hash )
            {
            case L_if:              /* These can't turn     */
            case L_ifdef:           /*  compilation on, but */
            case L_ifndef:          /*   we must nest #if's */
                if( ++global->ifptr >= &global->ifstack[BLK_NEST] )
                    {
                    cfatal( global, FATAL_TOO_MANY_NESTINGS, global->tokenbuf );

                    return( FPP_TOO_MANY_NESTED_STATEMENTS );
                    }

                *global->ifptr = 0;       /* !WAS_COMPILING   */

            case L_line:            /* Many         */
                /*
                 * Are pragma's always processed?
                 */
            case L_pragma:          /*  options     */
            case L_include:         /*   are uninteresting  */
            case L_define:          /*    if we     */
            case L_undef:           /*     aren't           */
            case L_assert:          /*  compiling.  */
            case L_error:
                dump_line( global, counter );       /* Ignore rest of line  */
                return(FPP_OK);
            }
        }
    /*
     * Make sure that #line and #pragma are output on a fresh line.
     */
    if( *counter > 0 && (hash == L_line || hash == L_pragma) )
        {
        Putchar( global, '\n' );

        (*counter)--;
        }

    switch( hash )
        {
        case L_line:
            /*
             * Parse the line to update the line number and "progname"
             * field and line number for the next input line.
             * Set wrongline to force it out later.
             */
            c = skipws( global );

            global->workp = global->work;       /* Save name in work    */

            while( c != '\n' && c != EOF_CHAR )
                {
                if( (ret = save( global, c )) )
                    return(ret);

                c = get( global );
                }

            unget( global );

            if( (ret = save( global, EOS )) )
                return(ret);

            /*
             * Split #line argument into <line-number> and <name>
             * We subtract 1 as we want the number of the next line.
             */
            global->line = atoi(global->work) - 1;     /* Reset line number    */

            for( tp = global->work; isdigit(*tp) || type[(unsigned)*tp] == SPA; tp++)
                ;             /* Skip over digits */

            if( *tp != EOS )
                {
                /* Got a filename, so:  */

                if( *tp == '"' && (ep = strrchr(tp + 1, '"')) != NULL )
                    {
                    tp++;           /* Skip over left quote */

                    *ep = EOS;      /* And ignore right one */
                    }

                if( global->infile->progname != NULL )
                    /* Give up the old name if it's allocated.   */
                    free( global->infile->progname );

                global->infile->progname = savestring( global, tp );
                }

            global->wrongline = TRUE;           /* Force output later   */
            break;

        case L_include:
            ret = doinclude( global );
            if( ret )
                return(ret);
            break;

        case L_define:
            ret = dodefine( global );
            if( ret )
                return(ret);
            break;

        case L_undef:
            doundef( global );
            break;

        case L_else:
            if( global->ifptr == &global->ifstack[0] )
                {
                cerror( global, ERROR_STRING_MUST_BE_IF, global->tokenbuf );

                dump_line( global, counter );

                return( FPP_OK );
                }
            else if( (*global->ifptr & ELSE_SEEN) != 0 )
                {
                cerror( global, ERROR_STRING_MAY_NOT_FOLLOW_ELSE, global->tokenbuf );

                dump_line( global, counter );

                return( FPP_OK );
                }

            *global->ifptr |= ELSE_SEEN;

            if( (*global->ifptr & WAS_COMPILING) != 0 )
                {
                if( compiling || (*global->ifptr & TRUE_SEEN) != 0 )
                    compiling = FALSE;
                else
                    {
                    compiling = TRUE;
                    }
                }
            break;

        case L_elif:
            if( global->ifptr == &global->ifstack[0] )
                {
                cerror( global, ERROR_STRING_MUST_BE_IF, global->tokenbuf );

                dump_line( global, counter );

                return( FPP_OK );
                }
            else if( (*global->ifptr & ELSE_SEEN) != 0 )
                {
                cerror( global, ERROR_STRING_MAY_NOT_FOLLOW_ELSE, global->tokenbuf );

                dump_line( global, counter );

                return( FPP_OK );
                }

            if( (*global->ifptr & (WAS_COMPILING | TRUE_SEEN)) != WAS_COMPILING )
                {
                compiling = FALSE;        /* Done compiling stuff */

                dump_line( global, counter );   /* Skip this clause */

                return( FPP_OK );
                }

            ret = doif( global, L_if );

            if( ret )
                return(ret);

            break;

        case L_error:
            cerror(global, ERROR_ERROR);
            break;

        case L_if:
        case L_ifdef:
        case L_ifndef:
            if( ++global->ifptr < &global->ifstack[BLK_NEST] )
                {
                *global->ifptr = WAS_COMPILING;

                ret = doif( global, hash );

                if( ret )
                    return(ret);

                break;
                }

            cfatal( global, FATAL_TOO_MANY_NESTINGS, global->tokenbuf );

            return( FPP_TOO_MANY_NESTED_STATEMENTS );

        case L_endif:
            if( global->ifptr == &global->ifstack[0] )
                {
                cerror( global, ERROR_STRING_MUST_BE_IF, global->tokenbuf );

                dump_line( global, counter );

                return(FPP_OK);
                }

            if( !compiling && (*global->ifptr & WAS_COMPILING) != 0 )
                global->wrongline = TRUE;

            compiling = ((*global->ifptr & WAS_COMPILING) != 0);

            --global->ifptr;

            break;

        case L_assert:
            {
            int result;

            ret = eval( global, &result );

            if(ret)
                return(ret);

            if( result == 0 )
                cerror( global, ERROR_PREPROC_FAILURE );
            }
            break;

        case L_pragma:
            /*
             * #pragma is provided to pass "options" to later
             * passes of the compiler.  cpp doesn't have any yet.
             */
            Putstring( global, "#pragma " );

            while( (c = get( global ) ) != '\n' && c != EOF_CHAR )
                Putchar( global, c );

            unget( global );

            Putchar( global, '\n' );

            break;

        default:
            /*
             * Undefined #control keyword.
             * Note: the correct behavior may be to warn and
             * pass the line to a subsequent compiler pass.
             * This would allow #asm or similar extensions.
             */
            if( global->warnillegalcpp )
                cwarn( global, WARN_ILLEGAL_COMMAND, global->tokenbuf );

            Putchar( global, '#' );
            Putstring( global, global->tokenbuf );
            Putchar( global, ' ' );

            while( (c = get( global ) ) != '\n' && c != EOF_CHAR )
                Putchar( global, c );

            unget( global );

            Putchar( global, '\n' );

            break;
        }

    if( hash != L_include )
        {
        #if OLD_PREPROCESSOR
        /*
         * Ignore the rest of the #control line so you can write
         *      #if foo
         *      #endif  foo
         */
        dump_line( global, counter );         /* Take common exit */

        return( FPP_OK );
        #else
          if (skipws(global) != '\n')
            {
            cwarn( global, WARN_UNEXPECTED_TEXT_IGNORED );

            skipnl( global );
            }
        #endif
        }

    (*counter)++;

    return( FPP_OK );
}
/*
 ****************************************************************
 *	Analisa uma Linha de Controle				*
 ****************************************************************
 */
void
directive (void)
{
	SYMTB		*sp, **link_place;
	MAJOR		maj;
	char		*cp, c;

	/*
	 *	Convenção da STACK:
	 *		'U': é indefinido, e nunca foi definido
	 *		'N': é indefinido, mas já foi definido
	 *		'D': é definido
	 */
	if ((maj = scan ()) == EOL)
	{
		skipline ();
		return;
	}

	if (maj != ID || !TYPE (sp, token.l_name, S_KEYWORD))
	{
		err_msg
		(	ERRO, TOKMARK,
			"Esperava uma diretiva de préprocessamento"
		);
		skipline ();
		return;
	}

	switch (sp->s_index)
	{
	    case DEFINE:
		if (falselevel == 0)
			dodefine ();
		break;

	    case UNDEF:
		if (falselevel == 0)
			doundef ();
		break;

	    case INCLUDE:
		if (falselevel == 0)
		{
			doinclude ();
			return;
		}
		break;

	    case IF:
		if (falselevel == 0)
		{
			if (expression ())
			{
				*stackp++ = 'D';
				putoutnl ();
			}
			else
			{
				*stackp++ = 'U';
				falselevel++;
			}
	
			/*
			 *	A análise de expressões já processou
			 *	o fim de linha.	Não devemos avançar mais.
			 */
			return;
		}
		else
		{
			*stackp++ = 'U';
			falselevel++;
		}
		break;

	    case IFDEF:
		if (scan () != ID)
		{
			err_msg (ERRO, TOKMARK, "Esperava um identificador");
			*stackp++ = 'D';
			break;
		}

		if (TYPE (sp, token.l_name, S_MACRO))
		{
			*stackp++ = 'D';
			if (falselevel == 0)
				putoutnl ();
		}
		else
		{
			*stackp++ = 'U';
			falselevel++;
		}

		break;

	    case IFNDEF:
		if (scan () != ID)
		{
			err_msg (ERRO, TOKMARK, "Esperava um identificador");
			*stackp++ = 'D';
			break;
		}

		if (!TYPE (sp, token.l_name, S_MACRO))
		{
			*stackp++ = 'D';
			if (falselevel == 0)
				putoutnl ();
		}
		else
		{
			*stackp++ = 'U';
			falselevel++;
		}

		break;

	    case ELIF:
		if (stackp <= stack)
		{
			err_msg
			(	ERRO, TOKMARK,
				"\"elif\" sem prévio \"if\" ou \"ifdef\""
			);
			break;
		}

		switch (stackp[-1])
		{
		    case 'U':
			if (falselevel == 1)
			{
				if (expression ())
				{
					stackp[-1] = 'D';
					falselevel--;	/* == 0 */
					putlineno (lineno);
				}
				else
				{
					/* Nada faz */
				}

				return;
			}
			else
			{
				/* Nada faz */
			}
			break;

		    case 'N':
			/* Nada faz */
			break;

		    case 'D':
			stackp[-1] = 'N';
			falselevel++;
			putoutnl ();
			break;

		    default:
			err_msg
			(	ERRO, TOKMARK,
				"Estado inválido da STACK: '%c'",
				stackp[-1]
			);
		}

		break;

	    case ELSE:
		if (stackp <= stack)
		{
			err_msg
			(	ERRO, TOKMARK,
				"\"else\" sem prévio \"if\" ou \"ifdef\""
			);
			break;
		}

		switch (stackp[-1])
		{
		    case 'U':
			stackp[-1] = 'D';
			if (--falselevel == 0)
				putlineno (lineno + 1);
			break;

		    case 'N':
			/* Nada faz */
			break;

		    case 'D':
			stackp[-1] = 'U';
			falselevel++;
			break;

		    default:
			err_msg
			(	ERRO, TOKMARK,
				"Estado inválido da STACK: '%c'",
				stackp[-1]
			);
		}

		break;

	    case ENDIF:
		if (stackp <= stack)
		{
			err_msg
			(	ERRO, TOKMARK,
				"\"endif\" sem prévio \"if\" ou \"ifdef\""
			);
			break;
		}

		switch (*--stackp)
		{
		    case 'U':
		    case 'N':
			if (--falselevel == 0)
				putlineno (lineno + 1);
			break;

		    case 'D':
			putoutnl ();
			break;

		    default:
			err_msg
			(	ERRO, TOKMARK,
				"Estado inválido da STACK: '%c'",
				stackp[0]
			);
		}

		break;

	    case ERROR:
		if (falselevel == 0)
		{
			const char	*msg;

			for (cp = (char *)nextp; CATEG (cp) == SEPAR; cp++)
				/* vazio */;

			msg = cp;

			while (*cp != '\n' && (*cp != '/' || cp[1] != '*'))
				cp++;

			c = *cp; *cp = '\0';

			err_msg (ERRO, NOMARK, msg);

			*cp = c; nextp = msg; putoutnl ();
		}

		break;

	    case PRAGMA:
		if (falselevel == 0)
			dopragma ();
		break;

	    case LINE:
		if (falselevel == 0)
		{
			if (scan () != ICTE)
			{
				err_msg
				(
					ERRO,
					TOKMARK,
					"Esperava uma constante"
				);
			};

			lineno = token.l_ival - 1;

			if (scan () == STR)
			{
				srcname = token.l_begin + 1;
				((char *)token.l_end)[0] = '\0';
				scan ();
			}

			return;
		}
		break;

	    default:
		err_msg
		(	COMP, TOKMARK,
			"Erro no s_index para diretivas"
		);

	}	/* end switch (sp->s_index) */

	skipline ();

}	/* end directive */
Exemple #16
0
int
assemble(char *file)
{
	char *ofile, incfile[20], *p;
	int i, of;

	ofile = alloc(strlen(file)+3); // +3 for .x\0 (x=thechar)
	strcpy(ofile, file);
	p = utfrrune(ofile, '/');
	if(p) {
		include[0] = ofile;
		*p++ = 0;
	} else
		p = ofile;
	if(outfile == 0) {
		outfile = p;
		if(outfile){
			p = utfrrune(outfile, '.');
			if(p)
				if(p[1] == 's' && p[2] == 0)
					p[0] = 0;
			p = utfrune(outfile, 0);
			p[0] = '.';
			p[1] = thechar;
			p[2] = 0;
		} else
			outfile = "/dev/null";
	}
	p = getenv("INCLUDE");
	if(p) {
		setinclude(p);
	} else {
		if(systemtype(Plan9)) {
			sprint(incfile,"/%s/include", thestring);
			setinclude(strdup(incfile));
		}
	}

	of = create(outfile, OWRITE, 0664);
	if(of < 0) {
		yyerror("%ca: cannot create %s", thechar, outfile);
		errorexit();
	}
	Binit(&obuf, of, OWRITE);

	pass = 1;
	pinit(file);

	Bprint(&obuf, "%s\n", thestring);

	for(i=0; i<nDlist; i++)
		dodefine(Dlist[i]);
	yyparse();
	if(nerrors) {
		cclean();
		return nerrors;
	}

	Bprint(&obuf, "\n!\n");

	pass = 2;
	outhist();
	pinit(file);
	for(i=0; i<nDlist; i++)
		dodefine(Dlist[i]);
	yyparse();
	cclean();
	return nerrors;
}
Exemple #17
0
/*
 * expand_builtin - evaluate built-in macros.
 */
void
expand_builtin(const char *argv[], int argc, int td)
{
	int c, n;
	int ac;
	static int sysval = 0;

#ifdef DEBUG
	printf("argc = %d\n", argc);
	for (n = 0; n < argc; n++)
		printf("argv[%d] = %s\n", n, argv[n]);
	fflush(stdout);
#endif

 /*
  * if argc == 3 and argv[2] is null, then we
  * have macro-or-builtin() type call. We adjust
  * argc to avoid further checking..
  */
 /* we keep the initial value for those built-ins that differentiate
  * between builtin() and builtin.
  */
	ac = argc;

	if (argc == 3 && !*(argv[2]) && !mimic_gnu)
		argc--;

	switch (td & TYPEMASK) {

	case DEFITYPE:
		if (argc > 2)
			dodefine(argv[2], (argc > 3) ? argv[3] : null);
		break;

	case PUSDTYPE:
		if (argc > 2)
			dopushdef(argv[2], (argc > 3) ? argv[3] : null);
		break;

	case DUMPTYPE:
		dodump(argv, argc);
		break;

	case TRACEONTYPE:
		dotrace(argv, argc, 1);
		break;

	case TRACEOFFTYPE:
		dotrace(argv, argc, 0);
		break;

	case EXPRTYPE:
	/*
	 * doexpr - evaluate arithmetic
	 * expression
	 */
	{
		int base = 10;
		int maxdigits = 0;
		const char *errstr;

		if (argc > 3) {
			base = strtonum(argv[3], 2, 36, &errstr);
			if (errstr) {
				m4errx(1, "expr: base %s invalid.", argv[3]);
			}
		}
		if (argc > 4) {
			maxdigits = strtonum(argv[4], 0, INT_MAX, &errstr);
			if (errstr) {
				m4errx(1, "expr: maxdigits %s invalid.", argv[4]);
			}
		}
		if (argc > 2)
			pbnumbase(expr(argv[2]), base, maxdigits);
		break;
	}

	case IFELTYPE:
		if (argc > 4)
			doifelse(argv, argc);
		break;

	case IFDFTYPE:
	/*
	 * doifdef - select one of two
	 * alternatives based on the existence of
	 * another definition
	 */
		if (argc > 3) {
			if (lookup_macro_definition(argv[2]) != NULL)
				pbstr(argv[3]);
			else if (argc > 4)
				pbstr(argv[4]);
		}
		break;

	case LENGTYPE:
	/*
	 * dolen - find the length of the
	 * argument
	 */
		pbnum((argc > 2) ? strlen(argv[2]) : 0);
		break;

	case INCRTYPE:
	/*
	 * doincr - increment the value of the
	 * argument
	 */
		if (argc > 2)
			pbnum(atoi(argv[2]) + 1);
		break;

	case DECRTYPE:
	/*
	 * dodecr - decrement the value of the
	 * argument
	 */
		if (argc > 2)
			pbnum(atoi(argv[2]) - 1);
		break;

	case SYSCTYPE:
	/*
	 * dosys - execute system command
	 */
		if (argc > 2) {
			fflush(stdout);
			sysval = system(argv[2]);
		}
		break;

	case SYSVTYPE:
	/*
	 * dosysval - return value of the last
	 * system call.
	 *
	 */
		pbnum(sysval);
		break;

	case ESYSCMDTYPE:
		if (argc > 2)
			doesyscmd(argv[2]);
		break;
	case INCLTYPE:
		if (argc > 2)
			if (!doincl(argv[2])) {
				if (mimic_gnu) {
					warn("%s at line %lu: include(%s)",
					    CURRENT_NAME, CURRENT_LINE, argv[2]);
					exit_code = 1;
				} else
					err(1, "%s at line %lu: include(%s)",
					    CURRENT_NAME, CURRENT_LINE, argv[2]);
			}
		break;

	case SINCTYPE:
		if (argc > 2)
			(void) doincl(argv[2]);
		break;
#ifdef EXTENDED
	case PASTTYPE:
		if (argc > 2)
			if (!dopaste(argv[2]))
				err(1, "%s at line %lu: paste(%s)", 
				    CURRENT_NAME, CURRENT_LINE, argv[2]);
		break;

	case SPASTYPE:
		if (argc > 2)
			(void) dopaste(argv[2]);
		break;
	case FORMATTYPE:
		doformat(argv, argc);
		break;
#endif
	case CHNQTYPE:
		dochq(argv, ac);
		break;

	case CHNCTYPE:
		dochc(argv, argc);
		break;

	case SUBSTYPE:
	/*
	 * dosub - select substring
	 *
	 */
		if (argc > 3)
			dosub(argv, argc);
		break;

	case SHIFTYPE:
	/*
	 * doshift - push back all arguments
	 * except the first one (i.e. skip
	 * argv[2])
	 */
		if (argc > 3) {
			for (n = argc - 1; n > 3; n--) {
				pbstr(rquote);
				pbstr(argv[n]);
				pbstr(lquote);
				pushback(COMMA);
			}
			pbstr(rquote);
			pbstr(argv[3]);
			pbstr(lquote);
		}
		break;

	case DIVRTYPE:
		if (argc > 2 && (n = atoi(argv[2])) != 0)
			dodiv(n);
		else {
			active = stdout;
			oindex = 0;
		}
		break;

	case UNDVTYPE:
		doundiv(argv, argc);
		break;

	case DIVNTYPE:
	/*
	 * dodivnum - return the number of
	 * current output diversion
	 */
		pbnum(oindex);
		break;

	case UNDFTYPE:
	/*
	 * doundefine - undefine a previously
	 * defined macro(s) or m4 keyword(s).
	 */
		if (argc > 2)
			for (n = 2; n < argc; n++)
				macro_undefine(argv[n]);
		break;

	case POPDTYPE:
	/*
	 * dopopdef - remove the topmost
	 * definitions of macro(s) or m4
	 * keyword(s).
	 */
		if (argc > 2)
			for (n = 2; n < argc; n++)
				macro_popdef(argv[n]);
		break;

	case MKTMTYPE:
	/*
	 * dotemp - create a temporary file
	 */
		if (argc > 2) {
			int fd;
			char *temp;

			temp = xstrdup(argv[2]);

			fd = mkstemp(temp);
			if (fd == -1)
				err(1,
	    "%s at line %lu: couldn't make temp file %s",
	    CURRENT_NAME, CURRENT_LINE, argv[2]);
			close(fd);
			pbstr(temp);
			free(temp);
		}
		break;

	case TRNLTYPE:
	/*
	 * dotranslit - replace all characters in
	 * the source string that appears in the
	 * "from" string with the corresponding
	 * characters in the "to" string.
	 */
		if (argc > 3) {
			char *temp;

			temp = xalloc(strlen(argv[2])+1, NULL);
			if (argc > 4)
				map(temp, argv[2], argv[3], argv[4]);
			else
				map(temp, argv[2], argv[3], null);
			pbstr(temp);
			free(temp);
		} else if (argc > 2)
			pbstr(argv[2]);
		break;

	case INDXTYPE:
	/*
	 * doindex - find the index of the second
	 * argument string in the first argument
	 * string. -1 if not present.
	 */
		pbnum((argc > 3) ? indx(argv[2], argv[3]) : -1);
		break;

	case ERRPTYPE:
	/*
	 * doerrp - print the arguments to stderr
	 * file
	 */
		if (argc > 2) {
			for (n = 2; n < argc; n++)
				fprintf(stderr, "%s ", argv[n]);
			fprintf(stderr, "\n");
		}
		break;

	case DNLNTYPE:
	/*
	 * dodnl - eat-up-to and including
	 * newline
	 */
		while ((c = gpbc()) != '\n' && c != EOF)
			;
		break;

	case M4WRTYPE:
	/*
	 * dom4wrap - set up for
	 * wrap-up/wind-down activity
	 */
		if (argc > 2)
			dom4wrap(argv[2]);
		break;

	case EXITTYPE:
	/*
	 * doexit - immediate exit from m4.
	 */
		killdiv();
		exit((argc > 2) ? atoi(argv[2]) : 0);
		break;

	case DEFNTYPE:
		if (argc > 2)
			for (n = 2; n < argc; n++)
				dodefn(argv[n]);
		break;

	case INDIRTYPE:	/* Indirect call */
		if (argc > 2)
			doindir(argv, argc);
		break;

	case BUILTINTYPE: /* Builtins only */
		if (argc > 2)
			dobuiltin(argv, argc);
		break;

	case PATSTYPE:
		if (argc > 2)
			dopatsubst(argv, argc);
		break;
	case REGEXPTYPE:
		if (argc > 2)
			doregexp(argv, argc);
		break;
	case LINETYPE:
		doprintlineno(infile+ilevel);
		break;
	case FILENAMETYPE:
		doprintfilename(infile+ilevel);
		break;
	case SELFTYPE:
		pbstr(rquote);
		pbstr(argv[1]);
		pbstr(lquote);
		break;
	default:
		m4errx(1, "eval: major botch.");
		break;
	}
}
Exemple #18
0
void
main(int argc, char *argv[])
{
	char ofile[100], incfile[20], *p;
	int nout, nproc, status, i, c, of;

	thechar = '7';			/* of 9 */
	thestring = "alpha";
	memset(debug, 0, sizeof(debug));
	cinit();
	outfile = 0;
	include[ninclude++] = ".";
	ARGBEGIN {
	default:
		c = ARGC();
		if(c >= 0 || c < sizeof(debug))
			debug[c] = 1;
		break;

	case 'o':
		outfile = ARGF();
		break;

	case 'D':
		p = ARGF();
		if(p)
			Dlist[nDlist++] = p;
		break;

	case 'I':
		p = ARGF();
		if(p)
			include[ninclude++] = p;
		break;
	} ARGEND
	if(*argv == 0) {
		print("usage: %ca [-options] file.s\n", thechar);
		errorexit();
	}
	nproc = 3;
	if(p = getenv("NPROC"))
		nproc = atol(p);
	if(argc > 1) {
		c = 0;
		nout = 0;
		for(;;) {
			while(nout < nproc && argc > 0) {
				i = fork();
				if(i < 0) {
					i = mywait(&status);
					if(i < 0)
						errorexit();
					if(status)
						c++;
					nout--;
					continue;
				}
				if(i == 0) {
					print("%s:\n", *argv);
					goto child;
				}
				nout++;
				argc--;
				argv++;
			}
			i = mywait(&status);
			if(i < 0) {
				if(c)
					errorexit();
				exits(0);
			}
			if(status)
				c++;
			nout--;
		}
	}

child:
	strecpy(ofile, ofile+sizeof ofile, *argv);
	if(p = strrchr(ofile, '/')) {
		include[0] = ofile;
		*p++ = 0;
	} else
		p = ofile;
	if(outfile == 0) {
		outfile = p;
		if(p = strrchr(outfile, '.'))
			if(p[1] == 's' && p[2] == 0)
				p[0] = 0;
		p = strrchr(outfile, 0);
		p[0] = '.';
		p[1] = thechar;
		p[2] = 0;
	}
	if(0) {
		strcpy(incfile, "/usr/%include");
		p = strrchr(incfile, '%');
		if(p)
			*p = thechar;
	} else {
		strcpy(incfile, "/");
		strcat(incfile, thestring);
		strcat(incfile, "/include");
	}
	include[ninclude++] = incfile;
	if(p = getenv("INCLUDE"))
		include[ninclude-1] = p;	/* */
	of = mycreat(outfile, 0664);
	if(of < 0) {
		yyerror("%ca: cannot create %s", thechar, outfile);
		errorexit();
	}
	Binit(&obuf, of, OWRITE);

	pass = 1;
	pinit(*argv);
	for(i=0; i<nDlist; i++)
		dodefine(Dlist[i]);
	yyparse();
	if(nerrors) {
		cclean();
		errorexit();
	}

	pass = 2;
	outhist();
	pinit(*argv);
	for(i=0; i<nDlist; i++)
		dodefine(Dlist[i]);
	yyparse();
	cclean();
	if(nerrors)
		errorexit();
	exits(0);
}