summaryrefslogtreecommitdiffstats
path: root/src/isode/compat/sstr2arg.c
blob: 745870393c2b22a4a826b8fce1856bd4bee1fb46 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/* sstr2arg: convert string into argument list */

/* 
 * isode/compat/sstr2arg.c
 */

/*
 *				  NOTICE
 *
 *    Acquisition, use, and distribution of this module and related
 *    materials are subject to the restrictions of a license agreement.
 *    Consult the Preface in the User's Manual for the full terms of
 *    this agreement.
 *
 */


/* LINTLIBRARY */

#include <stdio.h>
#include "manifest.h"
#include "general.h"
#include <errno.h>
extern int errno;

/*  */

/*
   stash a pointer to each field into the passed array. any common seperators
   split the words.  extra white-space between fields is ignored.

   specially-interpreted characters:
	double-quote, backslash (preceding a special char with a backslash
	removes its interpretation.  A backslash not followed by a special is
	used to preface an octal specification for one character a string begun
	with double-quote has only double-quote and backslash as special
	characters.

*/




sstr2arg (srcptr, maxpf, argv, dlmstr)
register char *srcptr;  /* source data */
int maxpf;              /* maximum number of permitted fields */
char *argv[];           /* where to put the pointers */
char *dlmstr;           /* Delimiting character */
{
    char gotquote;		/* currently parsing quoted string */
    register int ind;
    register char *destptr;
    char idex[256];

    if (srcptr == 0)
	return (NOTOK);

    memset (idex, 0, sizeof idex);
    for (destptr = dlmstr; *destptr; destptr++)
	idex[*destptr] = 1;

    for (ind = 0, maxpf -= 2;; ind++) {
	if (ind >= maxpf) 
	    return (NOTOK);

	/* Skip leading white space */
	for (; *srcptr == ' ' || *srcptr == '\t'; srcptr++);

	argv [ind] = srcptr;
	destptr = srcptr;

	for (gotquote = 0; ; ) {

	    if (idex[*srcptr])
	    {
		if (gotquote) {	/* don't interpret the char */
		    *destptr++ = *srcptr++;
		    continue;
		}

		srcptr++;
		*destptr = '\0';
		goto nextarg;
	    } else {
		switch (*srcptr) {
		default:	/* just copy it                     */
		    *destptr++ = *srcptr++;
		    break;

		case '\"':	/* beginning or end of string       */
		    gotquote = (gotquote) ? 0 : 1 ;
		    srcptr++;	/* just toggle */
		    break;

		case '\\':	/* quote next character     */
		    srcptr++;	/* skip the back-slash      */
		    switch (*srcptr) {
			/* Octal character	    */
		    case '0': case '1':
		    case '2': case '3': 
		    case '4': case '5':
		    case '6': case '7': 
			*destptr = '\0';
			do
			    *destptr = (*destptr << 3) | (*srcptr++ - '0');
			while (*srcptr >= '0' && *srcptr <= '7');
			destptr++;
			break;
			/* C escape char	    */
		    case 'b':
			*destptr++ = '\b';
			srcptr++;
			break;
		    case 'n':
			*destptr++ = '\n';
			srcptr++;
			break;
		    case 'r':
			*destptr++ = '\r';
			srcptr++;
			break;
		    case 't':
			*destptr++ = '\t';
			srcptr++;
			break;
						
			/* Boring -- just copy ASIS */
		    default:
			*destptr++ = *srcptr++;
		    }
		    break;

		case '\0':
		    *destptr = '\0';
		    ind++;
		    argv[ind] = (char *) 0;
		    return (ind);
		}
	    }
	}
    nextarg:
	continue;
    }
}