X-Git-Url: http://git.tuebingen.mpg.de/?p=adu.git;a=blobdiff_plain;f=format.c;h=f1d1247074da8c97c41368aa3663b037dbbfc4bd;hp=3d1daa2aca20fde5f7b993bb01d6b178818f8d3b;hb=f638c88fad8a1350cf56d5f60ddef297ece92805;hpb=0a8f1be6ca96c7050f02129bb275c926671007f4 diff --git a/format.c b/format.c index 3d1daa2..f1d1247 100644 --- a/format.c +++ b/format.c @@ -4,7 +4,7 @@ * Licensed under the GPL v2. For licencing details see COPYING. */ -/** \file format.c Functions for pretty-printing numbers and strings. */ +/** \file format.c \brief Functions for pretty-printing numbers and strings. */ #include /* readdir() */ #include "adu.h" @@ -13,6 +13,7 @@ #include "string.h" #include "error.h" #include "format.h" + enum alignment {ALIGN_LEFT, ALIGN_RIGHT, ALIGN_CENTER}; struct num_format { @@ -95,12 +96,12 @@ static struct format_item *make_const_string(char *cp, char *ep) 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; @@ -157,7 +158,7 @@ static struct format_item *parse_atom(char *ap, struct atom *atoms) col--; break; default: - err_msg = "bad alignment spec"; + ret = -E_BAD_ALIGN_SPEC; goto err; } switch (col[2]) { @@ -167,7 +168,7 @@ static struct format_item *parse_atom(char *ap, struct atom *atoms) col += 2; break; default: - err_msg = "trailing garbage after alignment spec"; + ret = -E_TRAILING_GARBAGE; goto err; } /* read width */ @@ -181,11 +182,11 @@ static struct format_item *parse_atom(char *ap, struct atom *atoms) 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] == '*') { @@ -199,28 +200,37 @@ static struct format_item *parse_atom(char *ap, struct atom *atoms) 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) +/** + * Parse the given string according to the list of given atoms. + * + * \param fmt The format string. + * \param atoms The array of valid atoms. + * \param result Points to a format_info structure for later use. + * + * \return Standard. + */ +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; @@ -234,8 +244,8 @@ struct format_info *parse_format_string(char *fmt, struct atom *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; } @@ -249,7 +259,8 @@ struct format_info *parse_format_string(char *fmt, struct atom *atoms) } 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) @@ -258,14 +269,26 @@ err: } free(info->items); free(info); - return NULL; + *result = NULL; + return ret; } +/** + * Free a struct of type \a format_info. + * + * \param info Pointer to the format info to be freed. + * + * It's OK to pass a \p NULL pointer to this function in which case the + * function does nothing. + */ void free_format_info(struct format_info *info) { int i; struct format_item *item; + if (!info) + return; + for (i = 0; (item = info->items[i]); i++) { if (!item->atom_ptr) free(item->af.cs.string); @@ -389,11 +412,21 @@ static char *align_unsigned_int(long long unsigned num, unsigned int width, nnum, postfix, width - (width + len) / 2, ""); } +/** + * Pretty-format the given values according to \a info. + * + * \param info The formating information. + * \param values The contents of the atoms. + * + * \return A string that must be freed by the caller. + */ char *format_items(struct format_info *info, union atom_value *values) { int i; char *buf = NULL; + if (!info) + return NULL; for (i = 0; info->items[i]; i++) { struct atom *a; struct format_item *fi = info->items[i]; @@ -422,6 +455,9 @@ char *format_items(struct format_info *info, union atom_value *values) fi->width, &af->nf, type); } buf = adu_strcat(buf, val); + free(val); } + if (!buf) + buf = adu_strdup(""); return buf; }