예제 #1
0
파일: parser.c 프로젝트: jsiembida/splinter
static atom_p parse_list(parsebuf_p pb, expression_callback_t out, int indentation)
{
  int c, i, terminator;
  atom_p first, prev, curr;
  struct __operator * operator;
  parsebuf_t buf;
  DEBUG();

  // Grab the opening parenthesis, or whatever it is
  __consume_whitespace(pb);
  __parsebuf_snapshot(pb, &buf);
  if((c = __parsebuf_next(pb)) == '(') {
    terminator = ')';
  } else if(c == '[') {
    terminator = ']';
  } else if(c == '<') {
    terminator = '>';
  } else if(c == '{') {
    terminator = '}';
  } else {
    splinter_error_return(NULL, "%s invalid list opening @ %d:%d", buf.n, buf.l, buf.c);
  }

  __consume_whitespace(pb);
  if ((operator = __find_closest_token(pb, terminator)) == NULL)
    return NULL;

  __parse_out_indentation(out, indentation);
  __parse_out_char(out, c);
  __parse_out_string(out, operator->token, (int)strlen(operator->token));

  for(first = prev = curr = NULL; 1;) {
    __consume_whitespace(pb);
    i = pb->i;
    __parse_out_char(out, '\n');
    if((c = __parsebuf_next(pb)) <= 0) {
      splinter_error_set("%s missing list closing @ %d:%d", buf.n, pb->l, pb->c);
      return atom_free(first);
    } else if(c == terminator) {
      if ((curr = atom_alloc_list(operator->exec_call, first)) == NULL) {
        return atom_free(first);
      }
      __parse_out_indentation(out, indentation);
      __parse_out_char(out, terminator);
      return curr;
    } else if(c == '0' && (__parsebuf_peek(pb) == 'x' || __parsebuf_peek(pb) == 'X')) {
      __parsebuf_prev(pb);
      curr = parse_hex(pb, operator->mode);
      if (curr != NULL) __parse_out_line(out, pb->s + i, pb->i - i, indentation + 2);
    } else if('0' <= c && c <= '9') {
      __parsebuf_prev(pb);
      curr = (c == '0') ? parse_oct(pb, operator->mode) : parse_uint(pb, operator->mode);
      if (curr != NULL) __parse_out_line(out, pb->s + i, pb->i - i, indentation + 2);
    } else if(c == '-' && ('0' <= __parsebuf_peek(pb) && __parsebuf_peek(pb) <= '9')) {
      __parsebuf_prev(pb);
      curr = parse_int(pb, operator->mode);
      if (curr != NULL) __parse_out_line(out, pb->s + i, pb->i - i, indentation + 2);
    } else if(c == '(' || c == '[' || c == '<' || c == '{') {
      __parsebuf_prev(pb);
      curr = parse_list(pb, out, indentation + 2);
    } else if(c == '\'') {
      curr = parse_string(pb, '\'', operator->mode);
      if (curr != NULL) __parse_out_line(out, pb->s + i, pb->i - i, indentation + 2);
    } else if(c == '"') {
      curr = parse_string(pb, '"', operator->mode);
      if (curr != NULL) __parse_out_line(out, pb->s + i, pb->i - i, indentation + 2);
    } else if (c == '$') {
      __parsebuf_prev(pb);
      curr = parse_variable(pb, terminator, operator->mode);
      if (curr != NULL) __parse_out_line(out, (char *)curr->data, strlen((char *)curr->data), indentation + 2);
    } else if (c == '@') {
      __parsebuf_prev(pb);
      curr = parse_symbol(pb, terminator, operator->mode);
      if (curr != NULL) __parse_out_line(out, pb->s + i, pb->i - i, indentation + 2);
    } else {
      curr = NULL;
    }

    if(curr == NULL) {
      return atom_free(first);
    }

    if(first == NULL) {
      first = prev = curr;
    } else {
      prev->next = curr;
      prev = curr;
    }
  }
}
예제 #2
0
파일: config.c 프로젝트: multiplay/qstat
STATIC char *
parse_value(char *source, int len)
{
	char *value, *v, *end;
	int error = 0;

	value = (char *)malloc(len + 1);
	end = v = value;

/*
 * printf( "parse_value <%.*s>\n", len, source);
 */

	for ( ; len; len--, source++) {
		if (*source != '\\') {
			*v++ = *source;
			if (*source != ' ') {
				end = v;
			}
			continue;
		}
		source++;
		len--;
		if (len == 0) {
			break;
		}
		if (*source == '\\') {
			*v++ = *source;
		} else if (*source == 'n') {
			*v++ = '\n';
		} else if (*source == 'r') {
			*v++ = '\r';
		} else if (*source == ' ') {
			*v++ = ' ';
		} else if (*source == 'x') {
			source++;
			len--;
			if (len < 2) {
				break;
			}
			*v++ = parse_hex(source, 2, &error);
			if (error) {
				break;
			}
			source++;
			len--;
		} else if (isdigit((unsigned char)*source)) {
			if (len < 3) {
				break;
			}
			*v++ = parse_oct(source, 3, &error);
			if (error) {
				break;
			}
			source++;
			len--;
			source++;
			len--;
		} else {
			error = 1;
			REPORT_ERROR((stderr, "Invalid character escape \"%.*s\"", 2,
			    source - 1));
			break;
		}
		end = v;
	}

	if (error) {
		free(value);
		return (NULL);
	}

	value_len = end - value;
	memcpy(token_buf, value, value_len);
	token_buf[value_len] = '\0';

	free(value);
	return (&token_buf[0]);
}