Beispiel #1
0
long long
llfrom_oct (int digs, char *where)
{
  long long value;

  while (ISSPACE (*where))
    {				/* skip spaces */
      where++;
      if (--digs <= 0)
	return -1;		/* all blank field */
    }
  value = 0;
  while (digs > 0 && ISODIGIT (*where))
    {
      /* Scan til nonoctal.  */

      value = (value << 3) | (*where++ - '0');
      --digs;
    }

  if (digs > 0 && *where && !ISSPACE (*where))
    return -1;			/* ended on non-space/nul */

  return value;
}
Beispiel #2
0
/*
 * unescape - handle C escapes in a string
 */
char *
unescape(char *orig)
{
	char c, *cp, *new = orig;
	int i;

	for (cp = orig; (*orig = *cp); cp++, orig++) {
		if (*cp != '\\')
			continue;

		switch (*++cp) {
		case 'a':	/* alert (bell) */
			*orig = '\a';
			continue;
		case 'b':	/* backspace */
			*orig = '\b';
			continue;
		case 'e':	/* escape */
			*orig = '\e';
			continue;
		case 'f':	/* formfeed */
			*orig = '\f';
			continue;
		case 'n':	/* newline */
			*orig = '\n';
			continue;
		case 'r':	/* carriage return */
			*orig = '\r';
			continue;
		case 't':	/* horizontal tab */
			*orig = '\t';
			continue;
		case 'v':	/* vertical tab */
			*orig = '\v';
			continue;
		case '\\':	/* backslash */
			*orig = '\\';
			continue;
		case '\'':	/* single quote */
			*orig = '\'';
			continue;
		case '\"':	/* double quote */
			*orig = '"';
			continue;
		case '0':
		case '1':
		case '2':
		case '3':	/* octal */
		case '4':
		case '5':
		case '6':
		case '7':	/* number */
			for (i = 0, c = 0;
			     ISODIGIT((unsigned char)*cp) && i < 3;
			     i++, cp++) {
				c <<= 3;
				c |= (*cp - '0');
			}
			*orig = c;
			--cp;
			continue;
		case 'x':	/* hexidecimal number */
			cp++;	/* skip 'x' */
			for (i = 0, c = 0;
			     isxdigit((unsigned char)*cp) && i < 2;
			     i++, cp++) {
				c <<= 4;
				if (isdigit((unsigned char)*cp))
					c |= (*cp - '0');
				else
					c |= ((toupper((unsigned char)*cp) -
					    'A') + 10);
			}
			*orig = c;
			--cp;
			continue;
		default:
			--cp;
			break;
		}
	}

	return (new);
}
Beispiel #3
0
//*****************************************************************************
// unescape( orig) - Return a string with escaped character sequences replaced 
// by the actual characters that the escape codes refer to.
char* unescape( char *orig)
{
  // Loop: Examine pointers to successive words of the string
  char c, *cp, *result = orig;
  int i;
  for( cp = orig; (*orig = *cp); cp++, orig++) {

    // If this is not an escape sequence, keep going
    if (*cp != '\\') continue;

    // Check for different escape sequences
    switch (*++cp) {
    case 'a':  /* alert (bell) */
      *orig = '\a';
      continue;
    case 'b':  /* backspace */
      *orig = '\b';
      continue;
    case 'e':  /* escape */
      *orig = '\e';
      continue;
    case 'f':  /* formfeed */
      *orig = '\f';
      continue;
    case 'n':  /* newline */
      *orig = '\n';
      continue;
    case 'r':  /* carriage return */
      *orig = '\r';
      continue;
    case 't':  /* horizontal tab */
      *orig = '\t';
      continue;
    case 'v':  /* vertical tab */
      *orig = '\v';
      continue;
    case '\\':  /* backslash */
      *orig = '\\';
      continue;
    case '\'':  /* single quote */
      *orig = '\'';
      continue;
    case '\"':  /* double quote */
      *orig = '"';
      continue;
    case '0':
    case '1':
    case '2':
    case '3':  /* octal */
    case '4':
    case '5':
    case '6':
    case '7':  /* number */
      for( i = 0, c = 0;
           ISODIGIT((unsigned char)*cp) && i < 3;
           i++, cp++) {
        c <<= 3;
        c |= (*cp - '0');
      }
      *orig = c;
      continue;
    case 'x':  /* hexidecimal number */
      cp++;  /* skip 'x' */
      for (i = 0, c = 0;
           isxdigit((unsigned char)*cp) && i < 2;
           i++, cp++) {
        c <<= 4;
        if (isdigit((unsigned char)*cp))
          c |= (*cp - '0');
        else
          c |= ((toupper((unsigned char)*cp) -
              'A') + 10);
      }
      *orig = c;
      continue;
    default:
      --cp;
      break;
    }
  }

  // Return result and quit
  return (result);
}
Beispiel #4
0
/*
 * ctpl_input_stream_read_number_internal:
 * @type: which kind of number match (float, int or both)
 * 
 * see ctpl_input_stream_read_number()
 */
