Ejemplo n.º 1
0
int pr_str2gid(const char *val, gid_t *gid) {
#ifdef HAVE_STRTOULL
  unsigned long long ull = 0ULL;
#endif /* HAVE_STRTOULL */
  unsigned long ul = 0UL;

  if (val == NULL ||
      gid == NULL) {
    errno = EINVAL;
    return -1;
  }

#if SIZEOF_GID_T == SIZEOF_LONG_LONG
# ifdef HAVE_STRTOULL
  if (parse_ull(val, &ull) < 0) {
    return -1;
  }
  *gid = ull; 

# else
  if (parse_ul(val, &ul) < 0) {
    return -1;
  }
  *gid = ul;
# endif /* HAVE_STRTOULL */
#else
  (void) ull;
  if (parse_ul(val, &ul) < 0) {
    return -1;
  }
  *gid = ul;
#endif /* sizeof(gid_t) != sizeof(long long) */

  return 0;
}
Ejemplo n.º 2
0
uint32_t parse_codepoint( char const *s ) {
  assert( s );

  if ( s[0] && !s[1] )                  // assume single-char ASCII
    return (uint32_t)s[0];

  char const *const s0 = s;
  if ( (s[0] == 'U' || s[0] == 'u') && s[1] == '+' ) {
    // convert [uU]+NNNN to 0xNNNN so strtoull() will grok it
    char *const t = freelist_add( check_strdup( s ) );
    s = memcpy( t, "0x", 2 );
  }
  uint64_t const codepoint = parse_ull( s );
  if ( codepoint_is_valid( codepoint ) )
    return (uint32_t)codepoint;         
  PMESSAGE_EXIT( USAGE,
    "\"%s\": invalid Unicode code-point for -%c\n",
    s0, 'U'
  );
}
Ejemplo n.º 3
0
// parses the memwatch data format from a string
unsigned long long read_string_data(const char* in, void** vdata, void** vmask) {

  *vdata = NULL;
  if (vmask)
    *vmask = NULL;
  unsigned char** data = (unsigned char**)vdata;
  unsigned char** mask = (unsigned char**)vmask;

  int read, chr = 0;
  int string = 0, unicode_string = 0, comment = 0, multiline_comment = 0, high = 1;
  int filename = 0, filename_start;
  unsigned long size = 0;
  int endian = 0;
  while (in[0]) {
    read = 0;

    // if between // and a newline, don't write to output buffer
    if (comment) {
      if (in[0] == '\n')
        comment = 0;
      in++;

    // if between /* and */, don't write to output buffer
    } else if (multiline_comment) {
      if (in[0] == '*' && in[1] == '/') {
        multiline_comment = 0;
        in++;
      }
      in++;

    // if between quotes, read bytes to output buffer, unescaping
    } else if (string) {
      if (in[0] == '\"')
        string = 0;
      else if (in[0] == '\\') { // unescape char after a backslash
        if (!in[1])
          return size;
        if (in[1] == 'n') {
          write_byte('\n');
        } else if (in[1] == 'r') {
          write_byte('\r');
        } else if (in[1] == 't') {
          write_byte('\t');
        } else {
          write_byte(in[1]);
        }
        in++;
      } else
        write_byte(in[0]);
      in++;

    // if between single quotes, word-expand bytes to output buffer, unescaping
    } else if (unicode_string) {
      if (in[0] == '\'')
        unicode_string = 0;
      else if (in[0] == '\\') { // unescape char after a backslash
        if (!in[1])
          return size;
        if (in[1] == 'n') {
          write_short('\n');
        } else if (in[1] == 'r') {
          write_short('\r');
        } else if (in[1] == 't') {
          write_short('\t');
        } else {
          write_short(in[1]);
        }
        if (endian)
          bswap(&(*data)[size - 2], 2);
        in++;
      } else {
        write_short(in[0]);
        if (endian)
          bswap(&(*data)[size - 2], 2);
      }
      in++;

    // if between <>, read a file name, then stick that file into the buffer
    } else if (filename) {
      if (in[0] == '>') {
        filename = 0;
        write_byte(0); // null-terminate the filename
        // TODO: support <filename@offset:size> syntax

        // open the file, read it into the buffer, close the file
        FILE* f = fopen((char*)(*data + filename_start), "rb");
        if (!f) {
          if (data)
            free(data);
          return 0;
        }
        fseek(f, 0, SEEK_END);
        int file_size = ftell(f);
        size = filename_start + file_size;
        *data = realloc(*data, size);
        fseek(f, 0, SEEK_SET);
        fread((*data + filename_start), 1, file_size, f);
        fclose(f);
      } else
        write_byte(in[0]);
      in++;

    // ? is an unknown byte, but only if the caller wants a mask
    } else if (in[0] == '?' && vmask) {
      write_blank();
      in++;

    // $ changes the endian-ness
    } else if (in[0] == '$') {
      endian = !endian;
      in++;

    // # signifies a decimal number
    } else if (in[0] == '#') { // 8-bit
      unsigned long long value;
      in++;
      if (in[0] == '#') { // 16-bit
        in++;
        if (in[0] == '#') { // 32-bit
          in++;
          if (in[0] == '#') { // 64-bit
            in++;
            expand(8);
            parse_ull(in, (unsigned long long*)(&((*data)[size - 8])), 0);
            if (endian)
              bswap(&((*data)[size - 8]), 8);
            if (mask)
              *(unsigned long long*)(&((*mask)[size - 8])) = 0xFFFFFFFFFFFFFFFF;
          } else {
            expand(4);
            parse_ull(in, &value, 0);
            if (endian)
              bswap(&value, 4);
            *(int32_t*)(&((*data)[size - 4])) = value;
            if (mask)
              *(uint32_t*)(&((*mask)[size - 4])) = 0xFFFFFFFF;
          }
        } else {
          expand(2);
          parse_ull(in, &value, 0);
          if (endian)
            bswap(&value, 2);
          *(int16_t*)(&((*data)[size - 2])) = value;
          if (mask)
            *(uint16_t*)(&((*mask)[size - 2])) = 0xFFFF;
        }
      } else {
        expand(1);
        parse_ull(in, &value, 0);
        *(int8_t*)(&((*data)[size - 1])) = value;
        if (mask)
          *(uint8_t*)(&((*mask)[size - 1])) = 0xFF;
      }
      if (in[0] == '-')
        in++;
      while (isdigit(in[0]))
        in++;

    // % is a float, %% is a double
    } else if (in[0] == '%') {
      in++;
      if (in[0] == '%') {
        in++;
        expand(8);
        double* value = (double*)(&((*data)[size - 8]));
        sscanf(in, "%lf", value);
        if (endian)
          bswap(value, 8);
        if (mask)
          *(unsigned long long*)(&((*mask)[size - 8])) = 0xFFFFFFFFFFFFFFFF;
      } else {
        expand(4);
        float* value = (float*)(&((*data)[size - 4]));
        sscanf(in, "%f", value);
        if (endian)
          bswap(value, 4);
        if (mask)
          *(uint32_t*)(&((*mask)[size - 4])) = 0xFFFFFFFF;
      }
      if (in[0] == '-')
        in++;
      while (isdigit(in[0]) || (in[0] == '.'))
        in++;

    // anything else is a hex digit
    } else {
      if ((in[0] >= '0') && (in[0] <= '9')) {
        read = 1;
        chr |= (in[0] - '0');
      }
      if ((in[0] >= 'A') && (in[0] <= 'F')) {
        read = 1;
        chr |= (in[0] - 'A' + 0x0A);
      }
      if ((in[0] >= 'a') && (in[0] <= 'f')) {
        read = 1;
        chr |= (in[0] - 'a' + 0x0A);
      }
      if (in[0] == '\"')
        string = 1;
      if (in[0] == '\'')
        unicode_string = 1;
      if (in[0] == '/' && in[1] == '/')
        comment = 1;
      if (in[0] == '/' && in[1] == '*')
        multiline_comment = 1;
      if (in[0] == '<') {
        filename = 1;
        filename_start = size;
      }
      in++;
    }

    if (read) {
      if (high)
        chr = chr << 4;
      else {
        write_byte(chr);
        chr = 0;
      }
      high = !high;
    }
  }
  return size;
}