123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435 |
- /*
- * CDE - Common Desktop Environment
- *
- * Copyright (c) 1993-2012, The Open Group. All rights reserved.
- *
- * These libraries and programs are free software; you can
- * redistribute them and/or modify them under the terms of the GNU
- * Lesser General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * These libraries and programs are distributed in the hope that
- * they will be useful, but WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with these libraries and programs; if not, write
- * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
- * Floor, Boston, MA 02110-1301 USA
- */
- /*
- * File: CmdUtility.c $XConsortium: CmdUtility.c /main/4 1995/10/26 15:18:41 rswiston $
- * Language: C
- *
- * (c) Copyright 1988, Hewlett-Packard Company, all rights reserved.
- *
- * (c) Copyright 1993, 1994 Hewlett-Packard Company *
- * (c) Copyright 1993, 1994 International Business Machines Corp. *
- * (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
- * (c) Copyright 1993, 1994 Novell, Inc. *
- */
- #include <ctype.h>
- #include <stdio.h>
- #include <string.h>
- #include <sys/param.h>
- #include <unistd.h>
- #include <limits.h>
- #include <sys/stat.h>
- #include <X11/Xlib.h>
- #include <X11/Intrinsic.h>
- #include <X11/StringDefs.h>
- #include <Dt/Utility.h>
- #include <Dt/DtNlUtils.h>
- #define _SINGLE "\'"
- #define _DOUBLE "\""
- /******** Static Function Declarations ********/
- static void SkipWhiteSpace(
- String string,
- int *position) ;
- static void FillWord(
- char *string,
- char *word,
- int *position) ;
- static void GetWordWithQuotes(
- String string,
- String word,
- int *position) ;
- /******** End Static Function Declarations ********/
- /*****************************************************************************
- *
- * SkipWhiteSpace - takes a string and in index ("position") into the
- * string and advances "position" until a non-whitespace character is
- * encountered.
- *
- * A "whitespace" character is defined by "isspace".
- *
- * PARAMETERS:
- *
- * String string; - The string to search.
- *
- * int *position; - MODIFIED: Set to the location of the first
- * non-whitespace character.
- *
- *****************************************************************************/
- static void
- SkipWhiteSpace(
- String string,
- int *position )
- {
- string += (*position);
- while (
- #ifdef NLS16
- (!is_multibyte || (mblen (string, MB_CUR_MAX) == 1)) &&
- #endif
- isspace ((u_char)*string)) {
- string++;
- (*position)++;
- }
- }
- /*****************************************************************************
- *
- * FillWord - parses "string" for a complete argument and puts the
- * result in "word".
- *
- * The algorithm was derived by empirical observation and checking the
- * (poorly written) Bourne Shell tutorial. A BNF for the shell meta
- * characters ", ', and \ was not availble.
- *
- * The algorithm - until the end of the word is found:
- *
- * For each character "c":
- * If c = \, remove the \ and pass on the next char.
- *
- * If c = ' or ", must save this in "qchar" and loop until the
- * ending quote is found:
- * c = the next char
- * If c = qchar, found the ending quote, exit this loop
- * If c = \
- * If qchar = double quote and c2 = next char
- * if c2 = \, ", $, or `, remove c and pass on c2
- * otherwise, pass on both c and c2
- * If qchar = single quote, and c2 = next char:
- * if c2 = ', pass on c, remove the ' and exit this loop
- * (the ' cannot be escaped)
- * otherwise, pass on both c and c2
- * Othewise, pass on c
- *
- * If c = white space, found the end of the word, return
- * Otherwise, pass on the char
- *
- *
- * PARAMETERS:
- *
- * char *string; - The string to search.
- *
- * char *word; - MODIFIED: Points to the beginning of the word.
- *
- * int *position - MODIFIED: Starts at the beginning of the string
- * and gets advanced past "word".
- *
- *****************************************************************************/
- static void
- FillWord(
- char *string,
- char *word,
- int *position )
- {
- char *qchar;
- int len, i;
- Boolean found = False;
- Boolean done = False;
- int j = 0;
- char *pbeg = string;
- while ((*string != '\0') && (!found)) {
- /*
- * Check for multibyte chars. The assumption here is that if
- * is_multibyte is true and "string" points to a multi-byte char,
- * then that entire char should be copied to "word".
- */
- #ifdef NLS16
- if (is_multibyte && ((len = mblen (string, MB_CUR_MAX)) > 1))
- for (i=0; i < len; i++, j++, string++)
- word[j] = *string;
- else
- #endif
- {
- switch (*string) {
- case '\\':
- /* Remove the slash and add the following character. */
- string++;
- #ifdef NLS16
- if (is_multibyte && ((len = mblen (string, MB_CUR_MAX)) > 1))
- for (i=0; i < len; i++, j++, string++)
- word[j] = *string;
- else
- #endif
- word[j++] = *(string)++;
- break;
- case '\'':
- case '\"':
- qchar = _DOUBLE;
- if (*string == '\'') qchar = _SINGLE;
- string++;
- /* Search for the ending quote. */
- done = False;
- while ((!done) && (*string != '\0')) {
- #ifdef NLS16
- if (is_multibyte && ((len = mblen (string, MB_CUR_MAX)) > 1))
- for (i=0; i < len; i++, j++, string++)
- word[j] = *string;
- else
- #endif
- {
- if (*string == *qchar) {
- done = True;
- string++;
- break;
- }
- if (*string == '\\') {
- /* Must follow the rules of the single or double
- * quote - which ever "qchar" points to.
- */
- if (!strcmp (qchar, _DOUBLE)) {
- if ((DtStrcspn (string+1, "\"\\$`")) == 0) {
- /* Skip past the '\', but fill in the
- * following character.
- */
- string++;
- }
- else
- /* Want to pass on both the '\' and the
- * following char.
- */
- word[j++] = *(string)++;
- /* The '\' is skipped. Fill in the next char. */
- #ifdef NLS16
- if (is_multibyte && ((len = mblen (string, MB_CUR_MAX)) > 1))
- for (i=0; i < len; i++, j++, string++)
- word[j] = *string;
- else
- #endif
- word[j++] = *(string)++;
- /* The \ and following char are now skipped. */
- }
- else if (!strcmp (qchar, _SINGLE)) {
- /* Must be working on a _SINGLE quoted word. */
- if ((DtStrcspn (string+1, "\'")) == 0) {
- /*
- * Have \', which passes on the \, skips
- * the single quote and ends the word. An
- * assumption here is that the char following
- * the '\' was a single byte single quote
- * and there is no need for checking multi-byte.
- */
- word[j++] = *(string)++;
- /* Now skip the quote. */
- string++;
- done = True;
- break;
- }
- else {
- /*
- * Need to pass on both chars. Pass on the
- * first char here.
- */
- word[j++] = *(string)++;
- /*
- * The '\' is skipped if present. Fill in the
- * next char.
- */
- #ifdef NLS16
- if (is_multibyte && ((len = mblen (string, MB_CUR_MAX)) > 1))
- for (i=0; i < len; i++, j++, string++)
- word[j] = *string;
- else
- #endif
- /* Pass on what ever char is there. */
- word[j++] = *(string)++;
- }
- }
- }
- else
- /* This char was not escaped, just add it. */
- word[j++] = *(string)++;
- }
- }
- break;
- case ' ':
- case '\t':
- /* Found the end of the word. */
- found = True;
- string++;
- break;
- default: {
- word[j++] = *(string)++;
- }
- }
- }
- }
- word [j] = '\0';
- *position = *position + (string - pbeg);
- }
- /*****************************************************************************
- *
- * GetWordWithQuotes - takes the strings "string" and "word" and an index
- * into "string" and fills "word" with one word from "string".
- *
- * A word is defined in the function "FillWord".
- *
- * Note that if an ending quote is not found, "position" will be advanced to
- * the end of the string.
- *
- * PARAMETERS:
- *
- * String string; - String containing the word to be extracted.
- *
- * String word; - MODIFIED - contains the next word in "string".
- *
- * int *position; - MODIFIED - starts at beginning of word, ends
- * at end of word.
- *
- *****************************************************************************/
- static void
- GetWordWithQuotes(
- String string,
- String word,
- int *position )
- {
- int len = strlen(string);
- SkipWhiteSpace (string, position);
- if ((*position) >= len) {
- word[0] = '\0';
- return;
- }
- string += (*position);
- FillWord (string, word, position);
- }
- /*****************************************************************************
- *
- * _DtCmdStringToArrayOfStrings - takes a string and an array of pointers
- * to strings and breaks the string into whitespace separated words.
- *
- * A "word" is a sequence of characters that has no whitespace with
- * the following exception:
- *
- * - A word may contain contain whitespace if it is delimited
- * by a pair of matching single or double qotes.
- *
- * "Whitespace" is a tab or blank character.
- *
- *
- * NOTES:
- *
- * - The space for the "words" is malloc'd and must be free'd by
- * the caller.
- *
- * - "theArray" is NULL terminated.
- *
- * PARAMETERS:
- *
- * char theString[]; - The string to parse.
- *
- * char *theArray[]; - MODIFIED: gets filled with pointers to
- * the words that are parsed.
- *
- *****************************************************************************/
- void
- _DtCmdStringToArrayOfStrings(
- char theString[],
- char *theArray[] )
- {
- int len, i, position;
- char *tmp;
- tmp = (char *) XtMalloc (1 + strlen (theString));
- len=strlen(theString);
- for (position=0, i=0; (position <= len) &&
- (theString[position] != '\0'); ) {
- (void) strcpy (tmp, "");
- GetWordWithQuotes (theString, tmp, &position);
- /* Check word to see if it contains only trailing blanks. */
- if (tmp[0] == '\0')
- {
- if (position < len)
- {
- /*
- * This parameter is empty, such as "" or '' but we are
- * not at the end of the line. Consequently, put an
- * empty string in "theArray".
- */
- theArray[i] = XtNewString ("");
- }
- else
- {
- /*
- * Must be at the end of the line.
- */
- theArray[i] = (char *) NULL;
- break;
- }
- }
- else
- theArray[i] = XtNewString (tmp);
- i++;
- }
- /* Null terminate the array of string pointers. */
- theArray[i]=NULL;
- XtFree ((char *) tmp);
- }
- /******************************************************************************
- *
- * _DtCmdFreeStringVector - takes an array of pointers to strings and
- * frees the malloc'd space for the strings.
- *
- * This does NOT free the string vector itself; It assumes that
- * stringv is a static i.e. char *stringv[N].
- *
- * PARAMETERS:
- *
- * char **stringv; - MODIFIED: Each string in the array is freed.
- *
- *****************************************************************************/
- void
- _DtCmdFreeStringVector(
- char **stringv )
- {
- char **pch;
- for (pch = stringv; *pch != NULL; pch++) {
- XtFree (*pch);
- *pch = NULL;
- }
- }
|