/* AbiSource Application Framework * Copyright (C) 1998 AbiSource, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. */ #include #include #include "xap_Args.h" #include "ut_string.h" #include "ut_debugmsg.h" #include "ut_assert.h" /*****************************************************************/ XAP_Args::XAP_Args(int argc, char ** argv) { m_argc = argc; m_argv = argv; m_szBuf = NULL; } XAP_Args::XAP_Args(const char * szCmdLine) { // build an argc,argv for this command line m_argc = 0; m_argv = NULL; m_szBuf = NULL; if (!szCmdLine || !*szCmdLine) return; // copy command line into work buffer // and put pointers to the tokens in m_argv // // we support (with apologies to Flex & Bison): // // WHITE [ \t]+ // DQUOTE '"' // SQUOTE '\'' // OTHER [^ \t'"] // // T1 := OTHER* // T2 := DQUOTE [^DQUOTE]* DQUOTE // T3 := SQUOTE [^SQUOTE]* SQUOTE // // WHITE ({T1|T2|T3}WHITE)* [WHITE] m_szBuf = g_strdup(szCmdLine); UT_ASSERT(m_szBuf); int count = 10; // start with 10 and g_try_realloc if necessary int k = 0; char ** argv = (char **)UT_calloc(count,sizeof(char *)); enum _state { S_START, S_INTOKEN, S_INDQUOTE, S_INSQUOTE } state; state = S_START; #define GrowArrayIfNecessary() \ do { if (k==count) \ { int newsize = (count+10)*sizeof(char *); \ argv = (char **)g_try_realloc(argv,newsize); \ count += 10; \ }} while (0) char * p = m_szBuf; while (*p) { switch (state) { case S_START: if ( (*p==' ') || (*p=='\t') ) { p++; break; } if (*p=='\'') { state=S_INSQUOTE; *p++=0; // don't include starting quote in token } else if (*p=='"') { state=S_INDQUOTE; *p++=0; // don't include starting quote in token } else state=S_INTOKEN; GrowArrayIfNecessary(); argv[k++] = p++; break; case S_INTOKEN: if ( (*p==' ') || (*p=='\t') ) { state=S_START; *p++=0; break; } p++; break; case S_INDQUOTE: if ( (*p=='"') ) { state=S_START; *p++=0; break; } p++; break; case S_INSQUOTE: if ( (*p=='\'') ) { state=S_START; *p++=0; break; } p++; break; } } if (k==0) { FREEP(m_szBuf); return; } m_argv = argv; m_argc = k; #ifdef DEBUG for (int kk=0; kk