_ERROR(OSL, "osl error") \
_ERROR(SIGNAL_SIG_ERR, "signal() returned SIG_ERR") \
_ERROR(OUTPUT, "error writing output file") \
+ _ERROR(MALFORMED_FORMAT, "malformed format string") \
+ _ERROR(BAD_ALIGN_SPEC, "bad alignment specifier") \
+ _ERROR(TRAILING_GARBAGE, "trailing garbage after specifier") \
+ _ERROR(UNIT, "no unit allowed here") \
+ _ERROR(BAD_UNIT, "invalid unit specifier") \
+ _ERROR(BAD_ATOM, "invalid atom") \
/**
return fi;
}
-static struct format_item *parse_atom(char *ap, struct atom *atoms)
+static int parse_atom(char *ap, struct atom *atoms, struct format_item **result)
{
struct format_item *fi = NULL;
int i, n, len;
char *col, *ep = strchr(ap, ')');
- char *err_msg = "malformed format string";
+ int ret = -E_MALFORMED_FORMAT;
if (!ep)
goto err;
col--;
break;
default:
- err_msg = "bad alignment spec";
+ ret = -E_BAD_ALIGN_SPEC;
goto err;
}
switch (col[2]) {
col += 2;
break;
default:
- err_msg = "trailing garbage after alignment spec";
+ ret = -E_TRAILING_GARBAGE;
goto err;
}
/* read width */
col += 1 + n;
break;
default:
- err_msg = "trailing garbage after width spec";
+ ret = -E_TRAILING_GARBAGE;
goto err;
}
if (a->type != AT_SIZE && a->type != AT_COUNT) {
- err_msg = "no unit allowed here";
+ ret = -E_UNIT;
goto err;
}
if (col[1] == '*') {
break;
}
if (!units[j]) {
- err_msg = "bad unit spec";
+ ret = -E_BAD_UNIT;
goto err;
}
if (col + 2 != ep) {
- err_msg = "trailing garbage after unit spec";
+ ret = -E_TRAILING_GARBAGE;
goto err;
}
goto success;
}
- err_msg = "invalid atom";
+ ret = -E_BAD_ATOM;
err:
- ERROR_LOG("%s\n", err_msg);
free(fi);
- return NULL;
+ return ret;
success:
- return fi;
+ *result = fi;
+ return 1;
}
-struct format_info *parse_format_string(char *fmt, struct atom *atoms)
+int parse_format_string(char *fmt, struct atom *atoms, struct format_info **result)
{
char *cp, *ap, *ep;
- int num_items;
+ int num_items, ret;
struct format_info *info = malloc(sizeof(*info));
info->atoms = atoms;
num_items++;
}
info->items = realloc(info->items, (num_items + 1) * sizeof(struct format_info *));
- info->items[num_items] = parse_atom(ap + 2, atoms);
- if (!info->items[num_items]) {
+ ret = parse_atom(ap + 2, atoms, info->items + num_items);
+ if (ret < 0) {
num_items--;
goto err;
}
}
info->items = realloc(info->items, (num_items + 1) * sizeof(struct format_info *));
info->items[num_items] = NULL;
- return info;
+ *result = info;
+ return 1;
err:
for (; num_items >= 0; num_items--) {
if (!info->items[num_items]->atom_ptr)
}
free(info->items);
free(info);
- return NULL;
+ return ret;
}
void free_format_info(struct format_info *info)
};
struct format_info; /* opaque */
-struct format_info *parse_format_string(char *fmt, struct atom *atoms);
+int parse_format_string(char *fmt, struct atom *atoms, struct format_info **result);
char *format_items(struct format_info *info, union atom_value *values);
void free_format_info(struct format_info *info);