summaryrefslogtreecommitdiff
path: root/Build/source/utils/dialog/dialog-1.1-20080819/columns.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/utils/dialog/dialog-1.1-20080819/columns.c')
-rw-r--r--Build/source/utils/dialog/dialog-1.1-20080819/columns.c174
1 files changed, 174 insertions, 0 deletions
diff --git a/Build/source/utils/dialog/dialog-1.1-20080819/columns.c b/Build/source/utils/dialog/dialog-1.1-20080819/columns.c
new file mode 100644
index 00000000000..11ca65a1526
--- /dev/null
+++ b/Build/source/utils/dialog/dialog-1.1-20080819/columns.c
@@ -0,0 +1,174 @@
+/*
+ * $Id: columns.c,v 1.4 2008/06/21 12:27:35 tom Exp $
+ *
+ * columns.c -- implements column-alignment
+ *
+ * Copyright 2008 Thomas E. Dickey
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License, version 2.1
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to
+ * Free Software Foundation, Inc.
+ * 51 Franklin St., Fifth Floor
+ * Boston, MA 02110, USA.
+ */
+
+#include <dialog.h>
+
+#define each(row, data) \
+ row = 0, data = target; \
+ row < num_rows - 1; \
+ ++row, data = next_row(data, per_row)
+
+static char *
+column_separator(void)
+{
+ char *result = 0;
+
+ if ((result = dialog_vars.column_separator) != 0) {
+ if (*result == '\0')
+ result = 0;
+ }
+ return result;
+}
+
+static char **
+next_row(char **target, int per_row)
+{
+ char *result = (char *) target;
+ result += per_row;
+ return (char **) result;
+}
+
+static char *
+next_col(char *source, unsigned offset)
+{
+ char *mark = column_separator();
+ char *result = source + offset;
+ if (offset)
+ result += strlen(mark);
+ return strstr(result, mark);
+}
+
+/*
+ * Parse the source string, storing the offsets and widths of each column in
+ * the corresponding arrays. Return the number of columns.
+ */
+static unsigned
+split_row(char *source, unsigned *offsets, unsigned *widths)
+{
+ int mark = strlen(column_separator());
+ char *next = 0;
+ unsigned result = 0;
+ unsigned offset = 0;
+
+ do {
+ if (result) {
+ offset = mark + next - source;
+ widths[result - 1] = offset - offsets[result - 1] - mark;
+ }
+ offsets[result] = offset;
+ ++result;
+ } while ((next = next_col(source, offset)) != 0);
+
+ offset = strlen(source);
+ widths[result - 1] = offset - offsets[result - 1];
+
+ return result;
+}
+
+/*
+ * The caller passes a pointer to a struct or array containing pointers
+ * to strings that we may want to copy and reformat according to the column
+ * separator.
+ */
+void
+dlg_align_columns(char **target, int per_row, int num_rows)
+{
+ int row;
+
+ if (column_separator()) {
+ char **value;
+ unsigned numcols = 1;
+ unsigned maxcols = 0;
+ unsigned *widths;
+ unsigned *offsets;
+ unsigned *maxwidth;
+ unsigned realwidth;
+ unsigned n;
+
+ /* first allocate arrays for workspace */
+ for (each(row, value)) {
+ unsigned len = strlen(*value);
+ if (maxcols < len)
+ maxcols = len;
+ }
+ ++maxcols;
+ widths = dlg_calloc(unsigned, maxcols);
+ offsets = dlg_calloc(unsigned, maxcols);
+ maxwidth = dlg_calloc(unsigned, maxcols);
+
+ assert_ptr(widths, "dlg_align_columns");
+ assert_ptr(offsets, "dlg_align_columns");
+ assert_ptr(maxwidth, "dlg_align_columns");
+
+ /* now, determine the number of columns and the column-widths */
+ for (each(row, value)) {
+ unsigned cols = split_row(*value, offsets, widths);
+ if (numcols < cols)
+ numcols = cols;
+ for (n = 0; n < cols; ++n) {
+ if (maxwidth[n] < widths[n])
+ maxwidth[n] = widths[n];
+ }
+ }
+ realwidth = numcols - 1;
+ for (n = 0; n < numcols; ++n) {
+ realwidth += maxwidth[n];
+ }
+
+ /* finally, construct reformatted strings */
+ for (each(row, value)) {
+ unsigned cols = split_row(*value, offsets, widths);
+ unsigned offset = 0;
+ char *text = dlg_malloc(char, realwidth + 1);
+
+ assert_ptr(text, "dlg_align_columns");
+
+ memset(text, ' ', realwidth);
+ for (n = 0; n < cols; ++n) {
+ memcpy(text + offset, *value + offsets[n], widths[n]);
+ offset += maxwidth[n] + 1;
+ }
+ *value = text;
+ }
+
+ free(widths);
+ free(offsets);
+ free(maxwidth);
+ }
+}
+
+/*
+ * Free temporary storage used while making column-aligned data.
+ */
+void
+dlg_free_columns(char **target, int per_row, int num_rows)
+{
+ int row;
+ char **value;
+
+ if (column_separator()) {
+ for (each(row, value)) {
+ free(*value);
+ }
+ }
+}