Пример #1
0
Erc Strpack::unpack(uint64_t* val) {
    uint64_t r=0;
    while (is_digit(peek()) && hasData()) {
        r *= 10;
        r += to_digit(read());
    }
    *val = r;
    return E_OK;
}
Пример #2
0
int get_number(char *expr, int *pos)
{
  int val = 0;
  
  while (is_digit(expr[(*pos)]))
    {
      val *= 10;
      val += to_digit(expr[(*pos)++]);
    }

  return val;
}
Пример #3
0
static int digit()
{
	int reg;

	if (!is_digit(token)) {
		ERROR("Expected digit\n");
		exit(EXIT_FAILURE);
	}
	reg = next_register();
	CodeGen(LOADI, to_digit(token), reg, EMPTY_FIELD);
	next_token();
	return reg;
}
Пример #4
0
int unsigned_to_nstring(char* buffer, size_t blen, unsigned n, unsigned base)
{
    int cnt=0;
    unsigned digits = count_digits(n, base);
    if (digits > blen-1) return -1;
    buffer[digits] = '\0';
    unsigned temp = n;
    while (temp > 0)
    {
        buffer[digits-cnt-1]=to_digit(temp%base);
        temp /= base;
        cnt++;
    }
    return cnt;
}
Пример #5
0
void next_commit_id_part1(char* commit_id) {
  /* COMPLETE THE REST */
  // first commit id
  char * d = "000000000000000000000000000000"; //30
  if (strcmp(commit_id, d) == 0) { 
    // to ternary 
    to_61c(commit_id, 1);
  } else {
    // to digit
    to_digit(commit_id);
    // sum as decimal
    int decimal_sum = to_decimal(atoi(commit_id));
    // decimal sum to ternary binary
    to_ternary(decimal_sum + 1, commit_id);
 }
}
Пример #6
0
void
mult_one_digit(longint_t *var, int digit) {
	longint_t working=LONG_ZERO;
	int i, carry;
	carry = 0;
	for (i=0; i<var->ndig; i++) {
		working.digs[i] = add_to_digit(CH_ZERO,
			to_int(var->digs[i])*digit,
			&carry);
	}
	if (carry) {
		if (i==INTSIZE) {
			overflow_abort();
		}
		working.digs[i++] = to_digit(carry);
	}
	working.ndig = i;
	*var = working;
	return;
}
Пример #7
0
// Reads the next token available, and sets up the variables for that.
void Tokenizer::parse_next_token()
{
	// If the current token is the end of a statement, read the next one.
	if( current_token == END_STATEMENT)
	{
		if(m_file->has_next())
		{
			#ifdef DEBUG
			std::cout << "Getting next" << std::endl;
			#endif
			
			current_line = m_file->read_line();
			current_line_position = 0;
			// Continue parsing on!
			#ifdef DEBUG
			std::cout << "Next is: " << current_line << std::endl;
			#endif
		}
		else
		{
			current_token = END_PROGRAM;
			return;
		}
	}
	// Skip all whitespace.
	while(is_whitespace(current_line[current_line_position]))
		current_line_position++;

	#ifdef DEBUG
		std::cout << "Getting next token at pos: " << current_line_position << std::endl;
		std::cout << current_line << std::endl;
		for(int i = 0; i < current_line_position; ++i)
		std::cout << " ";
		std::cout << "^" << std::endl;
	#endif
	
	// Check to see if this is the end of the statement.
	if(current_line[current_line_position] == 0)
	{
		current_token = END_STATEMENT;
		return;
	}

	
	
	// Check to see if this is a number
	if(is_digit(current_line[current_line_position]))
	{
		curr_int = 0;
		while(is_digit(current_line[current_line_position]))
		{
			curr_int *= 10;
			curr_int += to_digit(current_line[current_line_position]);

			current_line_position++;
		}
		
		current_token = NUMBER;
		return;
	}

	// Check to see if this is an operator
	current_line_position ++; // Skip past this for now, decrement later if wrong.
	switch(current_line[current_line_position - 1])
	{
		case ',':
			current_token = COMMA;
			return;
		case '+':
			current_token = PLUS;
			return;
		case '-':
			current_token = MINUS;
			return;
		case '*':
			current_token = MULTIPLY;
			return;
		case '/':
			current_token = DIVIDE;
			return;
		case '=':
			current_token = EQUALS;
			return;
		case '(':
			current_token = LPAREN;
			return;
		case ')':
			current_token = RPAREN;
			return;
		case '>':
			current_token = GREATER_THAN;
			return;
		case '<':
			current_token = LESS_THAN;
			return;
		case '\n':
			current_token = END_STATEMENT;
			return;
		default:
			current_line_position--;
			break;
	}

	// Check to see if this is a var.
	if(is_alpha(current_line[current_line_position]) &&
		! is_alpha(current_line[current_line_position + 1]))
	{
		current_token = VARIABLE;
		varname = current_line[current_line_position];


		current_line_position++;

		#ifdef DEBUG
		std::cout << "Is a variable: " << varname << std::endl;
		#endif
		return;
	}

	// Check to see if this is a string
	if(current_line[current_line_position] == '"')
	{
		int tmp = 1;

		while(current_line[current_line_position + tmp] != '"' &&
			current_line[current_line_position + tmp] != 0)
			tmp ++;
		tmp++; // advance past the final "

		delete[] curr_str;
		curr_str = 0;
		
		curr_str = substring(current_line,current_line_position + 1, tmp - 2);
		current_line_position += tmp;
		current_token = STRING;
		
		return;
	}

	// Check to see if this is a function
	if(starts_with_ignore_case(current_line, current_line_position, (char*)"PRINT"))
	{
		current_token = PRINT;
		current_line_position += 5;
		return;
	}
	if(starts_with_ignore_case(current_line, current_line_position, (char*)"IF"))
	{
		current_token = IF;
		current_line_position += 2;
		return;
	}
	if(starts_with_ignore_case(current_line, current_line_position, (char*)"THEN"))
	{
		current_token = THEN;
		current_line_position += 4;
		return;
	}
	if(starts_with_ignore_case(current_line, current_line_position, (char*)"GOTO"))
	{
		current_token = GOTO;
		current_line_position += 4;

		return;
	}
	if(starts_with_ignore_case(current_line, current_line_position, (char*)"INPUT"))
	{
		current_token = INPUT;
		current_line_position += 5;
		return;
	}
	if(starts_with_ignore_case(current_line, current_line_position, (char*)"LET"))
	{
		current_token = LET;
		current_line_position += 3;
		return;
	}
	if(starts_with_ignore_case(current_line, current_line_position, (char*)"GOSUB"))
	{
		current_token = GOSUB;
		current_line_position += 5;
		return;
	}
	if(starts_with_ignore_case(current_line, current_line_position, (char*)"RETURN"))
	{
		current_token = RETURN;
		current_line_position += 6;
		return;
	}
	if(starts_with_ignore_case(current_line, current_line_position, (char*)"CLEAR"))
	{
		current_token = CLEAR;
		current_line_position += 5;
		return;
	}
	if(starts_with_ignore_case(current_line, current_line_position, (char*)"LIST"))
	{
		current_token = LIST;
		current_line_position += 4;
		return;
	}
	if(starts_with_ignore_case(current_line, current_line_position, (char*)"RUN"))
	{
		current_token = RUN;
		return;
	}
	if(starts_with_ignore_case(current_line, current_line_position, (char*)"END"))
	{
		current_token = END;
		current_line_position += 3;
		return;
	}

	current_token = ERROR;
	
}
Пример #8
0
/* We have to overcome some problems with this implementation.  On the
   one hand the strfmon() function is specified in XPG4 and of course
   it has to follow this.  But on the other hand POSIX.2 specifies
   some information in the LC_MONETARY category which should be used,
   too.  Some of the information contradicts the information which can
   be specified in format string.  */
