예제 #1
0
파일: doupdt.c 프로젝트: 8l/FUZIX
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 */
예제 #2
0
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;
	}
예제 #3
0
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();
    }
}
예제 #4
0
파일: Log.cpp 프로젝트: KKRainbow/FreeCROS
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));
	}
}
예제 #5
0
파일: cpp1.c 프로젝트: amisuki/bgfx
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++);
}
예제 #6
0
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;
	}
}
예제 #7
0
파일: cpp1.c 프로젝트: kwertz/fcpp
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++);
}
예제 #8
0
파일: cpp1.c 프로젝트: kwertz/fcpp
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;
}
예제 #9
0
파일: cpp1.c 프로젝트: kwertz/fcpp
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);
}
예제 #10
0
파일: doupdt.c 프로젝트: 8l/FUZIX
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 */
예제 #11
0
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
}
예제 #12
0
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 = &current_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;
}
예제 #13
0
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);
    }
}
예제 #14
0
파일: cpp2.c 프로젝트: WangHoi/slc
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 );
}
예제 #15
0
파일: cpp1.c 프로젝트: kwertz/fcpp
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);
}