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