Initial import of the CDE 2.1.30 sources from the Open Group.
This commit is contained in:
416
cde/lib/DtSvc/DtUtil2/CmdUtility.c
Normal file
416
cde/lib/DtSvc/DtUtil2/CmdUtility.c
Normal file
@@ -0,0 +1,416 @@
|
||||
/*
|
||||
* 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 <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#ifdef __apollo
|
||||
#include "/sys5/usr/include/unistd.h"
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user