* 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 <dirent.h> /* readdir() */
#include "adu.h"
#include "string.h"
#include "error.h"
#include "format.h"
+
+/** The three different alignment types. */
enum alignment {ALIGN_LEFT, ALIGN_RIGHT, ALIGN_CENTER};
struct num_format {
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)
+/**
+ * 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;
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;
+ *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);
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];
fi->width, &af->nf, type);
}
buf = adu_strcat(buf, val);
+ free(val);
}
+ if (!buf)
+ buf = adu_strdup("");
return buf;
}