acpi: Narrow workaround for broken interrupt settings
[dragonfly.git] / contrib / dialog / argv.c
blobd08c6d56e6cdb6df265c4f61951585261105ea2d
1 /*
2 * $Id: argv.c,v 1.14 2022/04/03 22:38:16 tom Exp $
4 * argv - Reusable functions for argv-parsing.
6 * Copyright 2011-2020,2022 Thomas E. Dickey
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU Lesser General Public License, version 2.1
10 * as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this program; if not, write to
19 * Free Software Foundation, Inc.
20 * 51 Franklin St., Fifth Floor
21 * Boston, MA 02110, USA.
24 #include <dlg_internals.h>
27 * Convert a string to an argv[], returning a char** index (which must be
28 * freed by the caller). The string is modified (replacing gaps between
29 * tokens with nulls).
31 char **
32 dlg_string_to_argv(char *blob)
34 size_t n, k;
35 int pass;
36 size_t length = strlen(blob);
37 char **result = 0;
39 #ifdef HAVE_DLG_TRACE
40 if (dialog_state.trace_output) {
41 DLG_TRACE(("# dlg_string_to_argv:\n"));
42 DLG_TRACE(("# given:\n"));
43 for (n = k = 0; n < length; ++n) {
44 if (blob[n] == '\n') {
45 DLG_TRACE(("#%s\t%.*s\\n\n",
46 k ? "+" : "",
47 (int) (n - k), blob + k));
48 k = n + 1;
51 if (n > k) {
52 DLG_TRACE(("#%s\t%.*s\n",
53 k ? "+" : "",
54 (int) (n - k), blob + k));
56 DLG_TRACE(("# result:\n"));
58 #endif
59 for (pass = 0; pass < 2; ++pass) {
60 bool inparm = FALSE;
61 bool quoted = FALSE;
62 char *param = blob;
63 size_t count = 0;
65 for (n = 0; n < length; ++n) {
66 if (quoted && blob[n] == '"') {
67 quoted = FALSE;
68 } else if (blob[n] == '"') {
69 quoted = TRUE;
70 if (!inparm) {
71 if (pass) {
72 result[count] = param;
74 ++count;
75 inparm = TRUE;
77 } else if (!quoted && isspace(UCH(blob[n]))) {
78 if (inparm) {
79 if (pass) {
80 *param = '\0';
82 ++param;
83 inparm = FALSE;
85 } else {
86 if (blob[n] == '\\') {
87 size_t n1 = (n + 1);
88 bool ignore = FALSE;
89 if (n1 == length) {
90 break; /* The string is terminated by a backslash */
91 } else if ((blob[n1] == '\\') ||
92 (blob[n1] == '"') ||
93 (ignore = (blob[n1] == '\n'))) {
94 /* eat the backslash */
95 if (pass) {
96 --length;
97 for (k = n; k < length; ++k)
98 blob[k] = blob[k + 1];
99 blob[length] = '\0';
100 } else {
101 ++param; /* pretend I ate it */
103 if (ignore)
104 continue;
107 if (!inparm) {
108 if (pass) {
109 result[count] = param;
111 ++count;
112 inparm = TRUE;
114 if (pass) {
115 *param = blob[n];
117 ++param;
121 if (pass) {
122 *param = '\0';
123 } else {
124 if (count) {
125 result = dlg_calloc(char *, count + 1);
126 assert_ptr(result, "string_to_argv");
127 } else {
128 break; /* no tokens found */
132 #ifdef HAVE_DLG_TRACE
133 if (result != 0) {
134 for (n = 0; result[n] != 0; ++n) {
135 DLG_TRACE(("#\targv[%d] = %s\n", (int) n, result[n]));
138 #endif
139 return result;
143 * Count the entries in an argv list.
146 dlg_count_argv(char **argv)
148 int result = 0;
150 if (argv != 0) {
151 while (argv[result] != 0)
152 ++result;
154 return result;
158 dlg_eat_argv(int *argcp, char ***argvp, int start, int count)
160 int k;
162 *argcp -= count;
163 for (k = start; k <= *argcp; k++)
164 (*argvp)[k] = (*argvp)[k + count];
165 (*argvp)[*argcp] = 0;
166 return TRUE;