summaryrefslogtreecommitdiff
path: root/stream/obj_parse.c
diff options
context:
space:
mode:
Diffstat (limited to 'stream/obj_parse.c')
-rw-r--r--stream/obj_parse.c180
1 files changed, 135 insertions, 45 deletions
diff --git a/stream/obj_parse.c b/stream/obj_parse.c
index 73b761cb..316e8ad4 100644
--- a/stream/obj_parse.c
+++ b/stream/obj_parse.c
@@ -62,6 +62,7 @@ static void parsekeyword(char **sp, char *b, char *eb)
static fz_error *parsename(fz_obj **obj, char **sp)
{
+ fz_error *error;
char buf[64];
char *s = *sp;
char *p = buf;
@@ -72,11 +73,15 @@ static fz_error *parsename(fz_obj **obj, char **sp)
*p++ = 0;
*sp = s;
- return fz_newname(obj, buf);
+ error = fz_newname(obj, buf);
+ if (error)
+ return fz_rethrow(error, "cannot create name");
+ return fz_okay;
}
static fz_error *parsenumber(fz_obj **obj, char **sp)
{
+ fz_error *error;
char buf[32];
char *s = *sp;
char *p = buf;
@@ -92,8 +97,13 @@ static fz_error *parsenumber(fz_obj **obj, char **sp)
*sp = s;
if (strchr(buf, '.'))
- return fz_newreal(obj, atof(buf));
- return fz_newint(obj, atoi(buf));
+ error = fz_newreal(obj, atof(buf));
+ else
+ error = fz_newint(obj, atoi(buf));
+
+ if (error)
+ return fz_rethrow(error, "cannot parse number");
+ return fz_okay;
}
static fz_error *parsedict(fz_obj **obj, char **sp, struct vap *v)
@@ -105,8 +115,8 @@ static fz_error *parsedict(fz_obj **obj, char **sp, struct vap *v)
char *s = *sp;
error = fz_newdict(&dict, 8);
- if (error) return error;
- *obj = dict;
+ if (error)
+ return fz_rethrow(error, "cannot create dict");
s += 2; /* skip "<<" */
@@ -115,39 +125,55 @@ static fz_error *parsedict(fz_obj **obj, char **sp, struct vap *v)
skipwhite(&s);
/* end-of-dict marker >> */
- if (*s == '>') {
+ if (*s == '>')
+ {
s ++;
- if (*s == '>') {
+ if (*s == '>')
+ {
s ++;
break;
}
- error = fz_throw("syntaxerror in parsedict");
+ error = fz_throw("malformed >> marker");
goto cleanup;
}
/* non-name as key, bail */
- if (*s != '/') {
- error = fz_throw("syntaxerror in parsedict");
+ if (*s != '/')
+ {
+ error = fz_throw("key is not a name");
goto cleanup;
}
error = parsename(&key, &s);
- if (error) goto cleanup;
+ if (error)
+ {
+ error = fz_rethrow(error, "cannot parse key");
+ goto cleanup;
+ }
skipwhite(&s);
error = parseobj(&val, &s, v);
- if (error) goto cleanup;
+ if (error)
+ {
+ error = fz_rethrow(error, "cannot parse value");
+ goto cleanup;
+ }
error = fz_dictput(dict, key, val);
- if (error) goto cleanup;
+ if (error)
+ {
+ error = fz_rethrow(error, "cannot insert dict entry");
+ goto cleanup;
+ }
fz_dropobj(val); val = nil;
fz_dropobj(key); key = nil;
}
+ *obj = dict;
*sp = s;
- return nil;
+ return fz_okay;
cleanup:
if (val) fz_dropobj(val);
@@ -166,8 +192,8 @@ static fz_error *parsearray(fz_obj **obj, char **sp, struct vap *v)
char *s = *sp;
error = fz_newarray(&a, 8);
- if (error) return error;
- *obj = a;
+ if (error)
+ return fz_rethrow(error, "cannot create array");
s ++; /* skip '[' */
@@ -175,26 +201,38 @@ static fz_error *parsearray(fz_obj **obj, char **sp, struct vap *v)
{
skipwhite(&s);
- if (*s == ']') {
+ if (*s == ']')
+ {
s ++;
break;
}
error = parseobj(&o, &s, v);
- if (error) { *obj = nil; fz_dropobj(a); return error; }
+ if (error)
+ {
+ fz_dropobj(a);
+ return fz_rethrow(error, "cannot parse item");
+ }
error = fz_arraypush(a, o);
- if (error) { fz_dropobj(o); *obj = nil; fz_dropobj(a); return error; }
+ if (error)
+ {
+ fz_dropobj(o);
+ fz_dropobj(a);
+ return fz_rethrow(error, "cannot add item to array");
+ }
fz_dropobj(o);
}
+ *obj = a;
*sp = s;
- return nil;
+ return fz_okay;
}
static fz_error *parsestring(fz_obj **obj, char **sp)
{
+ fz_error *error;
char buf[512];
char *s = *sp;
char *p = buf;
@@ -236,12 +274,12 @@ static fz_error *parsestring(fz_obj **obj, char **sp)
}
else switch (*s)
{
- case 'n': *p++ = '\n'; s++; break;
- case 'r': *p++ = '\r'; s++; break;
- case 't': *p++ = '\t'; s++; break;
- case 'b': *p++ = '\b'; s++; break;
- case 'f': *p++ = '\f'; s++; break;
- default: *p++ = *s++; break;
+ case 'n': *p++ = '\n'; s++; break;
+ case 'r': *p++ = '\r'; s++; break;
+ case 't': *p++ = '\t'; s++; break;
+ case 'b': *p++ = '\b'; s++; break;
+ case 'f': *p++ = '\f'; s++; break;
+ default: *p++ = *s++; break;
}
}
else
@@ -252,11 +290,16 @@ static fz_error *parsestring(fz_obj **obj, char **sp)
}
*sp = s;
- return fz_newstring(obj, buf, p - buf - 1);
+
+ error = fz_newstring(obj, buf, p - buf - 1);
+ if (error)
+ return fz_rethrow(error, "cannot create string");
+ return fz_okay;
}
static fz_error *parsehexstring(fz_obj **obj, char **sp)
{
+ fz_error *error;
char buf[512];
char *s = *sp;
char *p = buf;
@@ -287,7 +330,10 @@ static fz_error *parsehexstring(fz_obj **obj, char **sp)
}
*sp = s;
- return fz_newstring(obj, buf, p - buf);
+ error = fz_newstring(obj, buf, p - buf);
+ if (error)
+ return fz_rethrow(error, "cannot create string");
+ return fz_okay;
}
static fz_error *parseobj(fz_obj **obj, char **sp, struct vap *v)
@@ -299,7 +345,7 @@ static fz_error *parseobj(fz_obj **obj, char **sp, struct vap *v)
char *s = *sp;
if (*s == '\0')
- return fz_throw("syntaxerror in parseobj: end-of-string");
+ return fz_throw("end of data");
skipwhite(&s);
@@ -308,6 +354,7 @@ static fz_error *parseobj(fz_obj **obj, char **sp, struct vap *v)
if (v != nil && *s == '%')
{
s ++;
+
switch (*s)
{
case 'p': error = fz_newpointer(obj, va_arg(v->ap, void*)); break;
@@ -317,61 +364,102 @@ static fz_error *parseobj(fz_obj **obj, char **sp, struct vap *v)
case 'f': error = fz_newreal(obj, (float)va_arg(v->ap, double)); break;
case 'n': error = fz_newname(obj, va_arg(v->ap, char*)); break;
case 'r':
- oid = va_arg(v->ap, int);
- gid = va_arg(v->ap, int);
- error = fz_newindirect(obj, oid, gid);
- break;
+ oid = va_arg(v->ap, int);
+ gid = va_arg(v->ap, int);
+ error = fz_newindirect(obj, oid, gid);
+ break;
case 's':
- tmp = va_arg(v->ap, char*);
- error = fz_newstring(obj, tmp, strlen(tmp));
- break;
+ tmp = va_arg(v->ap, char*);
+ error = fz_newstring(obj, tmp, strlen(tmp));
+ break;
case '#':
- tmp = va_arg(v->ap, char*);
- len = va_arg(v->ap, int);
- error = fz_newstring(obj, tmp, len);
- break;
+ tmp = va_arg(v->ap, char*);
+ len = va_arg(v->ap, int);
+ error = fz_newstring(obj, tmp, len);
+ break;
default:
- error = fz_throw("unknown format specifier in packobj: '%c'", *s);
- break;
+ error = fz_throw("unknown format specifier in packobj: '%c'", *s);
+ break;
}
+
+ if (error)
+ error = fz_rethrow(error, "cannot create object for %% format");
+
s ++;
}
else if (*s == '/')
+ {
error = parsename(obj, &s);
+ if (error)
+ error = fz_rethrow(error, "cannot parse name");
+ }
else if (*s == '(')
+ {
error = parsestring(obj, &s);
+ if (error)
+ error = fz_rethrow(error, "cannot parse string");
+ }
- else if (*s == '<') {
+ else if (*s == '<')
+ {
if (s[1] == '<')
+ {
error = parsedict(obj, &s, v);
+ if (error)
+ error = fz_rethrow(error, "cannot parse dict");
+ }
else
+ {
error = parsehexstring(obj, &s);
+ if (error)
+ error = fz_rethrow(error, "cannot parse hex string");
+ }
}
else if (*s == '[')
+ {
error = parsearray(obj, &s, v);
+ if (error)
+ error = fz_rethrow(error, "cannot parse array");
+ }
else if (*s == '-' || *s == '.' || (*s >= '0' && *s <= '9'))
+ {
error = parsenumber(obj, &s);
+ if (error)
+ error = fz_rethrow(error, "cannot parse number");
+ }
else if (isregular(*s))
{
parsekeyword(&s, buf, buf + sizeof buf);
if (strcmp("true", buf) == 0)
+ {
error = fz_newbool(obj, 1);
+ if (error)
+ error = fz_rethrow(error, "cannot create bool (true)");
+ }
else if (strcmp("false", buf) == 0)
+ {
error = fz_newbool(obj, 0);
+ if (error)
+ error = fz_rethrow(error, "cannot create bool (false)");
+ }
else if (strcmp("null", buf) == 0)
+ {
error = fz_newnull(obj);
+ if (error)
+ error = fz_rethrow(error, "cannot create null object");
+ }
else
- error = fz_throw("syntaxerror in parseobj: undefined keyword %s", buf);
+ error = fz_throw("undefined keyword %s", buf);
}
else
- error = fz_throw("syntaxerror in parseobj");
+ error = fz_throw("syntax error: unknown byte 0x%d", *s);
*sp = s;
return error;
@@ -388,6 +476,8 @@ fz_packobj(fz_obj **op, char *fmt, ...)
va_copy(v.ap, ap);
error = parseobj(op, &fmt, &v);
+ if (error)
+ error = fz_rethrow(error, "cannot parse object");
va_end(ap);