+ fputs(new_line, stdout);
+}
+
+/*
+ * Trim leading/trailing blanks, as well as blanks after a comma.
+ * Convert embedded blanks to commas.
+ */
+static char *
+trimmed_tab_list(const char *source)
+{
+ char *result = strdup(source);
+ if (result != 0) {
+ int j, k, last;
+
+ for (j = k = last = 0; result[j] != 0; ++j) {
+ int ch = UChar(result[j]);
+ if (isspace(ch)) {
+ if (last == '\0') {
+ continue;
+ } else if (isdigit(last) || last == ',') {
+ ch = ',';
+ }
+ } else if (ch == ',') {
+ ;
+ } else {
+ if (last == ',')
+ result[k++] = (char) last;
+ result[k++] = (char) ch;
+ }
+ last = ch;
+ }
+ result[k] = '\0';
+ }
+ return result;
+}
+
+static bool
+comma_is_needed(const char *source)
+{
+ bool result = FALSE;
+
+ if (source != 0) {
+ size_t len = strlen(source);
+ if (len != 0)
+ result = (source[len - 1] != ',');
+ } else {
+ result = FALSE;
+ }
+ return result;
+}
+
+/*
+ * Add a command-line parameter to the tab-list. It can be blank- or comma-
+ * separated (or a mixture). For simplicity, empty tabs are ignored, e.g.,
+ * tabs 1,,6,11
+ * tabs 1,6,11
+ * are treated the same.
+ */
+static const char *
+add_to_tab_list(char **append, const char *value)
+{
+ char *result = *append;
+ char *copied = trimmed_tab_list(value);
+
+ if (copied != 0 && *copied != '\0') {
+ const char *comma = ",";
+ size_t need = 1 + strlen(copied);
+
+ if (*copied == ',')
+ comma = "";
+ else if (!comma_is_needed(*append))
+ comma = "";
+
+ need += strlen(comma);
+ if (*append != 0)
+ need += strlen(*append);
+
+ result = malloc(need);
+ if (result == 0)
+ failed("add_to_tab_list");
+
+ *result = '\0';
+ if (*append != 0) {
+ _nc_STRCPY(result, *append, need);
+ free(*append);
+ }
+ _nc_STRCAT(result, comma, need);
+ _nc_STRCAT(result, copied, need);
+
+ *append = result;
+ }
+ free(copied);
+ return result;
+}
+
+/*
+ * If the terminal supports it, (re)set the left margin and return true.
+ * Otherwise, return false.
+ */
+static bool
+do_set_margin(int margin, bool no_op)
+{
+ bool result = FALSE;
+
+ if (margin == 0) { /* 0 is special case for resetting */
+ if (VALID_STRING(clear_margins)) {
+ result = TRUE;
+ if (!no_op)
+ tputs(clear_margins, 1, putch);
+ }
+ } else if (margin-- < 0) { /* margin will be 0-based from here on */
+ result = TRUE;
+ } else if (VALID_STRING(set_left_margin)) {
+ result = TRUE;
+ if (!no_op) {
+ /*
+ * assuming we're on the first column of the line, move the cursor
+ * to the column at which we will set a margin.
+ */
+ if (VALID_STRING(column_address)) {
+ tputs(TIPARM_1(column_address, margin), 1, putch);
+ } else if (margin >= 1) {
+ if (VALID_STRING(parm_right_cursor)) {
+ tputs(TIPARM_1(parm_right_cursor, margin), 1, putch);
+ } else {
+ while (margin-- > 0)
+ putch(' ');
+ }
+ }
+ tputs(set_left_margin, 1, putch);
+ }
+ } else if (VALID_STRING(set_left_margin_parm)) {
+ result = TRUE;
+ if (!no_op) {
+ if (VALID_STRING(set_right_margin_parm)) {
+ tputs(TIPARM_1(set_left_margin_parm, margin), 1, putch);
+ } else {
+ tputs(TIPARM_2(set_left_margin_parm, margin, max_cols), 1, putch);
+ }
+ }
+ } else if (VALID_STRING(set_lr_margin)) {
+ result = TRUE;
+ if (!no_op) {
+ tputs(TIPARM_2(set_lr_margin, margin, max_cols), 1, putch);
+ }
+ }
+ return result;
+}
+
+/*
+ * Check for illegal characters in the tab-list.
+ */
+static bool
+legal_tab_list(const char *tab_list)
+{
+ bool result = TRUE;
+
+ if (tab_list != 0 && *tab_list != '\0') {
+ if (comma_is_needed(tab_list)) {
+ int n;
+
+ for (n = 0; tab_list[n] != '\0'; ++n) {
+ int ch = UChar(tab_list[n]);
+
+ if (!(isdigit(ch) || ch == ',' || ch == '+')) {
+ fprintf(stderr,
+ "%s: unexpected character found '%c'\n",
+ _nc_progname, ch);
+ result = FALSE;
+ break;
+ }
+ }
+ } else {
+ fprintf(stderr, "%s: trailing comma found '%s'\n", _nc_progname, tab_list);
+ result = FALSE;
+ }
+ } else {
+ /* if no list given, default to "tabs -8" */
+ }
+ return result;
+}
+
+static char *
+skip_list(char *value)
+{
+ while (*value != '\0' &&
+ (isdigit(UChar(*value)) ||
+ isspace(UChar(*value)) ||
+ strchr("+,", UChar(*value)) != 0)) {
+ ++value;
+ }
+ return value;