/nqc-3.1.r6/nqc/CmdLine.cpp
C++ | 211 lines | 130 code | 36 blank | 45 comment | 46 complexity | 407601c6cd70fc0845789a66e15f468e MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception
- /*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
- * License for the specific language governing rights and limitations
- * under the License.
- *
- * The Initial Developer of this code is David Baum.
- * Portions created by David Baum are Copyright (C) 2000 David Baum.
- * All Rights Reserved.
- *
- * Portions created by John Hansen are Copyright (C) 2005 John Hansen.
- * All Rights Reserved.
- *
- */
- #include "CmdLine.h"
- #include <cstring>
- #include <cctype>
- CmdLine::~CmdLine()
- {
- unsigned int i;
- for(i=0; i<fArgs.size(); ++i)
- {
- delete[] fArgs[i];
- }
- }
- /*
- * Add a single argument
- */
- void CmdLine::Add(const char *a)
- {
- char *s;
- if (!a) return;
- s = new char[strlen(a) + 1];
- strcpy(s, a);
- fArgs.push_back(s);
- }
- /*
- * Add an array of arguments
- */
- void CmdLine::Add(int argc, const char * const *argv)
- {
- int i;
- for(i=0; i<argc; ++i)
- Add(argv[i]);
- }
- /*
- * Parse multiple arguments from a single line.
- *
- * Use double quotes to enclose whitespace within arguments.
- * No escaping is performed. The 'skip' parameter indicates
- * how many of the resulting arguments should be skipped (i.e.
- * not placed in the arg list). This is useful if you want to
- * strip out the first argument (typically the command itself).
- */
- void CmdLine::Parse(const char *line, int skip)
- {
- if (!line) return;
- char *buf = new char[strlen(line)+1];
- char *dst = buf;
- const char *src = line;
- enum
- {
- IDLE = 0,
- READING,
- QUOTING
- } state = IDLE;
- while(true)
- {
- // read chars until no more
- char c = *src++;
- if (c == 0) break;
- if (c == '\"')
- {
- // quote
- if (state == QUOTING)
- state = READING;
- else
- state = QUOTING;
- }
- else if (c== ' ' || c== '\t')
- {
- // whitespace
- if (state == READING)
- {
- // done with argument, terminate it and add to list
- *dst = 0;
- if (skip)
- --skip;
- else
- Add(buf);
- // reset to idle state and empty arg
- state = IDLE;
- dst = buf;
- }
- else if (state == QUOTING)
- *dst++ = c;
- }
- else
- {
- if (state == IDLE)
- state = READING;
- *dst++ = c;
- }
- }
- // add last arg if any
- if (dst > buf)
- {
- *dst = 0;
- if (!skip)
- Add(buf);
- }
- delete [] buf;
- }
- #if 0
- void CmdLine::Parse(const char *line)
- {
- const char *start, *ptr;
- if (!line) return;
- ptr = line;
- while(*ptr)
- {
- // eat up leading whitespace
- for(start = ptr; *start; ++start)
- if (!isspace(*start)) break;
- if (*start == 0) break;
- if (*start == '\"')
- {
- ++start;
- // find closing quote
- for(ptr = start; *ptr; ++ptr)
- {
- if (*ptr == '\\')
- {
- // char was escaped
- if (ptr[1] != 0) ++ptr;
- }
- else if (*ptr == '\"')
- break;
- }
- Add(start, ptr, true);
- if (*ptr == '\"')
- ++ptr;
- }
- else
- {
- // find end of token
- for(ptr = start; *ptr; ++ptr)
- if (isspace(*ptr)) break;
- // new argument
- if (ptr > start)
- Add(start, ptr, false);
- }
- }
- }
- void CmdLine::Add(const char *start, const char *end, bool escape)
- {
- int len = end - start;
- char *arg = new char[len + 1];
- char *dst = arg;
- while(len--)
- {
- if (escape && *start == '\\')
- ++start;
- else
- *dst++ = *start++;
- }
- *dst++ = 0;
- fArgs.Append(arg);
- }
- #endif