Пример #1
0
/*-------------------------------------------------------------------------*
 * PL_NUMBER_CODES_2                                                       *
 *                                                                         *
 *-------------------------------------------------------------------------*/
Bool
Pl_Number_Codes_2(WamWord number_word, WamWord codes_word)
{
  WamWord word, tag_mask;
  WamWord *lst_adr, list_word;
  char *str = pl_glob_buff;
  PlLong c;

  list_word = codes_word;
  for (;;)
    {
      DEREF(list_word, word, tag_mask);

      if (word == NIL_WORD)
	break;

      if (tag_mask != TAG_LST_MASK)
	goto from_nb;

      lst_adr = UnTag_LST(word);
      DEREF(Car(lst_adr), word, tag_mask);
      c = UnTag_INT(word);
      if (tag_mask != TAG_INT_MASK || !Is_Valid_Code(c))
	goto from_nb;

      *str++ = (char) c;
      list_word = Cdr(lst_adr);
    }

  *str = '\0';
  return String_To_Number(pl_glob_buff, number_word);

from_nb:
  DEREF(number_word, word, tag_mask);
  if (tag_mask == TAG_INT_MASK)
    {
      sprintf(pl_glob_buff, "%" PL_FMT_d, UnTag_INT(word));
      return Pl_Un_Codes_Check(pl_glob_buff, codes_word);
    }

  if (tag_mask != TAG_REF_MASK)
    {
      str = Pl_Float_To_String(Pl_Rd_Number_Check(word));
      return Pl_Un_Codes_Check(str, codes_word);
    }

  Pl_Rd_Codes_Check(codes_word);	/* only to raise the correct error */
  return FALSE;
}
Пример #2
0
/*-------------------------------------------------------------------------*
 * FORMAT                                                                  *
 *                                                                         *
 *-------------------------------------------------------------------------*/
static void
Format(StmInf *pstm, char *format, WamWord *lst_adr)

#define IMPOSS -12345678

