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