#pragma prototyped
#include <recfmt.h>
#include <ctype.h>
Recfmt_t
recstr(register const char* s, char** e)
{
char* t;
int n;
long v;
int a[6];
while (*s == ' ' || *s == '\t' || *s == ',')
s++;
switch (*s)
{
case 'd':
case 'D':
if (!*s)
n = '\n';
else
{
if (*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X'))
n = (int)strtol(s, &t, 0);
else
n = chresc(s, &t);
s = (const char*)t;
}
if (e)
*e = (char*)s;
return REC_D_TYPE(n);
case 'f':
case 'F':
while (*++s == ' ' || *s == '\t' || *s == ',');
case '+':
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
n = strton(s, &t, NiL, 0);
if (n > 0 && t > (char*)s)
{
if (e)
*e = t;
return REC_F_TYPE(n);
}
break;
case 'm':
case 'M':
while (*++s == ' ' || *s == '\t' || *s == ',');
for (t = (char*)s; *t && *t != ' ' && *t != '\t' && *t != ','; t++);
if ((t - s) == 4)
{
if (strneq(s, "data", 4))
{
if (e)
*e = t;
return REC_M_TYPE(REC_M_data);
}
else if (strneq(s, "path", 4))
{
if (e)
*e = t;
return REC_M_TYPE(REC_M_path);
}
}
break;
case 'u':
case 'U':
while (*++s == ' ' || *s == '\t' || *s == ',');
n = strtol(s, &t, 0);
if (n < 0 || n > 15 || *t++ != '.')
break;
v = strtol(t, &t, 0);
if (*t)
break;
if (e)
*e = t;
return REC_U_TYPE(n, v);
case 'v':
case 'V':
a[0] = 0;
a[1] = 4;
a[2] = 0;
a[3] = 2;
a[4] = 0;
a[5] = 1;
n = 0;
for (;;)
{
switch (*++s)
{
case 0:
break;
case 'm':
case 'M':
n = 0;
continue;
case 'h':
case 'H':
n = 1;
continue;
case 'o':
case 'O':
n = 2;
continue;
case 'z':
case 'Z':
n = 3;
continue;
case 'b':
case 'B':
n = 4;
a[n++] = 0;
continue;
case 'l':
case 'L':
n = 4;
a[n++] = 1;
continue;
case 'n':
case 'N':
n = 0;
a[5] = 0;
continue;
case 'i':
case 'I':
n = 0;
a[5] = 1;
continue;
case ' ':
case '\t':
case ',':
case '-':
case '+':
continue;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
a[n++] = strtol(s, &t, 0);
s = (const char*)t - 1;
continue;
}
break;
}
if (e)
*e = (char*)s;
return REC_V_RECORD(REC_V_TYPE(a[1], a[2], a[3], a[4], a[5]), a[0]);
case '%':
if (e)
*e = (char*)s + 1;
return REC_M_TYPE(REC_M_path);
case '-':
case '?':
if (e)
*e = (char*)s + 1;
return REC_M_TYPE(REC_M_data);
}
if (e)
*e = (char*)s;
return REC_N_TYPE();
}