static void transformline(register int lineno) { register int *dstp; register int *srcp; int x; int endx; x = twin->_minchng[lineno]; endx = twin->_maxchng[lineno]; dstp = curscr->_line[lineno] + x; srcp = twin->_line[lineno] + x; while (x <= endx) { if (*dstp != *srcp) { gotoxy(lineno, x); while (x <= endx && (*dstp != *srcp)) { Putchar(*srcp); *dstp++ = *srcp++; x++; } } else { *dstp++ = *srcp++; x++; } } /* for */ twin->_minchng[lineno] = _NO_CHANGE; twin->_maxchng[lineno] = _NO_CHANGE; } /* transformline */
void CParallel::Write_CON(Bitu val) { // init printer if bit 4 is switched on // ... autofeed = ((val & 0x02) != 0); // autofeed adds 0xa if 0xd is sent // data is strobed to the parallel printer on the falling edge of strobe bit if ((!(val & 1)) && (controlreg & 1)) { Putchar(datareg); if (autofeed && (datareg == 0xd)) Putchar(0xa); ack = true; } controlreg = val; }
Void stopAnyPrinting() { /* terminate printing of expression,*/ if (printing) { /* after successful termination or */ printing = FALSE; /* runtime error (e.g. interrupt) */ Putchar('\n'); if (showStats) { #define plural(v) v, (v==1?"":"s") #if HUGS_FOR_WINDOWS { int svColor = SetForeColor(BLUE); #endif Printf("(%lu reduction%s, ",plural(numReductions)); Printf("%lu cell%s",plural(numCells)); if (numGcs>0) Printf(", %u garbage collection%s",plural(numGcs)); Printf(")\n"); #if HUGS_FOR_WINDOWS SetForeColor(svColor); } #endif #undef plural } #if OBSERVATIONS printObserve(ALLTAGS); if (obsCount) { ERRMSG(0) "Internal: observation sanity counter > 0\n" EEND; } if (showStats){ Int n = countObserve(); if (n > 0) Printf("%d observations recorded\n", n); } #endif FlushStdout(); garbageCollect(); } }
void Printer::Print(const char* str) { int i; for (;*str;str++) { switch (*str) { case '\n': for (i=xpos;i<COLUMNS;i++) { Putchar(i,ypos,' '); } xpos = 0; ypos++; break; case '\b': if (xpos==0&&ypos==0) ; else if (xpos==0) { xpos = COLUMNS-1; ypos--; } else { xpos--; } Putchar(xpos,ypos,' '); break; default: Putchar(xpos,ypos,*str); if (xpos==COLUMNS-1) { xpos = 0; ypos++; } else { xpos++; } break; } } if (ypos<=(LINES-1)) { GotoXY(xpos,ypos); } else { Scrollup(ypos-(LINES-1)); GotoXY(xpos,(LINES-1)); } }
void Putstring(struct Global *global, char *string) { /* * Output a string! One letter at a time to the Putchar routine! */ if(!string) return; while(*string) Putchar(global, *string++); }
void xechoit(tchar **t) { #ifdef TRACE tprintf("TRACE- xechoit()\n"); #endif if (adrof(S_echo /* "echo" */)) { flush(); haderr = 1; blkpr(t), Putchar('\n'); haderr = 0; } }
void Putint(struct Global *global, int number) { /* * Output the number as a string. */ char buffer[16]; /* an integer can't be that big! */ char *point=buffer; sprintf(buffer, "%d", number); while(*point) Putchar(global, *point++); }
FILE_LOCAL void sharp(struct Global *global) { /* * Output a line number line. */ char *name; if (global->keepcomments) /* Make sure # comes on */ Putchar(global, '\n'); /* a fresh, new line. */ /* printf("#%s %d", LINE_PREFIX, global->line); */ Putchar(global, '#'); if(global->outputLINE) Putstring(global, LINE_PREFIX); Putchar(global, ' '); Putint(global, global->line); if (global->infile->fp != NULL) { name = (global->infile->progname != NULL) ? global->infile->progname : global->infile->filename; if (global->sharpfilename == NULL || (global->sharpfilename != NULL && !streq(name, global->sharpfilename))) { if (global->sharpfilename != NULL) free(global->sharpfilename); global->sharpfilename = savestring(global, name); /* printf(" \"%s\"", name); */ Putstring(global, " \""); Putstring(global, name); Putchar(global, '\"'); } } Putchar(global, '\n'); global->wrongline = FALSE; return; }
FILE_LOCAL ReturnCode output(struct Global *global, int c) { /* * Output one character to stdout -- output() is passed as an * argument to scanstring() */ #if COMMENT_INVISIBLE if (c != TOK_SEP && c != COM_SEP) #else if (c != TOK_SEP) #endif Putchar(global, c); return(FPP_OK); }
static void clrupdate(WINDOW *scr) { register int *src; register int *dst; register int i; register int j; WINDOW *w; w = curscr; if (scr != w) { /* copy scr to curscr */ for (i = 0; i < LINES; i++) { src = scr->_line[i]; dst = w->_line[i]; for (j = 0; j < COLS; j++) *dst++ = *src++; } /* for */ } /* if */ newattr(scr->_attrs); clrscr(); scr->_clear = FALSE; for (i = 0; i < LINES; i++) { /* update physical screen */ src = w->_line[i]; j = 0; while (j < COLS) { if (*src != (' ' | ATR_NRM)) { gotoxy(i, j); while (j < COLS && (*src != (' ' | ATR_NRM))) { Putchar(*src++); j++; } } else { src++; j++; } } /* for */ } /* for */ fflush(stdout); } /* clrupdate */
void prusage(struct rusage *r0, struct rusage *r1, struct timeval *e, struct timeval *b) { #define pgtok(p) ((p * pgsize) / 1024) static int pgsize; time_t t = (r1->ru_utime.tv_sec - r0->ru_utime.tv_sec) * 100 + (r1->ru_utime.tv_usec - r0->ru_utime.tv_usec) / 10000 + (r1->ru_stime.tv_sec - r0->ru_stime.tv_sec) * 100 + (r1->ru_stime.tv_usec - r0->ru_stime.tv_usec) / 10000; tchar *cp; int i; struct varent *vp = adrof(S_time); int ms = (e->tv_sec - b->tv_sec) * 100 + (e->tv_usec - b->tv_usec) / 10000; #ifdef TRACE tprintf("TRACE- prusage()\n"); #endif if (pgsize == 0) { pgsize = getpagesize(); } cp = S_USAGEFORMAT; /* "%Uu %Ss %E %P %X+%Dk %I+%Oio %Fpf+%Ww" */ if (vp && vp->vec[0] && vp->vec[1]) { cp = vp->vec[1]; } for (; *cp; cp++) { if (*cp != '%') { Putchar(*cp); } else if (cp[1]) { switch (*++cp) { case 'U': pdeltat(&r1->ru_utime, &r0->ru_utime); break; case 'S': pdeltat(&r1->ru_stime, &r0->ru_stime); break; case 'E': psecs_int(ms / 100); break; case 'P': printf("%d%%", (int)(t * 100 / ((ms ? ms : 1)))); break; case 'W': i = r1->ru_nswap - r0->ru_nswap; printf("%d", i); break; case 'X': printf("%d", t == 0 ? 0 : pgtok((r1->ru_ixrss - r0->ru_ixrss) / t)); break; case 'D': printf("%d", t == 0 ? 0 : pgtok((r1->ru_idrss + r1->ru_isrss- (r0->ru_idrss + r0->ru_isrss)) / t)); break; case 'K': printf("%d", t == 0 ? 0 : pgtok(((r1->ru_ixrss + r1->ru_isrss + r1->ru_idrss) - (r0->ru_ixrss + r0->ru_idrss + r0->ru_isrss)) / t)); break; case 'M': printf("%d", r1->ru_maxrss / 2); break; case 'F': printf("%d", r1->ru_majflt - r0->ru_majflt); break; case 'R': printf("%d", r1->ru_minflt - r0->ru_minflt); break; case 'I': printf("%d", r1->ru_inblock - r0->ru_inblock); break; case 'O': printf("%d", r1->ru_oublock - r0->ru_oublock); break; } } } Putchar('\n'); #undef pgtok }
static void pk_unpack_fn P1C(ubyte, ch) { int i, j; ubyte n; int row_bit_pos; boolean paint_switch; BMUNIT *cp; long fpwidth; BMUNIT word; int word_weight, bytes_wide; int rows_left, h_bit, count; register struct glyph *g = ¤t_font->glyph[ch]; /* We randomly chose `x2' to store this above. */ PK_flag_byte = g->x2; PK_dyn_f = PK_flag_byte >> 4; paint_switch = !!(PK_flag_byte & 8); PK_flag_byte &= 0x7; if (PK_flag_byte == 7) n = 4; else if (PK_flag_byte > 3) n = 2; else n = 1; if (debug & DBG_PK) Printf ("loading pk char %d, char type %d ", ch, n); /* Set the static variable for other routines to get the data from. */ data_string = g->packed_data; /* Now read rest of character preamble. */ if (n != 4) fpwidth = data_snum (3); else { fpwidth = data_sfour (); (void) data_four (); /* horizontal escapement */ } (void) data_num (n); /* vertical escapement */ { unsigned long w, h; w = data_num (n); h = data_num (n); if (w > 0x7fff || h > 0x7fff) oops ("Too large character in file %s", current_font->fontname); g->bitmap.w = w; g->bitmap.h = h; } g->x = data_snum (n); g->y = data_snum (n); g->dvi_adv = ((double) current_font->scale * fpwidth) / (1 << 20); if (debug & DBG_PK) { if (g->bitmap.w != 0) Printf (", size=%dx%d, dvi_adv=%d", g->bitmap.w, g->bitmap.h, g->dvi_adv); Putchar ('\n'); } alloc_bitmap (&g->bitmap); cp = (BMUNIT *) g->bitmap.bits; /* read character data into *cp. */ bytes_wide = ROUNDUP (g->bitmap.w, BITS_PER_BMUNIT) * BYTES_PER_BMUNIT; PK_bitpos = -1; if (PK_dyn_f == 14) /* get raster by bits */ { bzero (g->bitmap.bits, g->bitmap.h * bytes_wide); for (i = 0; i < g->bitmap.h; i++) /* get all rows */ { cp = ADD (g->bitmap.bits, i * bytes_wide); #ifndef MSBITFIRST row_bit_pos = -1; #else row_bit_pos = BITS_PER_BMUNIT; #endif for (j = 0; j < g->bitmap.w; j++) /* get one row */ { if (--PK_bitpos < 0) { word = data_one (); PK_bitpos = 7; } #ifndef MSBITFIRST if (++row_bit_pos >= BITS_PER_BMUNIT) #else if (--row_bit_pos < 0) #endif { cp++; #ifndef MSBITFIRST row_bit_pos = 0; #else row_bit_pos = BITS_PER_BMUNIT - 1; #endif } if (word & (1 << PK_bitpos)) *cp |= 1 << row_bit_pos; } } } else { /* get packed raster */ rows_left = g->bitmap.h; h_bit = g->bitmap.w; PK_repeat_count = 0; word_weight = BITS_PER_BMUNIT; word = 0; while (rows_left > 0) { count = PK_packed_num (); while (count > 0) { if (count < word_weight && count < h_bit) { #ifndef MSBITFIRST if (paint_switch) word |= bit_masks[count] << (BITS_PER_BMUNIT - word_weight); #endif h_bit -= count; word_weight -= count; #ifdef MSBITFIRST if (paint_switch) word |= bit_masks[count] << word_weight; #endif count = 0; } else if (count >= h_bit && h_bit <= word_weight) { if (paint_switch) word |= bit_masks[h_bit] << #ifndef MSBITFIRST (BITS_PER_BMUNIT - word_weight); #else (word_weight - h_bit); #endif *cp++ = word; /* "output" row(s) */ for (i = PK_repeat_count * bytes_wide / BYTES_PER_BMUNIT; i > 0; --i) { *cp = *SUB (cp, bytes_wide); ++cp; } rows_left -= PK_repeat_count + 1; PK_repeat_count = 0; word = 0; word_weight = BITS_PER_BMUNIT; count -= h_bit; h_bit = g->bitmap.w; } else { if (paint_switch) #ifndef MSBITFIRST word |= bit_masks[word_weight] << (BITS_PER_BMUNIT - word_weight); #else word |= bit_masks[word_weight]; #endif *cp++ = word; word = 0; count -= word_weight; h_bit -= word_weight; word_weight = BITS_PER_BMUNIT; } } paint_switch = 1 - paint_switch; } if (cp != ((BMUNIT *) (g->bitmap.bits + bytes_wide * g->bitmap.h))) oops ("Wrong number of bits stored: char. %d, font %s", ch, current_font->fontname); if (rows_left != 0 || h_bit != g->bitmap.w) oops ("Bad pk file (%s), too many bits", current_font->fontname); } /* Now that we've read the packed data, we can release the memory. */ free (g->packed_data); g->packed_data = NULL; }
static void read_PK_char(struct font *fontp, wide_ubyte ch) { int i, j; int n; int row_bit_pos; Boolean paint_switch; BMUNIT *cp; struct glyph *g; FILE *fp = fontp->file; long fpwidth; BMUNIT word = 0; int word_weight, bytes_wide; int rows_left, h_bit, count; g = &fontp->glyph[ch]; PK_flag_byte = g->x2; PK_dyn_f = PK_flag_byte >> 4; paint_switch = ((PK_flag_byte & 8) != 0); PK_flag_byte &= 0x7; if (PK_flag_byte == 7) n = 4; else if (PK_flag_byte > 3) n = 2; else n = 1; if (debug & DBG_PK) Printf("loading pk char %d, char type %d ", ch, n); /* * now read rest of character preamble */ if (n != 4) fpwidth = num(fp, 3); else { fpwidth = sfour(fp); (void)four(fp); /* horizontal escapement */ } (void)num(fp, n); /* vertical escapement */ { unsigned long w, h; w = num(fp, n); h = num(fp, n); if (w > 0x7fff || h > 0x7fff) oops("Character %d too large in file %s", ch, fontp->fontname); g->bitmap.w = w; g->bitmap.h = h; } g->x = snum(fp, n); g->y = snum(fp, n); g->dvi_adv = fontp->dimconv * fpwidth; if (debug & DBG_PK) { if (g->bitmap.w != 0) Printf(", size=%dx%d, dvi_adv=%ld", g->bitmap.w, g->bitmap.h, g->dvi_adv); Putchar('\n'); } alloc_bitmap(&g->bitmap); cp = (BMUNIT *) g->bitmap.bits; /* * read character data into *cp */ bytes_wide = ROUNDUP((int)g->bitmap.w, BMBITS) * BMBYTES; PK_bitpos = -1; if (PK_dyn_f == 14) { /* get raster by bits */ bzero(g->bitmap.bits, (int)g->bitmap.h * bytes_wide); for (i = 0; i < (int)g->bitmap.h; i++) { /* get all rows */ cp = ADD(g->bitmap.bits, i * bytes_wide); #ifndef WORDS_BIGENDIAN row_bit_pos = -1; #else row_bit_pos = BMBITS; #endif for (j = 0; j < (int)g->bitmap.w; j++) { /* get one row */ if (--PK_bitpos < 0) { word = one(fp); PK_bitpos = 7; } #ifndef WORDS_BIGENDIAN if (++row_bit_pos >= BMBITS) { cp++; row_bit_pos = 0; } #else if (--row_bit_pos < 0) { cp++; row_bit_pos = BMBITS - 1; } #endif if (word & (1 << PK_bitpos)) *cp |= 1 << row_bit_pos; } } } else { /* get packed raster */ rows_left = g->bitmap.h; h_bit = g->bitmap.w; PK_repeat_count = 0; word_weight = BMBITS; word = 0; while (rows_left > 0) { count = PK_packed_num(fp); while (count > 0) { if (count < word_weight && count < h_bit) { #ifndef WORDS_BIGENDIAN if (paint_switch) word |= bit_masks[count] << (BMBITS - word_weight); #endif h_bit -= count; word_weight -= count; #ifdef WORDS_BIGENDIAN if (paint_switch) word |= bit_masks[count] << word_weight; #endif count = 0; } else if (count >= h_bit && h_bit <= word_weight) { if (paint_switch) word |= bit_masks[h_bit] << #ifndef WORDS_BIGENDIAN (BMBITS - word_weight); #else (word_weight - h_bit); #endif *cp++ = word; /* "output" row(s) */ for (i = PK_repeat_count * bytes_wide / BMBYTES; i > 0; --i) { *cp = *SUB(cp, bytes_wide); ++cp; } rows_left -= PK_repeat_count + 1; PK_repeat_count = 0; word = 0; word_weight = BMBITS; count -= h_bit; h_bit = g->bitmap.w; } else { if (paint_switch) #ifndef WORDS_BIGENDIAN word |= bit_masks[word_weight] << (BMBITS - word_weight); #else word |= bit_masks[word_weight]; #endif *cp++ = word; word = 0; count -= word_weight; h_bit -= word_weight; word_weight = BMBITS; } } paint_switch = 1 - paint_switch; } if (cp != ((BMUNIT *) (g->bitmap.bits + bytes_wide * g->bitmap.h))) oops("Wrong number of bits stored: char. %d, font %s", ch, fontp->fontname); if (rows_left != 0 || h_bit != g->bitmap.w) oops("Bad pk file (%s), too many bits", fontp->fontname); } }
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 ); }
INLINE FILE_LOCAL ReturnCode cppmain(struct Global *global) { /* * Main process for cpp -- copies tokens from the current input * stream (main file, include file, or a macro) to the output * file. */ int c; /* Current character */ int counter; /* newlines and spaces */ ReturnCode ret; /* return code variable type */ long bracelevel = 0; long parenlevel = 0; long bracketlevel = 0; int fake = 0; #define MAX_FUNC_LENGTH 50 char tempfunc[MAX_FUNC_LENGTH + 1]; char tempfunc2[MAX_FUNC_LENGTH + 1]; char define = 0; /* probability of a function define phase in the program */ char prev = 0; /* previous type */ char go = 0; char include = 0; char initfunc = 0; /* Initialize for reading tokens */ global->tokenbsize = 50; global->tokenbuf = malloc(global->tokenbsize + 1); if(!global->tokenbuf) return(FPP_OUT_OF_MEMORY); global->functionname = malloc(global->tokenbsize + 1); if(!global->functionname) return(FPP_OUT_OF_MEMORY); global->functionname[0] = '\0'; if(global->showspace) { global->spacebuf = (char *)malloc(MAX_SPACE_SIZE); if(!global->spacebuf) return(FPP_OUT_OF_MEMORY); } if(global->showversion) Error(global, VERSION_TEXT); /* * Explicitly output a #line at the start of cpp output so * that lint (etc.) knows the name of the original source * file. If we don't do this explicitly, we may get * the name of the first #include file instead. */ if(global->linelines) /* if #line lines are wanted! */ sharp(global); /* * This loop is started "from the top" at the beginning of each line * wrongline is set TRUE in many places if it is necessary to write * a #line record. (But we don't write them when expanding macros.) * * The counter variable has two different uses: at * the start of a line, it counts the number of blank lines that * have been skipped over. These are then either output via * #line records or by outputting explicit blank lines. * When expanding tokens within a line, the counter remembers * whether a blank/tab has been output. These are dropped * at the end of the line, and replaced by a single blank * within lines. */ include = global->included; while(include--) { openinclude(global, global->include[include], TRUE); } for (;;) { counter = 0; /* Count empty lines */ for (;;) { /* For each line, ... */ global->comment = FALSE; /* No comment yet! */ global->chpos = 0; /* Count whitespaces */ while (type[(c = get(global))] == SPA) /* Skip leading blanks */ if(global->showspace) { if(global->chpos<MAX_SPACE_SIZE-1) /* we still have buffer to store this! */ global->spacebuf[global->chpos++]=(char)c; } if (c == '\n') { /* If line's all blank, */ if(global->comment) { /* A comment was output! */ Putchar(global, '\n'); } else ++counter; /* Do nothing now */ } else if (c == '#') { /* Is 1st non-space '#' */ global->keepcomments = FALSE; /* Don't pass comments */ ret = control(global, &counter); /* Yes, do a #command */ if(ret) return(ret); global->keepcomments = (global->cflag && compiling); } else if (c == EOF_CHAR) /* At end of file? */ break; else if (!compiling) { /* #ifdef false? */ skipnl(global); /* Skip to newline */ counter++; /* Count it, too. */ } else { break; /* Actual token */ } } if (c == EOF_CHAR) /* Exit process at */ break; /* End of file */ /* * If the loop didn't terminate because of end of file, we * know there is a token to compile. First, clean up after * absorbing newlines. counter has the number we skipped. */ if(global->linelines) { /* if #line lines are wanted! */ if ((global->wrongline && global->infile->fp != NULL) || counter > 4) sharp(global); /* Output # line number */ else { /* If just a few, stuff */ while (--counter >= 0) /* them out ourselves */ Putchar(global, (int)'\n'); } } if(global->showspace) { /* Show all whitespaces! */ global->spacebuf[global->chpos] = '\0'; Putstring(global, global->spacebuf); } /* * Process each token on this line. */ unget(global); /* Reread the char. */ for (;;) { /* For the whole line, */ do { /* Token concat. loop */ for (global->chpos = counter = 0; (type[(c = get(global))] == SPA);) { #if COMMENT_INVISIBLE if (c != COM_SEP) counter++; #else if(global->showspace && global->chpos < MAX_SPACE_SIZE-1) { global->spacebuf[global->chpos++]=(char)c; } counter++; /* Skip over blanks */ #endif } if (c == EOF_CHAR || c == '\n') break; /* Exit line loop */ else if (counter > 0) { /* If we got any spaces */ if(!global->showspace) /* We don't output all spaces */ Putchar(global, (int)' ');/* Output one space */ else { global->spacebuf[global->chpos] = '\0'; Putstring(global, global->spacebuf); /* Output all whitespaces */ } } if(ret=macroid(global, &c)) /* Grab the token */ return(ret); } while (type[c] == LET && catenate(global, &ret) && !ret); if(ret) /* If the loop was broken because of a fatal error! */ return(ret); if (c == EOF_CHAR || c == '\n') /* From macro exp error */ break; /* Exit line loop */ go++; switch (type[c]) { case LET: go =0; /* Quite ordinary token */ Putstring(global, global->tokenbuf); if(!define) { /* Copy the name */ strncpy(tempfunc, global->tokenbuf, MAX_FUNC_LENGTH); tempfunc[MAX_FUNC_LENGTH]=0; } /* fputs(global->tokenbuf, stdout); */ break; case DIG: /* Output a number */ case DOT: /* Dot may begin floats */ go = 0; ret=scannumber(global, c, (ReturnCode(*)(struct Global *, int))output); if(ret) return(ret); break; case QUO: /* char or string const */ go = 0; /* Copy it to output */ if(!global->webmode) { ret=scanstring(global, c, (ReturnCode(*)(struct Global *, int))output); if(ret) return(ret); break; } /* FALLTHROUGH */ default: /* Some other character */ define++; switch(c) { case '{': if(! bracelevel++ && define > 2) { /* * This is a starting brace. If there is a probability of a * function defining, we copy the `tempfunc' function name to * `global->functionname'. */ strcpy(global->functionname, tempfunc2); global->funcline = global->line; if(global->outputfunctions) { /* * Output the discovered function name to stderr! */ Error(global, "#> Function defined at line %d: %s <#\n", global->line, global->functionname); } if(global->initialfunc) { int a; for(a=0; a<global->excluded; a++) { /* check for excluded functions */ if(!strcmp(global->functionname, global->excludedinit[a])) break; } if(a==global->excluded) { expstuff(global, "__brace__", "{"); expstuff(global, "__init_func__", global->initialfunc); initfunc = TRUE; } } } break; case '}': go = 0; if( (--bracelevel == initfunc) && strcmp(global->infile->filename, "__init_func__") ) { /* we just stepped out of the function! */ global->functionname[0] = '\0'; global->funcline = 0; define = 1; if(initfunc) { Putchar(global, '}'); bracelevel--; initfunc=0; } } fake = 0; break; case ';': case ',': if(go == 2) { define = 1; fake = 0; go--; break; } break; case '(': if(! parenlevel++ && !bracelevel) { if(go == 2) { /* foobar(text) -> "(" is found. This can't be a function */ go--; define = 1; break; } if( define < 2 && prev == LET) { /* This is the first parenthesis on the ground brace level, and we did previously not have a probable function name */ strncpy(tempfunc2, global->tokenbuf, MAX_FUNC_LENGTH); tempfunc2[MAX_FUNC_LENGTH]=0; define++; } else { /* we have a fake start */ fake++; } } break; case ')': if(! --parenlevel && !bracelevel && define>1 && !fake) { /* * The starting parentheses level and * the starting brace level. * This might be the start of a function defining coming * up! */ define++; /* increase probability */ fake = 0; go = 1; } break; case '[': bracketlevel++; break; case ']': bracketlevel--; break; } define--; /* decrease function probability */ Putchar(global, c); /* Just output it */ break; } /* Switch ends */ prev = type[c]; } /* Line for loop */ if (c == '\n') { /* Compiling at EOL? */ Putchar(global, '\n'); /* Output newline, if */ if (global->infile->fp == NULL) /* Expanding a macro, */ global->wrongline = TRUE; /* Output # line later */ } } /* Continue until EOF */ if(global->showbalance) { if(bracketlevel) { cwarn(global, WARN_BRACKET_DEPTH, bracketlevel); } if(parenlevel) { cwarn(global, WARN_PAREN_DEPTH, parenlevel); } if(bracelevel) { cwarn(global, WARN_BRACE_DEPTH, bracelevel); } } if (global->wflag) { global->out = TRUE; /* enable output */ outdefines(global); /* Write out #defines */ } return(FPP_OK); }