xref: /titanic_41/usr/src/lib/libast/common/misc/recstr.c (revision 450396635f70344c58b6b1e4db38cf17ff34445c)
1 /***********************************************************************
2 *                                                                      *
3 *               This software is part of the ast package               *
4 *          Copyright (c) 1985-2008 AT&T Intellectual Property          *
5 *                      and is licensed under the                       *
6 *                  Common Public License, Version 1.0                  *
7 *                    by AT&T Intellectual Property                     *
8 *                                                                      *
9 *                A copy of the License is available at                 *
10 *            http://www.opensource.org/licenses/cpl1.0.txt             *
11 *         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
12 *                                                                      *
13 *              Information and Software Systems Research               *
14 *                            AT&T Research                             *
15 *                           Florham Park NJ                            *
16 *                                                                      *
17 *                 Glenn Fowler <gsf@research.att.com>                  *
18 *                  David Korn <dgk@research.att.com>                   *
19 *                   Phong Vo <kpv@research.att.com>                    *
20 *                                                                      *
21 ***********************************************************************/
22 #pragma prototyped
23 
24 /*
25  * return the record format descriptor given a format string
26  * e!=0 set to the first unrecognized char after the format
27  * REC_N_TYPE() returned on error
28  *
29  *	d[0xNN|delimiter] (delimited, newline default)
30  *	[f][+]size (fixed length)
31  *	v hN oN zN b|l i|n (variable length with size header)
32  *	  h   header size in bytes (ibm V 4)
33  *	  o   size offset in bytes (ibm V 0)
34  *	  z   size length in bytes (ibm V 2)
35  *	  l|b little-endian or big-endian size (ibm V b (0))
36  *	  i|n header included/not-included in size (ibm V i (1))
37  */
38 
39 #include <recfmt.h>
40 #include <ctype.h>
41 
42 Recfmt_t
43 recstr(register const char* s, char** e)
44 {
45 	char*	t;
46 	int	n;
47 	long	v;
48 	int	a[6];
49 
50 	while (*s == ' ' || *s == '\t' || *s == ',')
51 		s++;
52 	switch (*s)
53 	{
54 	case 'd':
55 	case 'D':
56 		if (!*s)
57 			n = '\n';
58 		else
59 		{
60 			if (*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X'))
61 				n = (int)strtol(s, &t, 0);
62 			else
63 				n = chresc(s, &t);
64 			s = (const char*)t;
65 		}
66 		if (e)
67 			*e = (char*)s;
68 		return REC_D_TYPE(n);
69 	case 'f':
70 	case 'F':
71 		while (*++s == ' ' || *s == '\t' || *s == ',');
72 		/*FALLTHROUGH*/
73 	case '+':
74 	case '0': case '1': case '2': case '3': case '4':
75 	case '5': case '6': case '7': case '8': case '9':
76 		n = strton(s, &t, NiL, 0);
77 		if (n > 0 && t > (char*)s)
78 		{
79 			if (e)
80 				*e = t;
81 			return REC_F_TYPE(n);
82 		}
83 		break;
84 	case 'm':
85 	case 'M':
86 		while (*++s == ' ' || *s == '\t' || *s == ',');
87 		for (t = (char*)s; *t && *t != ' ' && *t != '\t' && *t != ','; t++);
88 		if ((t - s) == 4)
89 		{
90 			if (strneq(s, "data", 4))
91 			{
92 				if (e)
93 					*e = t;
94 				return REC_M_TYPE(REC_M_data);
95 			}
96 			else if (strneq(s, "path", 4))
97 			{
98 				if (e)
99 					*e = t;
100 				return REC_M_TYPE(REC_M_path);
101 			}
102 		}
103 
104 		/*
105 		 * TBD: look up name in method libraries
106 		 *	and assign an integer index
107 		 */
108 
109 		break;
110 	case 'u':
111 	case 'U':
112 		while (*++s == ' ' || *s == '\t' || *s == ',');
113 		n = strtol(s, &t, 0);
114 		if (n < 0 || n > 15 || *t++ != '.')
115 			break;
116 		v = strtol(t, &t, 0);
117 		if (*t)
118 			break;
119 		if (e)
120 			*e = t;
121 		return REC_U_TYPE(n, v);
122 	case 'v':
123 	case 'V':
124 		a[0] = 0;
125 		a[1] = 4;
126 		a[2] = 0;
127 		a[3] = 2;
128 		a[4] = 0;
129 		a[5] = 1;
130 		n = 0;
131 		for (;;)
132 		{
133 			switch (*++s)
134 			{
135 			case 0:
136 				break;
137 			case 'm':
138 			case 'M':
139 				n = 0;
140 				continue;
141 			case 'h':
142 			case 'H':
143 				n = 1;
144 				continue;
145 			case 'o':
146 			case 'O':
147 				n = 2;
148 				continue;
149 			case 'z':
150 			case 'Z':
151 				n = 3;
152 				continue;
153 			case 'b':
154 			case 'B':
155 				n = 4;
156 				a[n++] = 0;
157 				continue;
158 			case 'l':
159 			case 'L':
160 				n = 4;
161 				a[n++] = 1;
162 				continue;
163 			case 'n':
164 			case 'N':
165 				n = 0;
166 				a[5] = 0;
167 				continue;
168 			case 'i':
169 			case 'I':
170 				n = 0;
171 				a[5] = 1;
172 				continue;
173 			case ' ':
174 			case '\t':
175 			case ',':
176 			case '-':
177 			case '+':
178 				continue;
179 			case '0': case '1': case '2': case '3': case '4':
180 			case '5': case '6': case '7': case '8': case '9':
181 				v = 0;
182 				a[n++] = strtol(s, &t, 0);
183 				if (t > s && (*(t - 1) == 'l' || *(t - 1) == 'L'))
184 					t--;
185 				s = (const char*)t - 1;
186 				continue;
187 			}
188 			break;
189 		}
190 		if (e)
191 			*e = (char*)s;
192 		if (a[3] > (a[1] - a[2]))
193 			a[3] = a[1] - a[2];
194 		return REC_V_RECORD(REC_V_TYPE(a[1], a[2], a[3], a[4], a[5]), a[0]);
195 	case '%':
196 		if (e)
197 			*e = (char*)s + 1;
198 		return REC_M_TYPE(REC_M_path);
199 	case '-':
200 	case '?':
201 		if (e)
202 			*e = (char*)s + 1;
203 		return REC_M_TYPE(REC_M_data);
204 	}
205 	if (e)
206 		*e = (char*)s;
207 	return REC_N_TYPE();
208 }
209