{
  WamWord word;
  Bool has_n;
  long generic;
  long n, n1;
  char *p;
  long x;
  double d;
  int lg, stop;
  int i, k;
  char *format_stack[256];
  char **top_stack = format_stack;
  char buff[2048];


  *top_stack++ = format;
  do
    {
      format = *--top_stack;

      while (*format)
	{
	  if (*format == '%')	/* C printf format */
	    {
	      if (format[1] == '%')
		{
		  Pl_Stream_Putc('%', pstm);
		  format += 2;
		  continue;
		}

	      p = buff;
	      n = n1 = IMPOSS;

	      do
		if ((*p++ = *format++) == '*')
		  {
		    if (n == IMPOSS)
		      n = Arg_Integer(&lst_adr);
		    else
		      n1 = Arg_Integer(&lst_adr);
		  }
	      while ((char *) strchr("diouxXpnceEfgGs", p[-1]) == NULL);

	      *p = '\0';
	      if (strchr("eEfgG", p[-1]) == NULL)
		{
		  generic = (p[-1] == 's') ? (long) Arg_Atom(&lst_adr)
		    : Arg_Integer(&lst_adr);
		  if (n != IMPOSS)
		    {
		      if (n1 != IMPOSS)
			Pl_Stream_Printf(pstm, buff, n, n1, generic);
		      else
			Pl_Stream_Printf(pstm, buff, n, generic);
		    }
		  else
		    Pl_Stream_Printf(pstm, buff, generic);
		}
	      else
		{
		  d = Arg_Float(&lst_adr);
		  if (n != IMPOSS)
		    {
		      if (n1 != IMPOSS)
			Pl_Stream_Printf(pstm, buff, n, n1, d);
		      else
			Pl_Stream_Printf(pstm, buff, n, d);
		    }
		  else
		    Pl_Stream_Printf(pstm, buff, d);
		}
	      continue;
	    }

	  if (*format != '~')
	    {
	      Pl_Stream_Putc(*format, pstm);
	      format++;
	      continue;
	    }

	  if (*++format == '*')
	    {
	      n = Arg_Integer(&lst_adr);
	      format++;
	      has_n = TRUE;
	    }
	  else
	    {
	      p = format;
	      n = strtol(format, &format, 10);
	      has_n = (format != p);
	    }



	  switch (*format)
	    {
	    case 'a':
	      p = Arg_Atom(&lst_adr);
	      if (has_n)
		Pl_Stream_Printf(pstm, "%*s", -n, p);
	      else
		Pl_Stream_Puts(p, pstm);
	      break;

	    case 'c':
	      x = Arg_Integer(&lst_adr);
	      if (!Is_Valid_Code(x))
		Pl_Err_Representation(pl_representation_character_code);

	      do
		Pl_Stream_Putc(x, pstm);
	      while (--n > 0);
	      break;

	    case 'e':
	    case 'E':
	    case 'f':
	    case 'g':
	    case 'G':
	      x = *format;
	      d = Arg_Float(&lst_adr);

	      if (has_n)
		sprintf(buff, "%%.%ld%c", n, (char) x);
	      else
		sprintf(buff, "%%%c", (char) x);

	      Pl_Stream_Printf(pstm, buff, d);
	      break;

	    case 'd':
	    case 'D':
	      x = Arg_Integer(&lst_adr);

	      if (n == 0 && *format == 'd')
		{
		  Pl_Stream_Printf(pstm, "%ld", x);
		  break;
		}

	      if (x < 0)
		{
		  Pl_Stream_Putc('-', pstm);
		  x = -x;
		}

	      sprintf(buff, "%ld", x);
	      lg = strlen(buff) - n;
	      if (lg <= 0)
		{
		  Pl_Stream_Puts("0.", pstm);
		  for (i = 0; i < -lg; i++)
		    Pl_Stream_Putc('0', pstm);
		  Pl_Stream_Printf(pstm, "%ld", x);
		  break;
		}


	      stop = (*format == 'D') ? lg % 3 : -1;

	      if (stop == 0)
		stop = 3;

	      for (p = buff, i = 0; *p; p++, i++)
		{
		  if (i == lg)
		    Pl_Stream_Putc('.', pstm), stop = -1;

		  if (i == stop)
		    Pl_Stream_Putc(',', pstm), stop += 3;
		  Pl_Stream_Putc(*p, pstm);
		}
	      break;

	    case 'r':
	    case 'R':
	      x = Arg_Integer(&lst_adr);

	      if (!has_n || n < 2 || n > 36)
		n = 8;

	      k = ((*format == 'r') ? 'a' : 'A') - 10;

	      if (x < 0)
		{
		  Pl_Stream_Putc('-', pstm);
		  x = -x;
		}

	      p = buff + sizeof(buff) - 1;
	      *p = '\0';
	      do
		{
		  i = x % n;
		  x = x / n;
		  --p;
		  *p = (i < 10) ? i + '0' : i + k;
		}
	      while (x);
	      Pl_Stream_Puts(p, pstm);
	      break;

	    case 's':
	    case 'S':
	      word = Read_Arg(&lst_adr);
	      if (*format == 's')
		p = Pl_Rd_Codes_Check(word);
	      else
		p = Pl_Rd_Chars_Check(word);

	      if (has_n)
		Pl_Stream_Printf(pstm, "%-*.*s", n, n, p);
	      else
		Pl_Stream_Printf(pstm, "%s", p);
	      break;

	    case 'i':
	      do
		Read_Arg(&lst_adr);
	      while (--n > 0);
	      break;

	    case 'k':
	      word = Read_Arg(&lst_adr);
	      Pl_Write_Term(pstm, -1, MAX_PREC,
			 WRITE_IGNORE_OP | WRITE_QUOTED, word);
	      break;

	    case 'q':
	      word = Read_Arg(&lst_adr);
	      Pl_Write_Term(pstm, -1, MAX_PREC, WRITE_NUMBER_VARS |
			 WRITE_NAME_VARS | WRITE_QUOTED, word);
	      break;

	    case 'p':		/* only work if print.pl is linked */
	      word = Read_Arg(&lst_adr);
	      Pl_Write_Term(pstm, -1, MAX_PREC, WRITE_NUMBER_VARS |
			 WRITE_NAME_VARS | WRITE_PORTRAYED, word);
	      break;

	    case 'w':
	      word = Read_Arg(&lst_adr);
	      Pl_Write_Term(pstm, -1, MAX_PREC, WRITE_NUMBER_VARS |
			 WRITE_NAME_VARS, word);
	      break;

	    case '~':
	      Pl_Stream_Putc('~', pstm);
	      break;

	    case 'N':
	      if (pstm->line_pos == 0)
		break;
	    case 'n':
	      do
		Pl_Stream_Putc('\n', pstm);
	      while (--n > 0);
	      break;

	    case '?':
	      if (format[1])
		*top_stack++ = format + 1;

	      format = Arg_Atom(&lst_adr);
	      continue;

	    default:
	      Pl_Err_Domain(pl_domain_format_control_sequence,
			    Tag_ATM(ATOM_CHAR(*format)));
	    }
	  format++;
	}
    }
  while (top_stack > format_stack);
}
Пример #3
0
/*-------------------------------------------------------------------------*
 * SCAN_QUOTED_CHAR                                                        *
 *                                                                         *
 *-------------------------------------------------------------------------*/
