xref: /illumos-gate/usr/src/contrib/ast/src/lib/libast/string/tok.c (revision b30d193948be5a7794d7ae3ba0ed9c2f72c88e0f)
1*b30d1939SAndy Fiddaman /***********************************************************************
2*b30d1939SAndy Fiddaman *                                                                      *
3*b30d1939SAndy Fiddaman *               This software is part of the ast package               *
4*b30d1939SAndy Fiddaman *          Copyright (c) 1985-2011 AT&T Intellectual Property          *
5*b30d1939SAndy Fiddaman *                      and is licensed under the                       *
6*b30d1939SAndy Fiddaman *                 Eclipse Public License, Version 1.0                  *
7*b30d1939SAndy Fiddaman *                    by AT&T Intellectual Property                     *
8*b30d1939SAndy Fiddaman *                                                                      *
9*b30d1939SAndy Fiddaman *                A copy of the License is available at                 *
10*b30d1939SAndy Fiddaman *          http://www.eclipse.org/org/documents/epl-v10.html           *
11*b30d1939SAndy Fiddaman *         (with md5 checksum b35adb5213ca9657e911e9befb180842)         *
12*b30d1939SAndy Fiddaman *                                                                      *
13*b30d1939SAndy Fiddaman *              Information and Software Systems Research               *
14*b30d1939SAndy Fiddaman *                            AT&T Research                             *
15*b30d1939SAndy Fiddaman *                           Florham Park NJ                            *
16*b30d1939SAndy Fiddaman *                                                                      *
17*b30d1939SAndy Fiddaman *                 Glenn Fowler <gsf@research.att.com>                  *
18*b30d1939SAndy Fiddaman *                  David Korn <dgk@research.att.com>                   *
19*b30d1939SAndy Fiddaman *                   Phong Vo <kpv@research.att.com>                    *
20*b30d1939SAndy Fiddaman *                                                                      *
21*b30d1939SAndy Fiddaman ***********************************************************************/
22*b30d1939SAndy Fiddaman #pragma prototyped
23*b30d1939SAndy Fiddaman /*
24*b30d1939SAndy Fiddaman  * Glenn Fowler
25*b30d1939SAndy Fiddaman  * AT&T Research
26*b30d1939SAndy Fiddaman  *
27*b30d1939SAndy Fiddaman  * token stream routines
28*b30d1939SAndy Fiddaman  */
29*b30d1939SAndy Fiddaman 
30*b30d1939SAndy Fiddaman #include <ast.h>
31*b30d1939SAndy Fiddaman #include <tok.h>
32*b30d1939SAndy Fiddaman 
33*b30d1939SAndy Fiddaman #define FLG_RESTORE	01		/* restore string on close	*/
34*b30d1939SAndy Fiddaman #define FLG_NEWLINE	02		/* return newline token next	*/
35*b30d1939SAndy Fiddaman 
36*b30d1939SAndy Fiddaman typedef struct Tok_s			/* token stream state		*/
37*b30d1939SAndy Fiddaman {
38*b30d1939SAndy Fiddaman 	union
39*b30d1939SAndy Fiddaman 	{
40*b30d1939SAndy Fiddaman 	char*		end;		/* end ('\0') of last token	*/
41*b30d1939SAndy Fiddaman 	struct Tok_s*	nxt;		/* next in free list		*/
42*b30d1939SAndy Fiddaman 	}		ptr;
43*b30d1939SAndy Fiddaman 	char		chr;		/* replace *end with this	*/
44*b30d1939SAndy Fiddaman 	char		flg;		/* FLG_*			*/
45*b30d1939SAndy Fiddaman } Tok_t;
46*b30d1939SAndy Fiddaman 
47*b30d1939SAndy Fiddaman static Tok_t*		freelist;
48*b30d1939SAndy Fiddaman 
49*b30d1939SAndy Fiddaman /*
50*b30d1939SAndy Fiddaman  * open a new token stream on s
51*b30d1939SAndy Fiddaman  * if f==0 then string is not restored
52*b30d1939SAndy Fiddaman  */
53*b30d1939SAndy Fiddaman 
54*b30d1939SAndy Fiddaman char*
tokopen(register char * s,int f)55*b30d1939SAndy Fiddaman tokopen(register char* s, int f)
56*b30d1939SAndy Fiddaman {
57*b30d1939SAndy Fiddaman 	register Tok_t*	p;
58*b30d1939SAndy Fiddaman 
59*b30d1939SAndy Fiddaman 	if (p = freelist)
60*b30d1939SAndy Fiddaman 		freelist = freelist->ptr.nxt;
61*b30d1939SAndy Fiddaman 	else if (!(p = newof(0, Tok_t, 1, 0)))
62*b30d1939SAndy Fiddaman 		return 0;
63*b30d1939SAndy Fiddaman 	p->chr = *(p->ptr.end = s);
64*b30d1939SAndy Fiddaman 	p->flg = f ? FLG_RESTORE : 0;
65*b30d1939SAndy Fiddaman 	return (char*)p;
66*b30d1939SAndy Fiddaman }
67*b30d1939SAndy Fiddaman 
68*b30d1939SAndy Fiddaman /*
69*b30d1939SAndy Fiddaman  * close a token stream
70*b30d1939SAndy Fiddaman  * restore the string to its original state
71*b30d1939SAndy Fiddaman  */
72*b30d1939SAndy Fiddaman 
73*b30d1939SAndy Fiddaman void
tokclose(char * u)74*b30d1939SAndy Fiddaman tokclose(char* u)
75*b30d1939SAndy Fiddaman {
76*b30d1939SAndy Fiddaman 	register Tok_t*	p = (Tok_t*)u;
77*b30d1939SAndy Fiddaman 
78*b30d1939SAndy Fiddaman 	if (p->flg == FLG_RESTORE && *p->ptr.end != p->chr)
79*b30d1939SAndy Fiddaman 		*p->ptr.end = p->chr;
80*b30d1939SAndy Fiddaman 	p->ptr.nxt = freelist;
81*b30d1939SAndy Fiddaman 	freelist = p;
82*b30d1939SAndy Fiddaman }
83*b30d1939SAndy Fiddaman 
84*b30d1939SAndy Fiddaman /*
85*b30d1939SAndy Fiddaman  * return next space separated token
86*b30d1939SAndy Fiddaman  * "\n" is returned as a token
87*b30d1939SAndy Fiddaman  * 0 returned when no tokens remain
88*b30d1939SAndy Fiddaman  * "..." and '...' quotes are honored with \ escapes
89*b30d1939SAndy Fiddaman  */
90*b30d1939SAndy Fiddaman 
91*b30d1939SAndy Fiddaman char*
tokread(char * u)92*b30d1939SAndy Fiddaman tokread(char* u)
93*b30d1939SAndy Fiddaman {
94*b30d1939SAndy Fiddaman 	register Tok_t*	p = (Tok_t*)u;
95*b30d1939SAndy Fiddaman 	register char*	s;
96*b30d1939SAndy Fiddaman 	register char*	r;
97*b30d1939SAndy Fiddaman 	register int	q;
98*b30d1939SAndy Fiddaman 	register int	c;
99*b30d1939SAndy Fiddaman 
100*b30d1939SAndy Fiddaman 	/*
101*b30d1939SAndy Fiddaman 	 * restore string on each call
102*b30d1939SAndy Fiddaman 	 */
103*b30d1939SAndy Fiddaman 
104*b30d1939SAndy Fiddaman 	if (!p->chr)
105*b30d1939SAndy Fiddaman 		return 0;
106*b30d1939SAndy Fiddaman 	s = p->ptr.end;
107*b30d1939SAndy Fiddaman 	switch (p->flg)
108*b30d1939SAndy Fiddaman 	{
109*b30d1939SAndy Fiddaman 	case FLG_NEWLINE:
110*b30d1939SAndy Fiddaman 		p->flg = 0;
111*b30d1939SAndy Fiddaman 		return "\n";
112*b30d1939SAndy Fiddaman 	case FLG_RESTORE:
113*b30d1939SAndy Fiddaman 		if (*s != p->chr)
114*b30d1939SAndy Fiddaman 			*s = p->chr;
115*b30d1939SAndy Fiddaman 		break;
116*b30d1939SAndy Fiddaman 	default:
117*b30d1939SAndy Fiddaman 		if (!*s)
118*b30d1939SAndy Fiddaman 			s++;
119*b30d1939SAndy Fiddaman 		break;
120*b30d1939SAndy Fiddaman 	}
121*b30d1939SAndy Fiddaman 
122*b30d1939SAndy Fiddaman 	/*
123*b30d1939SAndy Fiddaman 	 * skip leading space
124*b30d1939SAndy Fiddaman 	 */
125*b30d1939SAndy Fiddaman 
126*b30d1939SAndy Fiddaman 	while (*s == ' ' || *s == '\t')
127*b30d1939SAndy Fiddaman 		s++;
128*b30d1939SAndy Fiddaman 	if (!*s)
129*b30d1939SAndy Fiddaman 	{
130*b30d1939SAndy Fiddaman 		p->ptr.end = s;
131*b30d1939SAndy Fiddaman 		p->chr = 0;
132*b30d1939SAndy Fiddaman 		return 0;
133*b30d1939SAndy Fiddaman 	}
134*b30d1939SAndy Fiddaman 
135*b30d1939SAndy Fiddaman 	/*
136*b30d1939SAndy Fiddaman 	 * find the end of this token
137*b30d1939SAndy Fiddaman 	 */
138*b30d1939SAndy Fiddaman 
139*b30d1939SAndy Fiddaman 	r = s;
140*b30d1939SAndy Fiddaman 	q = 0;
141*b30d1939SAndy Fiddaman 	for (;;)
142*b30d1939SAndy Fiddaman 		switch (c = *r++)
143*b30d1939SAndy Fiddaman 		{
144*b30d1939SAndy Fiddaman 		case '\n':
145*b30d1939SAndy Fiddaman 			if (!q)
146*b30d1939SAndy Fiddaman 			{
147*b30d1939SAndy Fiddaman 				if (s == (r - 1))
148*b30d1939SAndy Fiddaman 				{
149*b30d1939SAndy Fiddaman 					if (!p->flg)
150*b30d1939SAndy Fiddaman 					{
151*b30d1939SAndy Fiddaman 						p->ptr.end = r;
152*b30d1939SAndy Fiddaman 						return "\n";
153*b30d1939SAndy Fiddaman 					}
154*b30d1939SAndy Fiddaman 					r++;
155*b30d1939SAndy Fiddaman 				}
156*b30d1939SAndy Fiddaman 				else if (!p->flg)
157*b30d1939SAndy Fiddaman 					p->flg = FLG_NEWLINE;
158*b30d1939SAndy Fiddaman 			}
159*b30d1939SAndy Fiddaman 			/*FALLTHROUGH*/
160*b30d1939SAndy Fiddaman 		case ' ':
161*b30d1939SAndy Fiddaman 		case '\t':
162*b30d1939SAndy Fiddaman 			if (q)
163*b30d1939SAndy Fiddaman 				break;
164*b30d1939SAndy Fiddaman 			/*FALLTHROUGH*/
165*b30d1939SAndy Fiddaman 		case 0:
166*b30d1939SAndy Fiddaman 			if (s == --r)
167*b30d1939SAndy Fiddaman 			{
168*b30d1939SAndy Fiddaman 				p->ptr.end = r;
169*b30d1939SAndy Fiddaman 				p->chr = 0;
170*b30d1939SAndy Fiddaman 			}
171*b30d1939SAndy Fiddaman 			else
172*b30d1939SAndy Fiddaman 			{
173*b30d1939SAndy Fiddaman 				p->chr = *(p->ptr.end = r);
174*b30d1939SAndy Fiddaman 				if (*r)
175*b30d1939SAndy Fiddaman 					*r = 0;
176*b30d1939SAndy Fiddaman 			}
177*b30d1939SAndy Fiddaman 			return s;
178*b30d1939SAndy Fiddaman 		case '\\':
179*b30d1939SAndy Fiddaman 			if (*r)
180*b30d1939SAndy Fiddaman 				r++;
181*b30d1939SAndy Fiddaman 			break;
182*b30d1939SAndy Fiddaman 		case '"':
183*b30d1939SAndy Fiddaman 		case '\'':
184*b30d1939SAndy Fiddaman 			if (c == q)
185*b30d1939SAndy Fiddaman 				q = 0;
186*b30d1939SAndy Fiddaman 			else if (!q)
187*b30d1939SAndy Fiddaman 				q = c;
188*b30d1939SAndy Fiddaman 			break;
189*b30d1939SAndy Fiddaman 		}
190*b30d1939SAndy Fiddaman }
191