diff options
author | Tor Andersson <tor@ghostscript.com> | 2008-03-21 13:28:39 +0100 |
---|---|---|
committer | Tor Andersson <tor@ghostscript.com> | 2008-03-21 13:28:39 +0100 |
commit | 4b9181cdb56a9d2015f8d79e90015038f4792334 (patch) | |
tree | 507876fcec4f91aa591f3cbf2196f4dcc4deeaad /stream/obj_parse.c | |
parent | 65e3374a2415399ded4624326a01bb9dfa77fa9e (diff) | |
download | mupdf-4b9181cdb56a9d2015f8d79e90015038f4792334.tar.xz |
Backport of chained error messages from experimental branch.
Diffstat (limited to 'stream/obj_parse.c')
-rw-r--r-- | stream/obj_parse.c | 180 |
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); |