static int
Scan_Quoted_Char(StmInf *pstm, Bool convert, int c0, Bool no_escape)
{
  int radix;
  char *p, *f;
  int x, i;

  Read_Next_Char(pstm, convert);
  if (c == c0)
    {
      if (Pl_Scan_Peek_Char(pstm, convert) != c0)	/* '' or "" or `` */
	return -1;					/* closing quote */

      Read_Next_Char(pstm, convert);
      return c;
    }

  if (c == EOF)
    {
      if (err_msg == NULL)
	{
	  Unget_Last_Char;
	  pl_token.line = pstm->line_count + 1;
	  pl_token.col = pstm->line_pos + 1;
	  err_msg = "unexpected end of file";
	}
      return -3;		/* -3 means EOF */
    }

  if (c == '\n')
    {
      if (err_msg == NULL)
	{
	  Unget_Last_Char;
	  pl_token.line = pstm->line_count + 1;
	  pl_token.col = pstm->line_pos + 1;
	  err_msg = "unexpected newline";
	}
      return -4;		/* -4 means newline */
    }

  if (c == '\t')
    {
      if (err_msg == NULL)
	{
	  Unget_Last_Char;
	  pl_token.line = pstm->line_count + 1;
	  pl_token.col = pstm->line_pos + 1;
	  err_msg = "unexpected tab";
	}
      return -5;		/* -5 means tab */
    }

  if (c != '\\' || no_escape)
    return c;

  				/* \...  escape sequences */

  Read_Next_Char(pstm, convert);

  if (c == '\n')		/* \ followed by newline */
    return -2;			/* -2 means \ newline */

  if (strchr("\\'\"`", c))	/* \\ or \' or \" or \` */
    return c;

  if ((p = (char *) strchr(pl_escape_symbol, c)))	/* \a \b \f \n \r \t \v */
    return pl_escape_char[p - pl_escape_symbol];

  if (!Flag_Value(strict_iso))
    {
      if (c == 's')		/* \s = space */
	return ' ';

      if (c == 'e')		/* ESCAPE */
	return 27;
    }

  if (c == 'x' || ('0' <= c && c <= '7'))	/* \xnn\ \nn\ */
    {
      if (c == 'x')
	{
	  radix = 16;
	  f = "0123456789abcdefABCDEF";
	  x = 0;
	}
      else
	{
	  radix = 8;
	  f = "01234567";
	  x = c - '0';
	}

      Read_Next_Char(pstm, convert);
      while ((p = strchr(f, c)) != NULL)
	{
	  i = p - f;
	  if (i >= 16)
	    i -= 6;
	  x = x * radix + i;
	  Read_Next_Char(pstm, convert);
	}

      if (!Is_Valid_Code(x))
	{
	  if (err_msg == NULL)
	    {
	      pl_token.line = pstm->line_count + 1;
	      pl_token.col = pstm->line_pos;
	      err_msg = "invalid character code in \\constant\\ sequence";
	    }
	  goto pump;
	}

      if (c != '\\')
	{
	  if (err_msg == NULL)
	    {
	      pl_token.line = pstm->line_count + 1;
	      pl_token.col = pstm->line_pos;
	      err_msg = "\\ expected in \\constant\\ sequence";
	    }

	  /* pump until \ or closing quote or newline is found */
	pump:
	  while(c != '\\' && c != c0 && c != EOF && c != '\n')
	    Read_Next_Char(pstm, convert);
	  if (c == c0)
	    Unget_Last_Char;	/* to be able to continue in the parent's loop */

	  return -6;		/* -6 means other error */
	}

      return (int) (unsigned char) x;
    }

  if (err_msg == NULL)
    {
      pl_token.line = pstm->line_count + 1;
      pl_token.col = pstm->line_pos;
      err_msg = "unknown escape sequence";
    }

  return -6;		/* -6 means other error */
}