ssize_t
__vstrfmon_l (char *s, size_t maxsize, __locale_t loc, const char *format,
	      va_list ap)
{
  struct __locale_data *current = loc->__locales[LC_MONETARY];
  _IO_strfile f;
  struct printf_info info;
  char *dest;			/* Pointer so copy the output.  */
  const char *fmt;		/* Pointer that walks through format.  */

  dest = s;
  fmt = format;

  /* Loop through the format-string.  */
  while (*fmt != '\0')
    {
      /* The floating-point value to output.  */
      union
      {
	double dbl;
	__long_double_t ldbl;
      }
      fpnum;
      int int_format;
      int print_curr_symbol;
      int left_prec;
      int left_pad;
      int right_prec;
      int group;
      char pad;
      int is_long_double;
      int p_sign_posn;
      int n_sign_posn;
      int sign_posn;
      int other_sign_posn;
      int left;
      int is_negative;
      int sep_by_space;
      int other_sep_by_space;
      int cs_precedes;
      int other_cs_precedes;
      const char *sign_string;
      const char *other_sign_string;
      int done;
      const char *currency_symbol;
      size_t currency_symbol_len;
      long int width;
      char *startp;
      const void *ptr;
      char space_char;

      /* Process all character which do not introduce a format
	 specification.  */
      if (*fmt != '%')
	{
	  out_char (*fmt++);
	  continue;
	}

      /* "%%" means a single '%' character.  */
      if (fmt[1] == '%')
	{
	  out_char (*++fmt);
	  ++fmt;
	  continue;
	}

      /* Defaults for formatting.  */
      int_format = 0;			/* Use international curr. symbol */
      print_curr_symbol = 1;		/* Print the currency symbol.  */
      left_prec = -1;			/* No left precision specified.  */
      right_prec = -1;			/* No right precision specified.  */
      group = 1;			/* Print digits grouped.  */
      pad = ' ';			/* Fill character is <SP>.  */
      is_long_double = 0;		/* Double argument by default.  */
      p_sign_posn = -2;			/* This indicates whether the */
      n_sign_posn = -2;			/* '(' flag is given.  */
      width = -1;			/* No width specified so far.  */
      left = 0;				/* Right justified by default.  */

      /* Parse group characters.  */
      while (1)
	{
	  switch (*++fmt)
	    {
	    case '=':			/* Set fill character.  */
	      pad = *++fmt;
	      if (pad == '\0')
		{
		  /* Premature EOS.  */
		  __set_errno (EINVAL);
		  return -1;
		}
	      continue;
	    case '^':			/* Don't group digits.  */
	      group = 0;
	      continue;
	    case '+':			/* Use +/- for sign of number.  */
	      if (n_sign_posn != -2)
		{
		  __set_errno (EINVAL);
		  return -1;
		}
	      p_sign_posn = *_NL_CURRENT (LC_MONETARY, P_SIGN_POSN);
	      n_sign_posn = *_NL_CURRENT (LC_MONETARY, N_SIGN_POSN);
	      continue;
	    case '(':			/* Use ( ) for negative sign.  */
	      if (n_sign_posn != -2)
		{
		  __set_errno (EINVAL);
		  return -1;
		}
	      p_sign_posn = 0;
	      n_sign_posn = 0;
	      continue;
	    case '!':			/* Don't print the currency symbol.  */
	      print_curr_symbol = 0;
	      continue;
	    case '-':			/* Print left justified.  */
	      left = 1;
	      continue;
	    default:
	      /* Will stop the loop.  */;
	    }
	  break;
	}

      if (isdigit (*fmt))
	{
	  /* Parse field width.  */
	  width = to_digit (*fmt);

	  while (isdigit (*++fmt))
	    {
	      int val = to_digit (*fmt);

	      if (width > LONG_MAX / 10
		  || (width == LONG_MAX && val > LONG_MAX % 10))
		{
		  __set_errno (E2BIG);
		  return -1;
		}

	      width = width * 10 + val;
	    }

	  /* If we don't have enough room for the demanded width we
	     can stop now and return an error.  */
	  if (width >= maxsize - (dest - s))
	    {
	      __set_errno (E2BIG);
	      return -1;
	    }
	}

      /* Recognize left precision.  */
      if (*fmt == '#')
	{
	  if (!isdigit (*++fmt))
	    {
	      __set_errno (EINVAL);
	      return -1;
	    }
	  left_prec = to_digit (*fmt);

	  while (isdigit (*++fmt))
	    {
	      left_prec *= 10;
	      left_prec += to_digit (*fmt);
	    }
	}

      /* Recognize right precision.  */
      if (*fmt == '.')
	{
	  if (!isdigit (*++fmt))
	    {
	      __set_errno (EINVAL);
	      return -1;
	    }
	  right_prec = to_digit (*fmt);

	  while (isdigit (*++fmt))
	    {
	      right_prec *= 10;
	      right_prec += to_digit (*fmt);
	    }
	}

      /* Handle modifier.  This is an extension.  */
      if (*fmt == 'L')
	{
	  ++fmt;
	  if (!__ldbl_is_dbl)
	    is_long_double = 1;
	}

      /* Handle format specifier.  */
      char int_symbol[4];
      switch (*fmt++)
	{
	case 'i': {		/* Use international currency symbol.  */
	  const char *int_curr_symbol;

	  int_curr_symbol = _NL_CURRENT (LC_MONETARY, INT_CURR_SYMBOL);
	  strncpy(int_symbol, int_curr_symbol, 3);
	  int_symbol[3] = '\0';

	  currency_symbol_len = 3;
	  currency_symbol = &int_symbol[0];
	  space_char = int_curr_symbol[3];
	  int_format = 1;
	  break;
	}
	case 'n':		/* Use national currency symbol.  */
	  currency_symbol = _NL_CURRENT (LC_MONETARY, CURRENCY_SYMBOL);
	  currency_symbol_len = strlen (currency_symbol);
	  space_char = ' ';
	  int_format = 0;
	  break;
	default:		/* Any unrecognized format is an error.  */
	  __set_errno (EINVAL);
	  return -1;
	}

      /* If not specified by the format string now find the values for
	 the format specification.  */
      if (p_sign_posn == -2)
	p_sign_posn = *_NL_CURRENT (LC_MONETARY, int_format ? INT_P_SIGN_POSN : P_SIGN_POSN);
      if (n_sign_posn == -2)
	n_sign_posn = *_NL_CURRENT (LC_MONETARY, int_format ? INT_N_SIGN_POSN : N_SIGN_POSN);

      if (right_prec == -1)
	{
	  right_prec = *_NL_CURRENT (LC_MONETARY, int_format ? INT_FRAC_DIGITS : FRAC_DIGITS);

	  if (right_prec == '\377')
	    right_prec = 2;
	}

      /* If we have to print the digits grouped determine how many
	 extra characters this means.  */
      if (group && left_prec != -1)
	left_prec += __guess_grouping (left_prec,
				       _NL_CURRENT (LC_MONETARY, MON_GROUPING),
				       *_NL_CURRENT (LC_MONETARY,
						     MON_THOUSANDS_SEP));

      /* Now it's time to get the value.  */
      if (is_long_double == 1)
	{
	  fpnum.ldbl = va_arg (ap, long double);
	  is_negative = fpnum.ldbl < 0;
	  if (is_negative)
	    fpnum.ldbl = -fpnum.ldbl;
	}
      else
	{
Пример #9
0
/**
 * \brief Get new time, successful value is put in new_date.year, new_date.month, new_date.day, new_date.week.
 */
static int get_new_date(void)
{
	char ucKey;
	int i = 0;

	/* clear setting variable */
	new_date.year = 0xFFFF;
	new_date.month = new_date.day = new_date.week = 0xFF;

	/* use time[] as a format template */
	while (1) {
		ucKey = console_get_char();

		/* end input */
		if (ucKey == 0x0d || ucKey == 0x0a) {
			printf("\r\n");
			break;
		}

		/* DEL or BACKSPACE */
		if (ucKey == 0x7f || ucKey == 0x08) {
			if (i > 0) {
				/* end of date[], index then one more back */
				if (!date[i]) {
					--i;
				}

				printf(pEraseSeq);
				--i;

				/* delimitor '/' for date is uneditable */
				if (!is_digit(date[i]) && i > 0) {
					printf(pEraseSeq);
					--i;
				}
			}
		}

		/* end of time[], no more input except above DEL/BS or enter to end */
		if (!date[i]) {
			continue;
		}

		if (!is_digit(ucKey)) {
			continue;
		}

		console_put_char(ucKey);
		date[i++] = ucKey;

		/* ignore non digit position */
		if (!is_digit(date[i]) && i < 10) {
			console_put_char(date[i]);
			++i;
		}
	}

	if (i == 0) {
		return 0;
	}

	if (i != 0 && date[i] != '\0' && i != 6) {
		return 1;	/* failure input */
	}

	/* MM-DD-YY */
	new_date.month = to_digit(date[0]) * 10 + to_digit(date[1]);
	new_date.day = to_digit(date[3]) * 10 + to_digit(date[4]);
	/* not scenario of getting mm/dd/ only for alarm */
	if (i != 6) {
		new_date.year =
		    to_digit(date[6]) * 1000 + to_digit(date[7]) * 100 +
		    to_digit(date[8]) * 10 + to_digit(date[9]);
		new_date.week = compute_week(new_date.year, new_date.month, new_date.day);
	}

	/* success input. verification of data is left to RTC internal Error Checking */
	return 0;
}
Пример #10
0
/**
 * \brief Get new time, successful value is put in new_time.hour, new_time.min, new_time.sec.
 */
static int get_new_time(void)
{
	char ucKey;
	int i = 0;

	/* clear setting variable */
	new_time.hour = new_time.min = new_time.sec = 0xFF;

	/* use time[] as a format template */
	while (1) {
		ucKey = console_get_char();

		/* end input */
		if (ucKey == 0x0d || ucKey == 0x0a) {
			printf("\r\n");
			break;
		}

		/* DEL or BACKSPACE */
		if (ucKey == 0x7f || ucKey == 0x08) {
			if (i > 0) {
				/* end of time[], index then one more back */
				if (!rtc_time[i]) {
					--i;
				}

				printf(pEraseSeq);
				--i;

				/* delimitor ':' for time is uneditable */
				if (!is_digit(rtc_time[i]) && i > 0) {
					printf(pEraseSeq);
					--i;
				}
			}
		}

		/* end of time[], no more input except above DEL/BS or enter to end */
		if (!rtc_time[i]) {
			continue;
		}

		if (!is_digit(ucKey)) {
			continue;
		}

		console_put_char(ucKey);
		rtc_time[i++] = ucKey;

		/* ignore non digit position if not end */
		if (!is_digit(rtc_time[i]) && i < 8) {
			console_put_char(rtc_time[i]);
			++i;
		}
	}

	if (i == 0) {
		return 0;
	}

	if (i != 0 && rtc_time[i] != '\0') {
		return 1;	/* failure input */
	}

	new_time.hour = to_digit(rtc_time[0]) * 10 + to_digit(rtc_time[1]);
	new_time.min = to_digit(rtc_time[3]) * 10 + to_digit(rtc_time[4]);
	new_time.sec = to_digit(rtc_time[6]) * 10 + to_digit(rtc_time[7]);

	/* success input. verification of data is left to RTC internal Error Checking */
	return 0;
}
Пример #11
0
static int
__v2printf(struct __printf_io *io, const char *fmt0, unsigned pct, va_list ap)
{
	struct printf_info	*pi, *pil;
	const char		*fmt;
	int			ch;
	struct printf_info	pia[pct + 10];
	int			argt[pct + 10];
	union arg		args[pct + 10];
	int			nextarg;
	int			maxarg;
	int			ret = 0;
	int			n;

	fmt = fmt0;
	maxarg = 0;
	nextarg = 1;
	memset(argt, 0, sizeof argt);
	for (pi = pia; ; pi++) {
		memset(pi, 0, sizeof *pi);
		pil = pi;
		if (*fmt == '\0')
			break;
		pil = pi + 1;
		pi->prec = -1;
		pi->pad = ' ';
		pi->begin = pi->end = fmt;
		while (*fmt != '\0' && *fmt != '%')
			pi->end = ++fmt;
		if (*fmt == '\0') 
			break;
		fmt++;
		for (;;) {
			pi->spec = *fmt;
			switch (pi->spec) {
			case ' ':
				/*-
				 * ``If the space and + flags both appear, the space
				 * flag will be ignored.''
				 *      -- ANSI X3J11
				 */
				if (pi->showsign == 0)
					pi->showsign = ' ';
				fmt++;
				continue;
			case '#':
				pi->alt = 1;
				fmt++;
				continue;
			case '.':
				pi->prec = 0;
				fmt++;
				if (*fmt == '*') {
					fmt++;
					pi->get_prec = nextarg;
					argt[nextarg++] = PA_INT;
					continue;
				}
				while (*fmt != '\0' && is_digit(*fmt)) {
					pi->prec *= 10;
					pi->prec += to_digit(*fmt);
					fmt++;
				}
				continue;
			case '-':
				pi->left = 1;
				fmt++;
				continue;
			case '+':
				pi->showsign = '+';
				fmt++;
				continue;
			case '*':
				fmt++;
				pi->get_width = nextarg;
				argt[nextarg++] = PA_INT;
				continue;
			case '%':
				fmt++;
				break;
			case '\'':
				pi->group = 1;
				fmt++;
				continue;
			case '0':
				/*-
				 * ``Note that 0 is taken as a flag, not as the
				 * beginning of a field width.''
				 *      -- ANSI X3J11
				 */
				pi->pad = '0';
				fmt++;
				continue;
			case '1': case '2': case '3':
			case '4': case '5': case '6':
			case '7': case '8': case '9':
				n = 0;
				while (*fmt != '\0' && is_digit(*fmt)) {
					n *= 10;
					n += to_digit(*fmt);
					fmt++;
				}
				if (*fmt == '$') {
					if (nextarg > maxarg)
						maxarg = nextarg;
					nextarg = n;
					fmt++;
				} else 
					pi->width = n;
				continue;
			case 'D':
			case 'O':
			case 'U':
				pi->spec += ('a' - 'A');
				pi->is_intmax = 0;
				if (pi->is_long_double || pi->is_quad) {
					pi->is_long = 0;
					pi->is_long_double = 1;
				} else {
					pi->is_long = 1;
					pi->is_long_double = 0;
				}
				fmt++;
				break;
			case 'j':
				pi->is_intmax = 1;
				fmt++;
				continue;
			case 'q':
				pi->is_long = 0;
				pi->is_quad = 1;
				fmt++;
				continue;
			case 'L':
				pi->is_long_double = 1;
				fmt++;
				continue;
			case 'h':
				fmt++;
				if (*fmt == 'h') {
					fmt++;
					pi->is_char = 1;
				} else {
					pi->is_short = 1;
				}
				continue;
			case 'l':
				fmt++;
				if (*fmt == 'l') {
					fmt++;
					pi->is_long_double = 1;
					pi->is_quad = 0;
				} else {
					pi->is_quad = 0;
					pi->is_long = 1;
				}
				continue;
			case 't':
				pi->is_ptrdiff = 1;
				fmt++;
				continue;
			case 'z':
				pi->is_size = 1;
				fmt++;
				continue;
			default:
				fmt++;
				break;
			}
			if (printf_tbl[pi->spec].arginfo == NULL)
				errx(1, "arginfo[%c] = NULL", pi->spec);
			ch = printf_tbl[pi->spec].arginfo(
			    pi, __PRINTFMAXARG, &argt[nextarg]);
			if (ch > 0)
				pi->arg[0] = &args[nextarg];
			if (ch > 1)
				pi->arg[1] = &args[nextarg + 1];
			nextarg += ch;
			break;
		}
	}
	if (nextarg > maxarg)
		maxarg = nextarg;
#if 0
	fprintf(stderr, "fmt0 <%s>\n", fmt0);
	fprintf(stderr, "pil %p\n", pil);
#endif
	for (ch = 1; ch < maxarg; ch++) {
#if 0
		fprintf(stderr, "arg %d %x\n", ch, argt[ch]);
#endif
		switch(argt[ch]) {
		case PA_CHAR:
			args[ch].intarg = (char)va_arg (ap, int);
			break;
		case PA_INT:
			args[ch].intarg = va_arg (ap, int);
			break;
		case PA_INT | PA_FLAG_SHORT:
			args[ch].intarg = (short)va_arg (ap, int);
			break;
		case PA_INT | PA_FLAG_LONG:
			args[ch].longarg = va_arg (ap, long);
			break;
		case PA_INT | PA_FLAG_INTMAX:
			args[ch].intmaxarg = va_arg (ap, intmax_t);
			break;
		case PA_INT | PA_FLAG_QUAD:
			args[ch].intmaxarg = va_arg (ap, long long);
			break;
		case PA_INT | PA_FLAG_LONG_LONG:
			args[ch].intmaxarg = va_arg (ap, long long);
			break;
		case PA_INT | PA_FLAG_SIZE:
			args[ch].intmaxarg = va_arg (ap, size_t);
			break;
		case PA_INT | PA_FLAG_PTRDIFF:
			args[ch].intmaxarg = va_arg (ap, ptrdiff_t);
			break;
		case PA_WCHAR:
#ifdef HAVE_WCHAR
			args[ch].wintarg = va_arg (ap, wint_t);
#endif
			break;
		case PA_POINTER:
			args[ch].pvoidarg = va_arg (ap, void *);
			break;
		case PA_STRING:
			args[ch].pchararg = va_arg (ap, char *);
			break;
		case PA_WSTRING:
#ifdef HAVE_WCHAR
			args[ch].pwchararg = va_arg (ap, wchar_t *);
#endif
			break;
		case PA_DOUBLE:
#ifndef NO_FLOATING_POINT
			args[ch].doublearg = va_arg (ap, double);
#endif
			break;
		case PA_DOUBLE | PA_FLAG_LONG_DOUBLE:
#ifndef NO_FLOATING_POINT
			args[ch].longdoublearg = va_arg (ap, long double);
#endif
			break;
		default:
			errx(1, "argtype = %x (fmt = \"%s\")\n",
			    argt[ch], fmt0);
		}
	}
	for (pi = pia; pi < pil; pi++) {
#if 0
		fprintf(stderr, "pi %p", pi);
		fprintf(stderr, " spec '%c'", pi->spec);
		fprintf(stderr, " args %d",
		    ((uintptr_t)pi->arg[0] - (uintptr_t)args) / sizeof args[0]);
		if (pi->width) fprintf(stderr, " width %d", pi->width);
		if (pi->pad) fprintf(stderr, " pad 0x%x", pi->pad);
		if (pi->left) fprintf(stderr, " left");
		if (pi->showsign) fprintf(stderr, " showsign");
		if (pi->prec != -1) fprintf(stderr, " prec %d", pi->prec);
		if (pi->is_char) fprintf(stderr, " char");
		if (pi->is_short) fprintf(stderr, " short");
		if (pi->is_long) fprintf(stderr, " long");
		if (pi->is_long_double) fprintf(stderr, " long_double");
		fprintf(stderr, "\n");
		fprintf(stderr, "\t\"%.*s\"\n", pi->end - pi->begin, pi->begin);
#endif
		if (pi->get_width) {
			pi->width = args[pi->get_width].intarg;
			/*-
			 * ``A negative field width argument is taken as a
			 * - flag followed by a positive field width.''
			 *      -- ANSI X3J11
			 * They don't exclude field widths read from args.
			 */
			if (pi->width < 0) {
				pi->left = 1;
				pi->width = -pi->width;
			}
		}
		if (pi->get_prec) 
			pi->prec = args[pi->get_prec].intarg;
		ret += __printf_puts(io, pi->begin, pi->end - pi->begin);
		if (printf_tbl[pi->spec].gnurender != NULL) {
			__printf_flush(io);
			pi->sofar = ret;
			ret += printf_tbl[pi->spec].gnurender(
			    io->u.fp, pi, (const void *)pi->arg);
		} else if (printf_tbl[pi->spec].render != NULL) {
			pi->sofar = ret;
			n = printf_tbl[pi->spec].render(
			    io, pi, (const void *)pi->arg);
			if (n < 0)
				; // io.fp->_flags |= __SERR;
			else
				ret += n;
		} else if (pi->begin == pi->end)
			errx(1, "render[%c] = NULL", *fmt);
	}
	__printf_flush(io);
	return (ret);
}