static gboolean
ctpl_input_stream_read_number_internal (CtplInputStream *stream,
                                        gint             type,
                                        CtplValue       *value,
                                        GError         **error)
{
  gboolean  have_mantissa       = FALSE;
  gboolean  have_exponent       = FALSE;
  gboolean  have_exponent_delim = FALSE;
  gboolean  have_sign           = FALSE;
  gboolean  have_dot            = FALSE;
  GString  *gstring;
  GError   *err                 = NULL;
  gboolean  in_number           = TRUE;
  gint      base                = 10;
  
  #define ISSIGN(c)   ((c) == '+' || (c) == '-')
  #define ISDIGIT(c)  ((c) >= '0' && (c) <= '9')
  #define ISBDIGIT(c) ((c) == '0' || (c) == '1')
  #define ISODIGIT(c) ((c) >= '0' && (c) <= '7')
  #define ISXDIGIT(c) (ISDIGIT (c) || \
                       ((c) >= 'a' && (c) <= 'f') || \
                       ((c) >= 'A' && (c) <= 'F'))
  
  gstring = g_string_new ("");
  while (in_number && ! err) {
    gchar   buf[3];
    gssize  buf_len;
    
    buf_len = ctpl_input_stream_peek (stream, buf, sizeof (buf), &err);
    if (! err) {
      gchar c = (buf_len > 0) ? buf[0] : CTPL_EOF;
      
      switch (c) {
        case '.':
          if (! have_dot && ! have_exponent_delim && (type & READ_FLOAT)) {
            g_string_append_c (gstring, c);
            have_dot = TRUE;
            type &= READ_FLOAT;
          } else {
            in_number = FALSE;
          }
          break;
        
        case '+':
        case '-':
          if (! have_sign && (! have_mantissa ||
                              (have_exponent_delim && ! have_exponent)) &&
              /* ISDIGIT() is fine here even though we probably don't know the
               * base yet because the default base is 10 and the exponent or
               * power are also in base 10 */
              buf_len > 1 && ISDIGIT (buf[1])) {
            g_string_append_c (gstring, c);
            have_sign = TRUE;
          } else {
            in_number = FALSE;
          }
          break;
        
        case 'e':
        case 'E':
          if (base < 15) {
            if (have_mantissa && ! have_exponent_delim &&
                (type & READ_FLOAT) && base == 10 &&
                ((buf_len > 1 && ISDIGIT (buf[1])) ||
                 (buf_len > 2 && ISSIGN (buf[1]) && ISDIGIT (buf[2])))) {
              have_exponent_delim = TRUE;
              have_sign = FALSE;
              type &= READ_FLOAT;
              g_string_append_c (gstring, 'e');
            } else {
              in_number = FALSE;
            }
            break;
          }
          /* Fallthrough */
        case 'b':
        case 'B':
        case 'a':
        case 'A':
        case 'c':
        case 'C':
        case 'd':
        case 'D':
        case 'f':
        case 'F':
          if (base < 16 || have_exponent_delim /* exponent is decimal */) {
            in_number = FALSE;
            break;
          }
          /* Fallthrough */
        case '8':
        case '9':
          if (base < 10) {
            in_number = FALSE;
            break;
          }
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
          if (base < 8) {
            in_number = FALSE;
            break;
          }
          /* Fallthrough */
        case '0':
          if (! have_mantissa && buf_len > 2) {
            gboolean is_start = TRUE;
            
            if ((type & READ_INT) &&
                (buf[1] == 'b' || buf[1] == 'B') && ISBDIGIT (buf[2])) {
              type &= READ_INT;
              base = 2;
            } else if ((type & READ_INT) &&
                       (buf[1] == 'o' || buf[1] == 'O') && ISODIGIT (buf[2])) {
              type &= READ_INT;
              base = 8;
            } else if ((buf[1] == 'x' || buf[1] == 'X') && ISXDIGIT (buf[2])) {
              /* needed for floating-points */
              g_string_append_c (gstring, c);
              g_string_append_c (gstring, buf[1]);
              base = 16;
            } else {
              is_start = FALSE;
            }
            if (is_start) {
              /* eat the character we just handled. no need to check the error
               * since the data is already cached -- so no error can happen */
              ctpl_input_stream_get_c (stream, NULL);
              break;
            }
          }
          /* Fallthrough */
        case '1':
          g_string_append_c (gstring, c);
          if (! have_exponent_delim) {
            have_mantissa = TRUE;
          } else {
            have_exponent = TRUE;
          }
          break;
        
        case 'p':
        case 'P':
          if (have_mantissa && ! have_exponent_delim &&
              (type & READ_FLOAT) && base == 16 &&
              ((buf_len > 1 && ISDIGIT (buf[1])) ||
               (buf_len > 2 && ISSIGN (buf[1]) && ISDIGIT (buf[2])))) {
            have_exponent_delim = TRUE;
            have_sign = FALSE;
            type &= READ_FLOAT;
            g_string_append_c (gstring, 'p');
          } else {
            in_number = FALSE;
          }
          break;
        
        default:
          in_number = FALSE;
      }
      if (in_number) {
        ctpl_input_stream_get_c (stream, &err); /* eat character */
      }
    }
  }
  if (! err) {
    if (! have_mantissa) {
      ctpl_input_stream_set_error (stream, &err, CTPL_IO_ERROR,
                                   CTPL_IO_ERROR_INVALID_NUMBER,
                                   "Missing mantissa in numeric constant");
    } else {
      gchar  *nptr = gstring->str;
      gchar  *endptr;
      gdouble dblval = 0.0;
      glong   longval = 0;
      gint    errno_save = errno;
      
      errno = 0;
      if (type & READ_INT) {
        longval = strtol (nptr, &endptr, base);
      } else {
        dblval = g_ascii_strtod (nptr, &endptr);
      }
      if (! endptr || *endptr != 0) {
        ctpl_input_stream_set_error (stream, &err, CTPL_IO_ERROR,
                                     CTPL_IO_ERROR_INVALID_NUMBER,
                                     "Invalid base %d numeric constant \"%s\"",
                                     base, nptr);
      } else if (errno == ERANGE) {
        ctpl_input_stream_set_error (stream, &err, CTPL_IO_ERROR,
                                     CTPL_IO_ERROR_RANGE,
                                     "Overflow in numeric constant conversion");
      } else {
        if (type & READ_INT) {
          ctpl_value_set_int (value, longval);
        } else {
          ctpl_value_set_float (value, dblval);
        }
      }
      errno = errno_save;
    }
  }
  if (err) {
    g_propagate_error (error, err);
  }
  g_string_free (gstring, TRUE);
  
  #undef ISSIGN
  #undef ISDIGIT
  #undef ISBDIGIT
  #undef ISODIGIT
  #undef ISXDIGIT
  
  return ! err;
}