1/***********************************************************************
2*                                                                      *
3*               This software is part of the ast package               *
4*          Copyright (c) 1985-2010 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
42Recfmt_t
43recstr(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				s = (const char*)t - 1;
184				continue;
185			}
186			break;
187		}
188		if (e)
189			*e = (char*)s;
190		if (a[3] > (a[1] - a[2]))
191			a[3] = a[1] - a[2];
192		return REC_V_RECORD(REC_V_TYPE(a[1], a[2], a[3], a[4], a[5]), a[0]);
193	case '%':
194		if (e)
195			*e = (char*)s + 1;
196		return REC_M_TYPE(REC_M_path);
197	case '-':
198	case '?':
199		if (e)
200			*e = (char*)s + 1;
201		return REC_M_TYPE(REC_M_data);
202	}
203	if (e)
204		*e = (char*)s;
205	return REC_N_TYPE();
206}
207