1251881Speter/* 2251881Speter * $Id: argv.c,v 1.2 2012/11/30 20:28:23 tom Exp $ 3251881Speter * 4251881Speter * argv - Reusable functions for argv-parsing. 5251881Speter * 6251881Speter * Copyright 2011,2012 Thomas E. Dickey 7251881Speter * 8251881Speter * This program is free software; you can redistribute it and/or modify 9251881Speter * it under the terms of the GNU Lesser General Public License, version 2.1 10251881Speter * as published by the Free Software Foundation. 11251881Speter * 12251881Speter * This program is distributed in the hope that it will be useful, but 13251881Speter * WITHOUT ANY WARRANTY; without even the implied warranty of 14251881Speter * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15251881Speter * Lesser General Public License for more details. 16251881Speter * 17251881Speter * You should have received a copy of the GNU Lesser General Public 18251881Speter * License along with this program; if not, write to 19251881Speter * Free Software Foundation, Inc. 20251881Speter * 51 Franklin St., Fifth Floor 21251881Speter * Boston, MA 02110, USA. 22251881Speter */ 23251881Speter 24251881Speter#include <dialog.h> 25251881Speter#include <string.h> 26251881Speter 27251881Speter/* 28251881Speter * Convert a string to an argv[], returning a char** index (which must be 29251881Speter * freed by the caller). The string is modified (replacing gaps between 30251881Speter * tokens with nulls). 31251881Speter */ 32251881Speterchar ** 33251881Speterdlg_string_to_argv(char *blob) 34251881Speter{ 35251881Speter size_t n; 36251881Speter int pass; 37251881Speter size_t length = strlen(blob); 38251881Speter char **result = 0; 39251881Speter 40251881Speter for (pass = 0; pass < 2; ++pass) { 41251881Speter bool inparm = FALSE; 42251881Speter bool quoted = FALSE; 43251881Speter char *param = blob; 44251881Speter size_t count = 0; 45251881Speter 46251881Speter for (n = 0; n < length; ++n) { 47251881Speter if (quoted && blob[n] == '"') { 48251881Speter quoted = FALSE; 49251881Speter } else if (blob[n] == '"') { 50251881Speter quoted = TRUE; 51251881Speter if (!inparm) { 52251881Speter if (pass) 53251881Speter result[count] = param; 54251881Speter ++count; 55251881Speter inparm = TRUE; 56251881Speter } 57251881Speter } else if (blob[n] == '\\') { 58251881Speter if (quoted && !isspace(UCH(blob[n + 1]))) { 59251881Speter if (pass) { 60251881Speter *param++ = blob[n]; 61251881Speter *param++ = blob[n + 1]; 62251881Speter } 63251881Speter } 64251881Speter ++n; 65251881Speter } else if (!quoted && isspace(UCH(blob[n]))) { 66251881Speter inparm = FALSE; 67251881Speter if (pass) { 68251881Speter *param++ = '\0'; 69251881Speter } 70251881Speter } else { 71251881Speter if (!inparm) { 72251881Speter if (pass) 73251881Speter result[count] = param; 74251881Speter ++count; 75251881Speter inparm = TRUE; 76251881Speter } 77251881Speter if (pass) { 78251881Speter *param++ = blob[n]; 79251881Speter } 80251881Speter } 81251881Speter } 82251881Speter 83251881Speter if (!pass) { 84251881Speter if (count) { 85251881Speter result = dlg_calloc(char *, count + 1); 86251881Speter assert_ptr(result, "string_to_argv"); 87251881Speter } else { 88251881Speter break; /* no tokens found */ 89251881Speter } 90251881Speter } else { 91251881Speter *param = '\0'; 92251881Speter } 93251881Speter } 94251881Speter return result; 95251881Speter} 96251881Speter 97251881Speter/* 98251881Speter * Count the entries in an argv list. 99251881Speter */ 100251881Speterint 101251881Speterdlg_count_argv(char **argv) 102251881Speter{ 103251881Speter int result = 0; 104251881Speter 105251881Speter if (argv != 0) { 106251881Speter while (argv[result] != 0) 107251881Speter ++result; 108251881Speter } 109251881Speter return result; 110251881Speter} 111251881Speter 112251881Speterint 113251881Speterdlg_eat_argv(int *argcp, char ***argvp, int start, int count) 114251881Speter{ 115251881Speter int k; 116251881Speter 117251881Speter *argcp -= count; 118251881Speter for (k = start; k <= *argcp; k++) 119251881Speter (*argvp)[k] = (*argvp)[k + count]; 120251881Speter (*argvp)[*argcp] = 0; 121251881Speter return TRUE; 122251881Speter} 123251881Speter