#undef ENTRY
};
+/*
+ * Static node for out of memory errors. Only "type" is used. lineno is
+ * always left at 0. The rest of the node content can be overwritten,
+ * but is never used.
+ */
+static struct ctf_node error_node = {
+ .type = NODE_ERROR,
+};
+
BT_HIDDEN
const char *node_type(struct ctf_node *node)
{
return gstr;
}
-/*
- * note: never use gc_string_append on a string that has external references.
- * gsrc will be garbage collected immediately, and gstr might be.
- * Should only be used to append characters to a string literal or constant.
- */
-BT_HIDDEN
-struct gc_string *gc_string_append(struct ctf_scanner *scanner,
- struct gc_string *gstr,
- struct gc_string *gsrc)
-{
- size_t newlen = strlen(gsrc->s) + strlen(gstr->s) + 1;
- size_t alloclen;
-
- /* TODO: could be faster with find first bit or glib Gstring */
- /* sizeof long to account for malloc header (int or long ?) */
- for (alloclen = 8; alloclen < sizeof(long) + sizeof(*gstr) + newlen;
- alloclen *= 2);
-
- if (alloclen > gstr->alloclen) {
- struct gc_string *newgstr;
-
- newgstr = gc_string_alloc(scanner, newlen);
- strcpy(newgstr->s, gstr->s);
- strcat(newgstr->s, gsrc->s);
- bt_list_del(&gstr->gc);
- free(gstr);
- gstr = newgstr;
- } else {
- strcat(gstr->s, gsrc->s);
- }
- bt_list_del(&gsrc->gc);
- free(gsrc);
- return gstr;
-}
-
void setstring(struct ctf_scanner *scanner, YYSTYPE *lvalp, const char *src)
{
lvalp->gs = gc_string_alloc(scanner, strlen(src) + 1);
return 0;
}
+static
+int bt_isodigit(int c)
+{
+ switch (c) {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+static
+int parse_base_sequence(const char *src, size_t len, size_t pos,
+ char *buffer, size_t *buf_len, int base)
+{
+ const size_t max_char = 3;
+ int nr_char = 0;
+
+ while (!str_check(len, pos, 1) && nr_char < max_char) {
+ char c = src[pos++];
+
+ if (base == 8) {
+ if (bt_isodigit(c))
+ buffer[nr_char++] = c;
+ else
+ break;
+ } else if (base == 16) {
+ if (isxdigit(c))
+ buffer[nr_char++] = c;
+ else
+ break;
+
+ } else {
+ /* Unsupported base */
+ return -1;
+ }
+ }
+ assert(nr_char > 0);
+ buffer[nr_char] = '\0';
+ *buf_len = nr_char;
+ return 0;
+}
+
static
int import_basic_string(struct ctf_scanner *scanner, YYSTYPE *lvalp,
size_t len, const char *src, char delim)
c = src[pos++];
switch (c) {
- case '0':
- c = '\0';
- break;
case 'a':
c = '\a';
break;
case '?':
c = '?';
break;
- case 'o':
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
{
- size_t oct_len = 3;
+ char oct_buffer[4];
+ size_t oct_len;
- if (str_check(len, pos, oct_len))
+ if (parse_base_sequence(src, len, pos - 1,
+ oct_buffer, &oct_len, 8))
return -1;
- if (!isdigit((int) src[pos]) || !isdigit((int) src[pos+1]) || !isdigit((int) src[pos+2]))
- return -1;
- char oct_buffer[4] = { src[pos], src[pos+1], src[pos+2], '\0' };
c = strtoul(&oct_buffer[0], NULL, 8);
- pos += oct_len;
+ pos += oct_len - 1;
break;
}
case 'x':
{
- size_t hex_len = 2;
+ char hex_buffer[4];
+ size_t hex_len;
- if (str_check(len, pos, hex_len))
- return -1;
- if (!isxdigit((int) src[pos]) || !isxdigit((int) src[pos+1]))
+ if (parse_base_sequence(src, len, pos,
+ hex_buffer, &hex_len, 16))
return -1;
- char hex_buffer[3] = { src[pos], src[pos+1], '\0' };
c = strtoul(&hex_buffer[0], NULL, 16);
pos += hex_len;
break;
struct ctf_node *node;
node = malloc(sizeof(*node));
- if (!node)
- return NULL;
+ if (!node) {
+ printfl_fatal(yyget_lineno(scanner->scanner), "out of memory");
+ return &error_node;
+ }
memset(node, 0, sizeof(*node));
node->type = type;
node->lineno = yyget_lineno(scanner->scanner);
switch (type) {
case NODE_ROOT:
+ node->type = NODE_ERROR;
printfn_fatal(node, "trying to create root node");
break;
case NODE_UNKNOWN:
default:
+ node->type = NODE_ERROR;
printfn_fatal(node, "unknown node type '%d'", (int) type);
break;
}
}
| LPAREN unary_expression RPAREN
{
- $$ = make_node(scanner, NODE_UNARY_EXPRESSION);
- $$->u.unary_expression.type = UNARY_NESTED;
- $$->u.unary_expression.u.nested_exp = $2;
+ $$ = $2;
}
| postfix_expression LSBRAC unary_expression RSBRAC
{