1220747Snwhitehorn/*
2251843Sbapt * $Id: argv.c,v 1.2 2012/11/30 20:28:23 tom Exp $
3220747Snwhitehorn *
4220747Snwhitehorn *  argv - Reusable functions for argv-parsing.
5220747Snwhitehorn *
6251843Sbapt *  Copyright 2011,2012	Thomas E. Dickey
7220747Snwhitehorn *
8220747Snwhitehorn *  This program is free software; you can redistribute it and/or modify
9220747Snwhitehorn *  it under the terms of the GNU Lesser General Public License, version 2.1
10220747Snwhitehorn *  as published by the Free Software Foundation.
11220747Snwhitehorn *
12220747Snwhitehorn *  This program is distributed in the hope that it will be useful, but
13220747Snwhitehorn *  WITHOUT ANY WARRANTY; without even the implied warranty of
14220747Snwhitehorn *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15220747Snwhitehorn *  Lesser General Public License for more details.
16220747Snwhitehorn *
17220747Snwhitehorn *  You should have received a copy of the GNU Lesser General Public
18220747Snwhitehorn *  License along with this program; if not, write to
19220747Snwhitehorn *	Free Software Foundation, Inc.
20220747Snwhitehorn *	51 Franklin St., Fifth Floor
21220747Snwhitehorn *	Boston, MA 02110, USA.
22220747Snwhitehorn */
23220747Snwhitehorn
24220747Snwhitehorn#include <dialog.h>
25220747Snwhitehorn#include <string.h>
26220747Snwhitehorn
27220747Snwhitehorn/*
28220747Snwhitehorn * Convert a string to an argv[], returning a char** index (which must be
29220747Snwhitehorn * freed by the caller).  The string is modified (replacing gaps between
30220747Snwhitehorn * tokens with nulls).
31220747Snwhitehorn */
32220747Snwhitehornchar **
33220747Snwhitehorndlg_string_to_argv(char *blob)
34220747Snwhitehorn{
35220747Snwhitehorn    size_t n;
36220747Snwhitehorn    int pass;
37220747Snwhitehorn    size_t length = strlen(blob);
38220747Snwhitehorn    char **result = 0;
39220747Snwhitehorn
40220747Snwhitehorn    for (pass = 0; pass < 2; ++pass) {
41220747Snwhitehorn	bool inparm = FALSE;
42220747Snwhitehorn	bool quoted = FALSE;
43220747Snwhitehorn	char *param = blob;
44220747Snwhitehorn	size_t count = 0;
45220747Snwhitehorn
46220747Snwhitehorn	for (n = 0; n < length; ++n) {
47220747Snwhitehorn	    if (quoted && blob[n] == '"') {
48220747Snwhitehorn		quoted = FALSE;
49220747Snwhitehorn	    } else if (blob[n] == '"') {
50220747Snwhitehorn		quoted = TRUE;
51220747Snwhitehorn		if (!inparm) {
52220747Snwhitehorn		    if (pass)
53220747Snwhitehorn			result[count] = param;
54220747Snwhitehorn		    ++count;
55220747Snwhitehorn		    inparm = TRUE;
56220747Snwhitehorn		}
57220747Snwhitehorn	    } else if (blob[n] == '\\') {
58220747Snwhitehorn		if (quoted && !isspace(UCH(blob[n + 1]))) {
59220747Snwhitehorn		    if (pass) {
60220747Snwhitehorn			*param++ = blob[n];
61220747Snwhitehorn			*param++ = blob[n + 1];
62220747Snwhitehorn		    }
63220747Snwhitehorn		}
64220747Snwhitehorn		++n;
65220747Snwhitehorn	    } else if (!quoted && isspace(UCH(blob[n]))) {
66220747Snwhitehorn		inparm = FALSE;
67220747Snwhitehorn		if (pass) {
68220747Snwhitehorn		    *param++ = '\0';
69220747Snwhitehorn		}
70220747Snwhitehorn	    } else {
71220747Snwhitehorn		if (!inparm) {
72220747Snwhitehorn		    if (pass)
73220747Snwhitehorn			result[count] = param;
74220747Snwhitehorn		    ++count;
75220747Snwhitehorn		    inparm = TRUE;
76220747Snwhitehorn		}
77220747Snwhitehorn		if (pass) {
78220747Snwhitehorn		    *param++ = blob[n];
79220747Snwhitehorn		}
80220747Snwhitehorn	    }
81220747Snwhitehorn	}
82220747Snwhitehorn
83220747Snwhitehorn	if (!pass) {
84220747Snwhitehorn	    if (count) {
85220747Snwhitehorn		result = dlg_calloc(char *, count + 1);
86220747Snwhitehorn		assert_ptr(result, "string_to_argv");
87220747Snwhitehorn	    } else {
88220747Snwhitehorn		break;		/* no tokens found */
89220747Snwhitehorn	    }
90220747Snwhitehorn	} else {
91220747Snwhitehorn	    *param = '\0';
92220747Snwhitehorn	}
93220747Snwhitehorn    }
94220747Snwhitehorn    return result;
95220747Snwhitehorn}
96220747Snwhitehorn
97220747Snwhitehorn/*
98220747Snwhitehorn * Count the entries in an argv list.
99220747Snwhitehorn */
100220747Snwhitehornint
101220747Snwhitehorndlg_count_argv(char **argv)
102220747Snwhitehorn{
103220747Snwhitehorn    int result = 0;
104220747Snwhitehorn
105220747Snwhitehorn    if (argv != 0) {
106220747Snwhitehorn	while (argv[result] != 0)
107220747Snwhitehorn	    ++result;
108220747Snwhitehorn    }
109220747Snwhitehorn    return result;
110220747Snwhitehorn}
111220747Snwhitehorn
112220747Snwhitehornint
113220747Snwhitehorndlg_eat_argv(int *argcp, char ***argvp, int start, int count)
114220747Snwhitehorn{
115220747Snwhitehorn    int k;
116220747Snwhitehorn
117220747Snwhitehorn    *argcp -= count;
118220747Snwhitehorn    for (k = start; k <= *argcp; k++)
119220747Snwhitehorn	(*argvp)[k] = (*argvp)[k + count];
120220747Snwhitehorn    (*argvp)[*argcp] = 0;
121220747Snwhitehorn    return TRUE;
122220747Snwhitehorn}
123