1/*********************************************************************** 2* * 3* This software is part of the ast package * 4* Copyright (c) 1985-2011 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