1N/A/***********************************************************************
1N/A* *
1N/A* This software is part of the ast package *
1N/A* Copyright (c) 1985-2011 AT&T Intellectual Property *
1N/A* and is licensed under the *
1N/A* Common Public License, Version 1.0 *
1N/A* by AT&T Intellectual Property *
1N/A* *
1N/A* A copy of the License is available at *
1N/A* http://www.opensource.org/licenses/cpl1.0.txt *
1N/A* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
1N/A* *
1N/A* Information and Software Systems Research *
1N/A* AT&T Research *
1N/A* Florham Park NJ *
1N/A* *
1N/A* Glenn Fowler <gsf@research.att.com> *
1N/A* David Korn <dgk@research.att.com> *
1N/A* Phong Vo <kpv@research.att.com> *
1N/A* *
1N/A***********************************************************************/
1N/A#pragma prototyped
1N/A
1N/A/*
1N/A * return the record format descriptor given a format string
1N/A * e!=0 set to the first unrecognized char after the format
1N/A * REC_N_TYPE() returned on error
1N/A *
1N/A * d[0xNN|delimiter] (delimited, newline default)
1N/A * [f][+]size (fixed length)
1N/A * v hN oN zN b|l i|n (variable length with size header)
1N/A * h header size in bytes (ibm V 4)
1N/A * o size offset in bytes (ibm V 0)
1N/A * z size length in bytes (ibm V 2)
1N/A * l|b little-endian or big-endian size (ibm V b (0))
1N/A * i|n header included/not-included in size (ibm V i (1))
1N/A */
1N/A
1N/A#include <recfmt.h>
1N/A#include <ctype.h>
1N/A
1N/ARecfmt_t
1N/Arecstr(register const char* s, char** e)
1N/A{
1N/A char* t;
1N/A int n;
1N/A long v;
1N/A int a[6];
1N/A
1N/A while (*s == ' ' || *s == '\t' || *s == ',')
1N/A s++;
1N/A switch (*s)
1N/A {
1N/A case 'd':
1N/A case 'D':
1N/A if (!*++s)
1N/A n = '\n';
1N/A else
1N/A {
1N/A if (*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X'))
1N/A n = (int)strtol(s, &t, 0);
1N/A else
1N/A n = chresc(s, &t);
1N/A s = (const char*)t;
1N/A }
1N/A if (e)
1N/A *e = (char*)s;
1N/A return REC_D_TYPE(n);
1N/A case 'f':
1N/A case 'F':
1N/A while (*++s == ' ' || *s == '\t' || *s == ',');
1N/A /*FALLTHROUGH*/
1N/A case '+':
1N/A case '0': case '1': case '2': case '3': case '4':
1N/A case '5': case '6': case '7': case '8': case '9':
1N/A n = strton(s, &t, NiL, 0);
1N/A if (n > 0 && t > (char*)s)
1N/A {
1N/A if (e)
1N/A *e = t;
1N/A return REC_F_TYPE(n);
1N/A }
1N/A break;
1N/A case 'm':
1N/A case 'M':
1N/A while (*++s == ' ' || *s == '\t' || *s == ',');
1N/A for (t = (char*)s; *t && *t != ' ' && *t != '\t' && *t != ','; t++);
1N/A if ((t - s) == 4)
1N/A {
1N/A if (strneq(s, "data", 4))
1N/A {
1N/A if (e)
1N/A *e = t;
1N/A return REC_M_TYPE(REC_M_data);
1N/A }
1N/A else if (strneq(s, "path", 4))
1N/A {
1N/A if (e)
1N/A *e = t;
1N/A return REC_M_TYPE(REC_M_path);
1N/A }
1N/A }
1N/A
1N/A /*
1N/A * TBD: look up name in method libraries
1N/A * and assign an integer index
1N/A */
1N/A
1N/A break;
1N/A case 'u':
1N/A case 'U':
1N/A while (*++s == ' ' || *s == '\t' || *s == ',');
1N/A n = strtol(s, &t, 0);
1N/A if (n < 0 || n > 15 || *t++ != '.')
1N/A break;
1N/A v = strtol(t, &t, 0);
1N/A if (*t)
1N/A break;
1N/A if (e)
1N/A *e = t;
1N/A return REC_U_TYPE(n, v);
1N/A case 'v':
1N/A case 'V':
1N/A a[0] = 0;
1N/A a[1] = 4;
1N/A a[2] = 0;
1N/A a[3] = 2;
1N/A a[4] = 0;
1N/A a[5] = 1;
1N/A n = 0;
1N/A for (;;)
1N/A {
1N/A switch (*++s)
1N/A {
1N/A case 0:
1N/A break;
1N/A case 'm':
1N/A case 'M':
1N/A n = 0;
1N/A continue;
1N/A case 'h':
1N/A case 'H':
1N/A n = 1;
1N/A continue;
1N/A case 'o':
1N/A case 'O':
1N/A n = 2;
1N/A continue;
1N/A case 'z':
1N/A case 'Z':
1N/A n = 3;
1N/A continue;
1N/A case 'b':
1N/A case 'B':
1N/A n = 4;
1N/A a[n++] = 0;
1N/A continue;
1N/A case 'l':
1N/A case 'L':
1N/A n = 4;
1N/A a[n++] = 1;
1N/A continue;
1N/A case 'n':
1N/A case 'N':
1N/A n = 0;
1N/A a[5] = 0;
1N/A continue;
1N/A case 'i':
1N/A case 'I':
1N/A n = 0;
1N/A a[5] = 1;
1N/A continue;
1N/A case ' ':
1N/A case '\t':
1N/A case ',':
1N/A case '-':
1N/A case '+':
1N/A continue;
1N/A case '0': case '1': case '2': case '3': case '4':
1N/A case '5': case '6': case '7': case '8': case '9':
1N/A v = 0;
1N/A a[n++] = strtol(s, &t, 0);
1N/A s = (const char*)t - 1;
1N/A continue;
1N/A }
1N/A break;
1N/A }
1N/A if (e)
1N/A *e = (char*)s;
1N/A if (a[3] > (a[1] - a[2]))
1N/A a[3] = a[1] - a[2];
1N/A return REC_V_RECORD(REC_V_TYPE(a[1], a[2], a[3], a[4], a[5]), a[0]);
1N/A case '%':
1N/A if (e)
1N/A *e = (char*)s + 1;
1N/A return REC_M_TYPE(REC_M_path);
1N/A case '-':
1N/A case '?':
1N/A if (e)
1N/A *e = (char*)s + 1;
1N/A return REC_M_TYPE(REC_M_data);
1N/A }
1N/A if (e)
1N/A *e = (char*)s;
1N/A return REC_N_TYPE();
1N/A}