[plist] Report line-relative character position in errors

Far better than string-relative.
This commit is contained in:
Bill Currie 2022-05-06 20:09:55 +09:00
parent b69b7b6a4a
commit ae9e8f8f4e

View file

@ -95,6 +95,7 @@ typedef struct pldata_s { // Unparsed property list string
unsigned end; unsigned end;
unsigned pos; unsigned pos;
unsigned line; unsigned line;
unsigned line_start;
plitem_t *error; plitem_t *error;
va_ctx_t *va_ctx; va_ctx_t *va_ctx;
hashlink_t **hashlinks; hashlink_t **hashlinks;
@ -516,6 +517,7 @@ pl_skipspace (pldata_t *pl)
if (c == '\n') { if (c == '\n') {
pl->line++; pl->line++;
pl->line_start = pl->pos + 1;
} else if (c == '*' && pl->pos < pl->end - 1 } else if (c == '*' && pl->pos < pl->end - 1
&& pl->ptr[pl->pos+1] == '/') { && pl->ptr[pl->pos+1] == '/') {
pl->pos++; pl->pos++;
@ -536,6 +538,7 @@ pl_skipspace (pldata_t *pl)
} }
if (c == '\n') { if (c == '\n') {
pl->line++; pl->line++;
pl->line_start = pl->pos + 1;
} }
pl->pos++; pl->pos++;
} }
@ -649,6 +652,7 @@ pl_parsequotedstring (pldata_t *pl)
if (c == '\n') { if (c == '\n') {
pl->line++; pl->line++;
pl->line_start = pl->pos + 1;
} }
pl->pos++; pl->pos++;
@ -932,36 +936,32 @@ pl_parsepropertylistitem (pldata_t *pl)
VISIBLE plitem_t * VISIBLE plitem_t *
PL_GetPropertyList (const char *string, hashlink_t **hashlinks) PL_GetPropertyList (const char *string, hashlink_t **hashlinks)
{ {
pldata_t *pl = calloc (1, sizeof (pldata_t));
plitem_t *newpl = NULL; plitem_t *newpl = NULL;
if (!quotable_bitmap[0]) if (!quotable_bitmap[0])
init_quotables (); init_quotables ();
pl->ptr = string; pldata_t pl = {
pl->pos = 0; .ptr = string,
pl->end = strlen (string); .end = strlen (string),
pl->error = NULL; .line = 1,
pl->line = 1; .va_ctx = va_create_context (4),
pl->va_ctx = va_create_context (4); .hashlinks = hashlinks,
pl->hashlinks = hashlinks; };
if ((newpl = pl_parsepropertylistitem (pl))) { if (!(newpl = pl_parsepropertylistitem (&pl))) {
va_destroy_context (pl->va_ctx); if (pl.error) {
free (pl); const char *error = PL_String (pl.error);
return newpl;
} else {
if (pl && pl->error) {
const char *error = PL_String (pl->error);
if (error[0]) { if (error[0]) {
Sys_Printf ("plist: %d,%d: %s\n", pl->line, pl->pos, error); Sys_Printf ("plist: %d,%d: %s\n", pl.line,
pl.pos - pl.line_start, error);
} }
PL_Free (pl->error); PL_Free (pl.error);
} }
va_destroy_context (pl->va_ctx);
free (pl);
return NULL; return NULL;
} }
va_destroy_context (pl.va_ctx);
return newpl;
} }
static void static void