source: trunk/third/sysinfo/strutil.c @ 12269

Revision 12269, 5.6 KB checked in by ghudson, 26 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r12268, which included commits to RCS files with non-trunk default branches.
Line 
1/*
2 * Copyright (c) 1992-1998 Michael A. Cooper.
3 * This software may be freely used and distributed provided it is not
4 * sold for profit or used in part or in whole for commercial gain
5 * without prior written agreement, and the author is credited
6 * appropriately.
7 */
8
9#ifndef lint
10static char *RCSid = "$Revision: 1.1.1.3 $";
11#endif
12
13/*
14 * String utility functions
15 */
16#include "defs.h"
17#include "strutil.h"
18
19/*
20 * Is What in List?
21 */
22int IsSep(What, List)
23    int                         What;
24    char                       *List;
25{
26    register char              *cp;
27
28    for (cp = List; cp < &List[strlen(List)]; ++cp)
29        if (What == *cp)
30            return(1);
31
32    return(0);
33}
34
35/*
36 * Find the first seperator from List in String and
37 * return a pointer.
38 */
39char *FindSep(String, List)
40    char                       *String;
41    char                       *List;
42{
43    register char              *cp;
44
45    for (cp = String; cp < &String[strlen(String)]; ++cp)
46        if (IsSep(*cp, List))
47            return(cp);
48
49    return((char *)NULL);
50}
51
52/*
53 * Is What a quote character?  If so, return the ending quote char
54 * which is the next char in QuoteChars.  QuoteChars may contain
55 * multiple pairs of quote characters. e.g ""<>''`'
56 */
57int IsQuote(What, QuoteChars)
58     int                        What;
59     char                      *QuoteChars;
60{
61    int                         QuotePair;
62    static int                  NumQuotes;
63    static char                *LastQuoteChars;
64
65    if (!QuoteChars)
66        return(0);
67
68    if (LastQuoteChars != QuoteChars || !NumQuotes)
69        NumQuotes = strlen(QuoteChars);
70    LastQuoteChars = QuoteChars;
71
72    for (QuotePair = 0; QuotePair < NumQuotes; QuotePair += 2) {
73        if (What == QuoteChars[QuotePair])
74            return(QuoteChars[QuotePair+1]);
75    }
76
77    return(0);
78}
79
80/*
81 * Parse a string into an argument vector.
82 * List is the string to be parsed.
83 * SepChars is the list of seperator characters which will be used to
84 *              break apart List.
85 * ArgvPtr is where the argument results will be stored.
86 * QuoteChars is the list of characters which indicate single arguments.
87 *              This is a list of pairs.  The first char indicated begining
88 *              of quoted argument, the next char indicates end. e.g ""<>''`'
89 */
90extern int
91StrToArgv(List, SepChars, ArgvPtr, QuoteChars, Flags)
92    char                       *List;
93    char                       *SepChars;
94    char                     ***ArgvPtr;
95    char                       *QuoteChars;
96    int                         Flags;
97{
98    char                      **Argv = NULL;
99    char                       *String;
100    char                       *Ptr;
101    char                       *Start;
102    char                       *Next;
103    char                       *End;
104    int                         EndQuote;
105    register char              *cp;
106    register int                Count;
107    register int                i;
108
109    if (!List)
110        return(0);
111
112    String = List;
113    for (Count = 0, Ptr = String; Ptr && *Ptr; ++Ptr) {
114        if (EndQuote = IsQuote(*Ptr, QuoteChars))
115            while (*(++Ptr) != EndQuote);
116        if (IsSep(*Ptr, SepChars))
117            ++Count;
118        if (FLAGS_ON(Flags, STRTO_SKIPRP)) {
119            /* Skip over rest of SepChars for now */
120            while (Ptr && *Ptr && IsSep(*Ptr, SepChars))
121                ++Ptr;
122        }
123    }
124
125    /*
126     * Watch for ending seperator
127     */
128    if (IsSep(*(Ptr-1), SepChars))
129        --Count;
130
131    /*
132     * There's only one argument with no seperator?
133     */
134    if (Count == 0 && String && *String)
135        ++Count;
136    else if (!Count)
137        return(0);
138    else
139        Count++;
140
141    Argv = (char **) xcalloc(Count+1, sizeof(char *));
142
143    /*
144     * We don't use strtok() because it doesn't like back-to-back
145     * seperators.  e.g. "foo||bar" will skip the NULL argument.
146     * strtok() also doesn't do QuoteChars like we do.
147     */
148    for (i = 0, Start = NULL, Ptr = String; i < Count; ++i) {
149        Start = Ptr;
150        if (!isspace(*SepChars))
151            /* Skip leading white space */
152            for ( ; Start && *Start && isspace(*Start); ++Start);
153        if (EndQuote = IsQuote(*Start, QuoteChars))
154            ++Start;
155        /* Find end of word */
156        for (End = Start; End && *End; ++End) {
157            if (EndQuote) {
158                if (*End == EndQuote)
159                    break;
160            } else if (IsSep(*End, SepChars))
161                break;
162        }
163        /* Mark next field */
164        Next = End;
165        if (Next)
166            ++Next;
167        /* Remove trailing white space */
168        if (!isspace(*SepChars) && isspace(*(End-1))) {
169            while (--End > Start && *End && isspace(*End));
170            ++End;
171        }
172        if (End > Start) {
173            Argv[i] = (char *) xmalloc( (End - Start) + 1 );
174            (void) strncpy(Argv[i], Start, End - Start);
175            Argv[i][End - Start] = CNULL;
176        }
177        Ptr = Next;
178        if (!Next)
179            break;
180        if (FLAGS_ON(Flags, STRTO_SKIPRP)) {
181            /* Skip over rest of SepChars for now */
182            while (Ptr && *Ptr && IsSep(*Ptr, SepChars))
183                ++Ptr;
184        }
185    }
186
187    *ArgvPtr = Argv;
188
189    return(Count);
190}
191
192/*
193 * Destroy an argument vector such as was created by StrToArgv().
194 */
195extern void
196DestroyArgv(ArgvPtr, Argc)
197    char                     ***ArgvPtr;
198    int                         Argc;
199{
200    register int                i;
201    char                      **Argv;
202
203    if (Argc <= 0 || !ArgvPtr)
204        return;
205
206    Argv = *ArgvPtr;
207    for (i = 0; i < Argc; ++i)
208        if (Argv[i])
209            (void) free(Argv[i]);
210
211    (void) free(*ArgvPtr);
212    *ArgvPtr = NULL;
213}
214
215/*
216 * Make String all lower case.
217 */
218extern void strtolower(String)
219    char                       *String;
220{
221    register char              *cp;
222
223    for (cp = String; cp && *cp; ++cp)
224        if (isupper(*cp))
225            *cp = tolower(*cp);
226}
227
228/*
229 * Return an all lower case version of String
230 */
231extern char *strlower(String)
232    char                       *String;
233{
234    static char                *Buffer = NULL;
235    register char              *cp;
236
237    if (Buffer)
238        free(Buffer);
239
240    Buffer = strdup(String);
241
242    for (cp = Buffer; cp && *cp; ++cp)
243        if (isupper(*cp))
244            *cp = tolower(*cp);
245
246    return(Buffer);
247}
248
249/*
250 * Return an all upper case version of String
251 */
252extern char *strupper(String)
253    char                       *String;
254{
255    static char                *Buffer = NULL;
256    register char              *cp;
257
258    if (Buffer)
259        free(Buffer);
260
261    Buffer = strdup(String);
262
263    for (cp = Buffer; cp && *cp; ++cp)
264        if (islower(*cp))
265            *cp = toupper(*cp);
266
267    return(Buffer);
268}
Note: See TracBrowser for help on using the repository browser.