xref: /onnv-gate/usr/src/lib/libast/common/misc/recstr.c (revision 12068:08a39a083754)
14887Schin /***********************************************************************
24887Schin *                                                                      *
34887Schin *               This software is part of the ast package               *
4*12068SRoger.Faulkner@Oracle.COM *          Copyright (c) 1985-2010 AT&T Intellectual Property          *
54887Schin *                      and is licensed under the                       *
64887Schin *                  Common Public License, Version 1.0                  *
78462SApril.Chin@Sun.COM *                    by AT&T Intellectual Property                     *
84887Schin *                                                                      *
94887Schin *                A copy of the License is available at                 *
104887Schin *            http://www.opensource.org/licenses/cpl1.0.txt             *
114887Schin *         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
124887Schin *                                                                      *
134887Schin *              Information and Software Systems Research               *
144887Schin *                            AT&T Research                             *
154887Schin *                           Florham Park NJ                            *
164887Schin *                                                                      *
174887Schin *                 Glenn Fowler <gsf@research.att.com>                  *
184887Schin *                  David Korn <dgk@research.att.com>                   *
194887Schin *                   Phong Vo <kpv@research.att.com>                    *
204887Schin *                                                                      *
214887Schin ***********************************************************************/
224887Schin #pragma prototyped
234887Schin 
244887Schin /*
254887Schin  * return the record format descriptor given a format string
264887Schin  * e!=0 set to the first unrecognized char after the format
274887Schin  * REC_N_TYPE() returned on error
284887Schin  *
294887Schin  *	d[0xNN|delimiter] (delimited, newline default)
304887Schin  *	[f][+]size (fixed length)
314887Schin  *	v hN oN zN b|l i|n (variable length with size header)
324887Schin  *	  h   header size in bytes (ibm V 4)
334887Schin  *	  o   size offset in bytes (ibm V 0)
344887Schin  *	  z   size length in bytes (ibm V 2)
354887Schin  *	  l|b little-endian or big-endian size (ibm V b (0))
364887Schin  *	  i|n header included/not-included in size (ibm V i (1))
374887Schin  */
384887Schin 
394887Schin #include <recfmt.h>
404887Schin #include <ctype.h>
414887Schin 
424887Schin Recfmt_t
recstr(register const char * s,char ** e)434887Schin recstr(register const char* s, char** e)
444887Schin {
454887Schin 	char*	t;
464887Schin 	int	n;
474887Schin 	long	v;
484887Schin 	int	a[6];
494887Schin 
504887Schin 	while (*s == ' ' || *s == '\t' || *s == ',')
514887Schin 		s++;
524887Schin 	switch (*s)
534887Schin 	{
544887Schin 	case 'd':
554887Schin 	case 'D':
564887Schin 		if (!*s)
574887Schin 			n = '\n';
584887Schin 		else
594887Schin 		{
604887Schin 			if (*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X'))
614887Schin 				n = (int)strtol(s, &t, 0);
624887Schin 			else
634887Schin 				n = chresc(s, &t);
644887Schin 			s = (const char*)t;
654887Schin 		}
664887Schin 		if (e)
674887Schin 			*e = (char*)s;
684887Schin 		return REC_D_TYPE(n);
694887Schin 	case 'f':
704887Schin 	case 'F':
714887Schin 		while (*++s == ' ' || *s == '\t' || *s == ',');
724887Schin 		/*FALLTHROUGH*/
734887Schin 	case '+':
744887Schin 	case '0': case '1': case '2': case '3': case '4':
754887Schin 	case '5': case '6': case '7': case '8': case '9':
764887Schin 		n = strton(s, &t, NiL, 0);
774887Schin 		if (n > 0 && t > (char*)s)
784887Schin 		{
794887Schin 			if (e)
804887Schin 				*e = t;
814887Schin 			return REC_F_TYPE(n);
824887Schin 		}
834887Schin 		break;
844887Schin 	case 'm':
854887Schin 	case 'M':
864887Schin 		while (*++s == ' ' || *s == '\t' || *s == ',');
874887Schin 		for (t = (char*)s; *t && *t != ' ' && *t != '\t' && *t != ','; t++);
884887Schin 		if ((t - s) == 4)
894887Schin 		{
904887Schin 			if (strneq(s, "data", 4))
914887Schin 			{
924887Schin 				if (e)
934887Schin 					*e = t;
944887Schin 				return REC_M_TYPE(REC_M_data);
954887Schin 			}
964887Schin 			else if (strneq(s, "path", 4))
974887Schin 			{
984887Schin 				if (e)
994887Schin 					*e = t;
1004887Schin 				return REC_M_TYPE(REC_M_path);
1014887Schin 			}
1024887Schin 		}
1034887Schin 
1044887Schin 		/*
1054887Schin 		 * TBD: look up name in method libraries
1064887Schin 		 *	and assign an integer index
1074887Schin 		 */
1084887Schin 
1094887Schin 		break;
1104887Schin 	case 'u':
1114887Schin 	case 'U':
1124887Schin 		while (*++s == ' ' || *s == '\t' || *s == ',');
1134887Schin 		n = strtol(s, &t, 0);
1144887Schin 		if (n < 0 || n > 15 || *t++ != '.')
1154887Schin 			break;
1164887Schin 		v = strtol(t, &t, 0);
1174887Schin 		if (*t)
1184887Schin 			break;
1194887Schin 		if (e)
1204887Schin 			*e = t;
1214887Schin 		return REC_U_TYPE(n, v);
1224887Schin 	case 'v':
1234887Schin 	case 'V':
1244887Schin 		a[0] = 0;
1254887Schin 		a[1] = 4;
1264887Schin 		a[2] = 0;
1274887Schin 		a[3] = 2;
1284887Schin 		a[4] = 0;
1294887Schin 		a[5] = 1;
1304887Schin 		n = 0;
1314887Schin 		for (;;)
1324887Schin 		{
1334887Schin 			switch (*++s)
1344887Schin 			{
1354887Schin 			case 0:
1364887Schin 				break;
1374887Schin 			case 'm':
1384887Schin 			case 'M':
1394887Schin 				n = 0;
1404887Schin 				continue;
1414887Schin 			case 'h':
1424887Schin 			case 'H':
1434887Schin 				n = 1;
1444887Schin 				continue;
1454887Schin 			case 'o':
1464887Schin 			case 'O':
1474887Schin 				n = 2;
1484887Schin 				continue;
1494887Schin 			case 'z':
1504887Schin 			case 'Z':
1514887Schin 				n = 3;
1524887Schin 				continue;
1534887Schin 			case 'b':
1544887Schin 			case 'B':
1554887Schin 				n = 4;
1564887Schin 				a[n++] = 0;
1574887Schin 				continue;
1584887Schin 			case 'l':
1594887Schin 			case 'L':
1604887Schin 				n = 4;
1614887Schin 				a[n++] = 1;
1624887Schin 				continue;
1634887Schin 			case 'n':
1644887Schin 			case 'N':
1654887Schin 				n = 0;
1664887Schin 				a[5] = 0;
1674887Schin 				continue;
1684887Schin 			case 'i':
1694887Schin 			case 'I':
1704887Schin 				n = 0;
1714887Schin 				a[5] = 1;
1724887Schin 				continue;
1734887Schin 			case ' ':
1744887Schin 			case '\t':
1754887Schin 			case ',':
1764887Schin 			case '-':
1774887Schin 			case '+':
1784887Schin 				continue;
1794887Schin 			case '0': case '1': case '2': case '3': case '4':
1804887Schin 			case '5': case '6': case '7': case '8': case '9':
1818462SApril.Chin@Sun.COM 				v = 0;
1824887Schin 				a[n++] = strtol(s, &t, 0);
1834887Schin 				s = (const char*)t - 1;
1844887Schin 				continue;
1854887Schin 			}
1864887Schin 			break;
1874887Schin 		}
1884887Schin 		if (e)
1894887Schin 			*e = (char*)s;
1908462SApril.Chin@Sun.COM 		if (a[3] > (a[1] - a[2]))
1918462SApril.Chin@Sun.COM 			a[3] = a[1] - a[2];
1924887Schin 		return REC_V_RECORD(REC_V_TYPE(a[1], a[2], a[3], a[4], a[5]), a[0]);
1934887Schin 	case '%':
1944887Schin 		if (e)
1954887Schin 			*e = (char*)s + 1;
1964887Schin 		return REC_M_TYPE(REC_M_path);
1974887Schin 	case '-':
1984887Schin 	case '?':
1994887Schin 		if (e)
2004887Schin 			*e = (char*)s + 1;
2014887Schin 		return REC_M_TYPE(REC_M_data);
2024887Schin 	}
2034887Schin 	if (e)
2044887Schin 		*e = (char*)s;
2054887Schin 	return REC_N_TYPE();
2064887Schin }
207