Example #1
0
int
xgettok(XFILE *xfp, char sepa, char *tok, int len)
{
	int	i = 0;
	int	c = 0;
	int 	quoted=0;

	while (i < len && (c = xgetc(xfp)) != EOF &&
	       (quoted || (c != sepa && !isspace(c)))) {
		if (c == '"') {
			quoted = !quoted;
			continue;
		}
		tok[i++] = c;
		if (i >= 4 &&
		    tok[i-4] == '\\' &&
		    isoctal(tok[i-3]) &&
		    isoctal(tok[i-2]) &&
		    isoctal(tok[i-1]) &&
		    ((tok[i]=0),
		     (c = strtol(tok+i-3,NULL, 8)) < 256)) {
			i -= 4;
			tok[i++] = c;
		}
	}	
	if (c == '\n')
		xungetc(c, xfp);
	if (!i)
		return 0;
	if (i >= len || (sepa && c != sepa))
		return -1;
	tok[i] = '\0';
	return 1;
}
Example #2
0
void
xskip(XFILE *xfp, char *str)
{
	int	c;

	while ((c = xgetc(xfp)) != EOF) {
		if (c == '#')
			c = xskipcomment(xfp);
		if (strchr(str, c) == NULL)
			break;
	}
	xungetc(c, xfp);
}
Example #3
0
File: port.c Project: KeenS/benz
static pic_value
pic_port_peek_char(pic_state *pic)
{
  int c;
  struct pic_port *port = pic_stdin(pic);

  pic_get_args(pic, "|p", &port);

  assert_port_profile(port, PIC_PORT_IN | PIC_PORT_TEXT, PIC_PORT_OPEN, "peek-char");

  if ((c = xfgetc(port->file)) == EOF) {
    return pic_eof_object();
  }
  else {
    xungetc(c, port->file);
    return pic_char_value((char)c);
  }
}
Example #4
0
File: port.c Project: KeenS/benz
static pic_value
pic_port_peek_byte(pic_state *pic)
{
  int c;
  struct pic_port *port = pic_stdin(pic);

  pic_get_args(pic, "|p", &port);

  assert_port_profile(port, PIC_PORT_IN | PIC_PORT_BINARY, PIC_PORT_OPEN, "peek-u8");

  c = xfgetc(port->file);
  if (c == EOF) {
    return pic_eof_object();
  }
  else {
    xungetc(c, port->file);
    return pic_int_value(c);
  }
}
Example #5
0
size_t xfread(void *ptr, size_t size, size_t count, xFILE *fp) {
  char *bptr = ptr;
  long nbytes;
  int c;

  nbytes = size * count;
  while (nbytes > fp->cnt) {
    memcpy(bptr, fp->ptr, fp->cnt);
    fp->ptr += fp->cnt;
    bptr += fp->cnt;
    nbytes -= fp->cnt;
    if ((c = x_fillbuf(fp)) == EOF) {
      return (size * count - nbytes) / size;
    } else {
      xungetc(c, fp);
    }
  }
  memcpy(bptr, fp->ptr, nbytes);
  fp->ptr += nbytes;
  fp->cnt -= nbytes;
  return count;
}
Example #6
0
int vxscanf(int (*xgetc)(void **), void (*xungetc)(int, void **), void *stream, const char *fmt, va_list ap) {
	union {
#if SCANF_LEVEL >= SCANF_FLT
		float	d;
#endif
		unsigned long ul;
		long	l;
		char	*cp;
	} a;
	char	c;	/* holds a char from the format string */
	u8	base = 0;
	int	nconvs, i, j = 0, olen, clen;
#if SCANF_LEVEL > SCANF_MIN
	s8	width = 0;
#endif
	u8 flags;
#if SCANF_LEVEL >= SCANF_FLT
	char	*buf, *bp;
	char	fltchars[] = "0123456789Ee.";
#endif

	flags = 0;
	nconvs = 0;
	i = 0;
	olen = clen = 0;
#if SCANF_LEVEL >= SCANF_FLT
	buf = 0;
#endif

	a.ul = 0;
	while ((c = *(fmt++))) {
#if SCANF_LEVEL >= SCANF_FLT
		if (isspace(c))
			continue;
		if (flags & FLBRACKET) {
			if (c == '^' && i == 0 && !(flags & FLNEGATE)) {
				flags |= FLNEGATE; /* negate set */
				continue; /* without bumping i */
			}
			if (c == '-') {
				if (i == 0) {
				  addbit:
					xscanf_set_bit(c);
					i++;
					continue;
				}
				flags |= FLMINUS;
				i++;
				continue;
			}
			if (c == ']') {
				if (i == 0)
					goto addbit;
				if (flags & FLMINUS) /* trailing - before ] */
					xscanf_set_bit('-');
				if (flags & FLNEGATE)
					for (i = 0; i < 256 / 8; i++)
						buf[i] = ~buf[i];
				if (!(flags & FLSTAR))
					a.cp = va_arg(ap, char *);
				while (width-- > 0) {
					i = w_xgetc(&stream);
					if (i == EOF)
						break;
					if (!xscanf_bit_is_set(i)) {
						xungetc(i, &stream);
						break;
					}
					if (!(flags & FLSTAR))
						*a.cp++ = i;
				}
				if (!(flags & FLSTAR))
					*a.cp = '\0';
				goto nextconv;
			}
			if (flags & FLMINUS) {
				flags &= ~FLMINUS;
				while ((unsigned char)j < (unsigned char)c) {
					xscanf_set_bit(j);
					j++;
				}
			}
			j = (unsigned char)c; /* remember for x-y range */
			goto addbit;
		}
#endif /* SCANF_LEVEL >= SCANF_FLT */
		if (flags & FLHASPERCENT) {
			if (c == '%') {
				flags &= ~FLHASPERCENT;
#if SCANF_LEVEL > SCANF_MIN
				goto literal;
#else
				continue;
#endif
			}

			/*
			 * Modifiers go first.  They all end up in a
			 * "continue" statement so to fetch the next
			 * char from the format string.
			 */
#if SCANF_LEVEL > SCANF_MIN
			if (c >= '0' && c <= '9') {
				c -= '0';
				if (width == SCHAR_MAX)
					width = 0;
				else
					width *= 10;
				width += c;
				continue;
			}
#endif /* SCANF_LEVEL > SCANF_MIN */

			c = tolower(c);
#if SCANF_LEVEL >= SCANF_FLT
			if ((c == '[' || c == 'e' || c == 'f' || c == 'g') &&
			    buf == 0) {
				if ((buf = malloc(FLTBUF)) == 0)
					return EOF;
			}
#endif /* SCANF_LEVEL >= SCANF_FLT */

			switch (c) {
#if SCANF_LEVEL > SCANF_MIN
			case '*':
				flags |= FLSTAR;
				continue;
#endif /* SCANF_LEVEL > SCANF_MIN */

			case 'h':
#if SHRT_MAX != INT_MAX
				flags |= FLSHORT;
#endif
				/*
				 * short int and int are identical on
				 * our target platform, ignore.
				 */
				continue;

			case 'l':
				flags |= FLLONG;
				continue;

				/*
				 * Actual conversion specifications go
				 * here.
				 */
			case 'c':
#if SCANF_LEVEL > SCANF_MIN
				if (!(flags & FLSTAR))
#endif /* SCANF_LEVEL > SCANF_MIN */
					a.cp = va_arg(ap, char *);
#if SCANF_LEVEL > SCANF_MIN
				if (width == SCHAR_MAX)
					width = 1;
				while (width-- > 0) {
#endif /* SCANF_LEVEL > SCANF_MIN */
					i = w_xgetc(&stream);
					if (i == EOF)
						goto leave;
#if SCANF_LEVEL > SCANF_MIN
					if (!(flags & FLSTAR))
#endif /* SCANF_LEVEL > SCANF_MIN */
						*a.cp++ = i;
#if SCANF_LEVEL > SCANF_MIN
				}
#endif /* SCANF_LEVEL > SCANF_MIN */
				break;

			case 's':
#if SCANF_LEVEL > SCANF_MIN
				if (!(flags & FLSTAR))
#endif /* SCANF_LEVEL > SCANF_MIN */
					a.cp = va_arg(ap, char *);
				do {
					i = w_xgetc(&stream);
				} while (isspace(i));
				if (i == EOF)
					goto leave;

#if SCANF_LEVEL > SCANF_MIN
				while (width-- > 0)
#else
				for (;;)
#endif /* SCANF_LEVEL > SCANF_MIN */
				{
					if (isspace(i)) {
						xungetc(i, &stream);
						break;
					}
#if SCANF_LEVEL > SCANF_MIN
					if (!(flags & FLSTAR))
#endif /* SCANF_LEVEL > SCANF_MIN */
						*a.cp++ = i;
					i = w_xgetc(&stream);
					if (i == EOF)
						break;
				}
#if SCANF_LEVEL > SCANF_MIN
				if (!(flags & FLSTAR))
#endif /* SCANF_LEVEL > SCANF_MIN */
					*a.cp = '\0';
				break;

			case 'o':
				base = 8;
				flags |= FLUNSIGNED;
				goto dointeger;

			case 'p':
				/*
				 * Handle pointers as plain unsigned
				 * integers.  This assumes that
				 * sizeof(void *) == sizeof(unsigned int).
				 */
			case 'x':
				base = 16;
				/* FALLTHROUGH */

			case 'u':
				flags |= FLUNSIGNED;
				/* FALLTHROUGH */

			case 'd':
			case 'i':
			  dointeger:
				do {
					i = w_xgetc(&stream);
				} while (isspace(i));
				if (i == EOF)
					goto leave;

				if ((char)i == '-' || (char)i == '+') {
#if SCANF_LEVEL > SCANF_MIN
					if (--width <= 0)
						/*
						 * Incomplete conversion
						 * due to field width
						 * truncation.
						 */
						goto leave;
#endif /* SCANF_LEVEL > SCANF_MIN */
					if ((char)i == '-')
						flags |= FLMINUS;
					i = w_xgetc(&stream);
					if (i == EOF)
						goto leave;
				}

				if ((char)i == '0') {
					/*
					 * %i conversions default to base
					 * 10, but allow for base 8
					 * indicated by a leading 0 in
					 * input, or base 16 indicated by
					 * leading 0x/0X.
					 *
					 * For %x (and %p) conversions, the
					 * leading 0x/0X is explicitly
					 * allowable.
					 *
					 * If we fail the conversion here,
					 * it is a mismatch condition, but
					 * since we already saw a zero,
					 * this means the current
					 * conversion succeeded, assigning
					 * 0.
					 */
					a.ul = 0;

#if SCANF_LEVEL > SCANF_MIN
					if (--width <= 0)
						goto intdone;
#endif /* SCANF_LEVEL > SCANF_MIN */
					i = w_xgetc(&stream);
					if (i == EOF)
						goto intdone;
					if ((char)tolower(i) == 'x') {
						if (c == 'o' ||
						    c == 'd' || c == 'u') {
							/*
							 * Invalid 0x in
							 * %d/%u/%o
							 */
							xungetc(i, &stream);
							goto intdone;
						}
						base = 16;
						i = w_xgetc(&stream);
						if (i == EOF)
							goto intdone;
					} else if (c == 'i')
						base = 8;
				}

				a.ul = 0;
				for (;;) {
					j = tolower(i);
					/*
					 * First, assume it is a decimal
					 * digit.
					 */
					j -= '0';
					if (j > 9) {
						/*
						 * Not a decimal digit.
						 * Try hex next.
						 */
						j += '0'; /* undo "- '0'"
							   * above */
						j -= 'a'; /* 'a' is first
							   * hex digit */
						if (j >= 0)
							/* 'a' has value
							 * 10 */
							j += 10;
						/*
						 * else: not a hex digit,
						 * gets caught below.
						 */
					}
					if (j < 0 || j >= base) {
						xungetc(i, &stream);
						break;
					}
					a.ul *= base;
					a.ul += j;
#if SCANF_LEVEL > SCANF_MIN
					if (--width <= 0)
						break;
#endif /* SCANF_LEVEL > SCANF_MIN */
					i = w_xgetc(&stream);
					if (i == EOF)
						break;
				}
				/*
				 * This is a bit of a hack: while we
				 * collect all integer digits in an
				 * unsigned long number in order to be
				 * safe for unsigned conversions, the
				 * standard allows for optional signs.
				 * We are thus faced to the concept of
				 * possibly negating an unsigned
				 * number. :-/  We rely here on union a
				 * mapping the signed and unsigned
				 * fields suitably.
				 */
				if (flags & FLMINUS)
					a.l = -a.l;
			  intdone:
#if SCANF_LEVEL > SCANF_MIN
				if (!(flags & FLSTAR)) {
#endif /* SCANF_LEVEL > SCANF_MIN */
					if ((flags & (FLLONG | FLUNSIGNED)) == (FLLONG | FLUNSIGNED))
						*(va_arg(ap, unsigned long *)) = a.ul;
					else if ((flags & (FLSHORT | FLUNSIGNED)) == (FLSHORT | FLUNSIGNED))
						*(va_arg(ap, unsigned short *)) = (unsigned short)a.ul;
					else if (flags & (FLUNSIGNED))
						*(va_arg(ap, unsigned *)) = (unsigned)a.ul;
					else if (flags & FLLONG)
						*(va_arg(ap, long *)) = a.l;
					else if (flags & FLSHORT)
						*(va_arg(ap, short *)) = (short)a.l;
					else
						*(va_arg(ap, int *)) = (int)a.l;
#if SCANF_LEVEL > SCANF_MIN
				}
#endif /* SCANF_LEVEL > SCANF_MIN */
				break;

#if SCANF_LEVEL > SCANF_MIN
			case 'n':
				if (!(flags & FLSTAR))
					*(va_arg(ap, int *)) = clen;
				break;
#endif /* SCANF_LEVEL > SCANF_MIN */

#if SCANF_LEVEL >= SCANF_FLT
			case 'e':
			case 'f':
			case 'g':
				do {
					i = w_xgetc(&stream);
				} while (isspace(i));
				if (i == EOF)
					goto leave;

				if ((char)i == '-' || (char)i == '+') {
					if ((char)i == '-')
						flags |= FLMINUS;
					i = w_xgetc(&stream);
					if (i == EOF)
						goto leave;
				}

				a.d = 0.0;
				for (bp = buf;
				     bp < buf + FLTBUF - 1 && width > 0;
				     width--) {
						if (isspace(i))
							break;
					if (strchr(fltchars, i) == 0) {
						xungetc(i, &stream);
						break;
					}
					if ((char)i == 'e' ||
					    (char)i == 'E') {
						/*
						 * Prevent another 'E'
						 * from being recognized.
						 */
						fltchars[10] = 0;
						*bp++ = i;
						i = w_xgetc(&stream);
						if (i == EOF)
							break;
						if ((char)i != '-' &&
						    (char)i != '+')
							continue;
					} else if ((char)i == '.')
						/*
						 * Prevent another dot from
						 * being recognized.  If we
						 * already saw an 'E'
						 * above, we could not get
						 * here at all.
						 */
						fltchars[12] = 0;
					*bp++ = i;
					i = w_xgetc(&stream);
					if (i == EOF)
						break;
				}
				*bp++ = 0;
				a.d = (float)strtod(buf, 0);
				if (flags & FLMINUS)
					a.d = -a.d;
				*(va_arg(ap, float  *)) = a.d;
				/*
				 * Restore the 'E' and '.' chars that
				 * might have been clobbered above.
				 */
				fltchars[10] = 'E';
				fltchars[12] = '.';
				break;

			case '[':
				flags |= FLBRACKET;
				i = j = 0;
				memset(buf, 0, 256 / 8);
				continue;
#endif /* SCANF_LEVEL >= SCANF_FLT */
			}

#if SCANF_LEVEL >= SCANF_FLT
		  nextconv:
#endif
			if (clen > olen && !(flags & FLSTAR)) {
				flags = 0;
				nconvs++;
			}
			else if (i == EOF) {
				/*
				 * If one conversion failed completely,
				 * punt.
				 */
				flags = 0;
				goto leave;
			}
			else
				flags = 0;
		} else if (c == '%') {
			flags = FLHASPERCENT;
			base = 10;
			olen = clen;
#if SCANF_LEVEL > SCANF_MIN
			width = SCHAR_MAX;
		} else if (isspace(c)) {
			/* match against any whitspace */
			do {
				i = w_xgetc(&stream);
			} while (isspace(i));
			if (i == EOF)
				goto leave;
			xungetc(i, &stream);
		} else {
			/* literal character in format, match it */
		  literal:
		  	i = w_xgetc(&stream);
			if (i == EOF)
				goto leave;
			if (i != c)
				goto leave;
#endif /* SCANF_LEVEL > SCANF_MIN */
		}
	}