Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/libdss/cxattr.c
1808 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 2002-2011 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* Glenn Fowler <[email protected]> *
18
* *
19
***********************************************************************/
20
#pragma prototyped
21
/*
22
* C expression library
23
*
24
* common Cxformat_t type attribute parse
25
*
26
* Glenn Fowler
27
* AT&T Research
28
*/
29
30
#include "cxlib.h"
31
32
#include <ccode.h>
33
34
typedef struct Attribute_s
35
{
36
const char* name;
37
size_t size;
38
short flags;
39
short width;
40
short base;
41
short code;
42
} Attribute_t;
43
44
#define S(s) s,(sizeof(s)-1)
45
46
static Attribute_t attributes[] =
47
{
48
S("unsigned"), CX_UNSIGNED|CX_INTEGER, 0, 0, -1,
49
S("decimal"), CX_INTEGER, 0, 10, -1,
50
S("integer"), CX_INTEGER, 0, 10, -1,
51
S("octal"), CX_UNSIGNED|CX_INTEGER, 0, 8, -1,
52
S("hex"), CX_UNSIGNED|CX_INTEGER, 0, 16, -1,
53
S("nul"), CX_NUL, 0, 0, -1,
54
S("float"), CX_FLOAT, 0, 0, -1,
55
S("double"), CX_FLOAT, 0, 0, -1,
56
S("long"), CX_LONG|CX_INTEGER, 0, 0, -1,
57
S("char"), CX_INTEGER, 1, 0, -1,
58
S("ascii"), 0, 0, 0, CC_ASCII,
59
S("ebcdic"), 0, 0, 0, CC_EBCDIC,
60
S("ebcdic_e"), 0, 0, 0, CC_EBCDIC_E,
61
S("ebcdic_i"), 0, 0, 0, CC_EBCDIC_I,
62
S("ebcdic_o"), 0, 0, 0, CC_EBCDIC_O,
63
S("native"), 0, 0, 0, CC_NATIVE,
64
};
65
66
/*
67
* parse attributes from s into f and return the type
68
* p!=0 set to the first char after the type or to the
69
* first unrecognized attribute if type==0
70
*/
71
72
Cxtype_t*
73
cxattr(Cx_t* cx, register const char* s, char** p, Cxformat_t* f, Cxdisc_t* disc)
74
{
75
register Attribute_t* a;
76
register const char* t;
77
char* e;
78
const char* b;
79
Cxtype_t* type;
80
int n;
81
char buf[32];
82
83
b = s;
84
for (;;)
85
{
86
while (*s == ':' || isspace(*s))
87
s++;
88
if (!*s)
89
break;
90
if (!strncasecmp(s, "base=", 5))
91
{
92
f->base = (int)strtol(s + 5, &e, 10);
93
s = (const char*)e;
94
}
95
else if (!strncasecmp(s, "code=", 5))
96
{
97
t = s + 5;
98
switch (*t++)
99
{
100
case 'a':
101
case 'A':
102
n = CC_ASCII;
103
break;
104
case 'e':
105
case 'E':
106
n = CC_EBCDIC_E;
107
break;
108
case 'i':
109
case 'I':
110
n = CC_EBCDIC_I;
111
break;
112
case 'o':
113
case 'O':
114
n = CC_EBCDIC_O;
115
break;
116
case 'n':
117
case 'N':
118
n = CC_NATIVE;
119
break;
120
default:
121
if (p)
122
*p = (char*)s;
123
return 0;
124
}
125
if (*t == '2')
126
t++;
127
switch (*t++)
128
{
129
case 'a':
130
case 'A':
131
n = CCOP(n, CC_ASCII);
132
break;
133
case 'e':
134
case 'E':
135
n = CCOP(n, CC_EBCDIC_E);
136
break;
137
case 'i':
138
case 'I':
139
n = CCOP(n, CC_EBCDIC_I);
140
break;
141
case 'o':
142
case 'O':
143
n = CCOP(n, CC_EBCDIC_O);
144
break;
145
case 'n':
146
case 'N':
147
n = CCOP(n, CC_NATIVE);
148
break;
149
case ':':
150
break;
151
default:
152
if (p)
153
*p = (char*)s;
154
return 0;
155
}
156
s = t;
157
}
158
else if (!strncasecmp(s, "width=", 6))
159
{
160
f->width = (int)strtol(s + 6, &e, 10);
161
s = (const char*)e;
162
}
163
else
164
{
165
for (t = s; *t && *t != ':' && !isspace(*t); t++);
166
for (a = attributes;; a++)
167
{
168
if (a >= &attributes[elementsof(attributes)])
169
goto last;
170
if ((t - s) == a->size && !strncasecmp(s, a->name, t - s))
171
{
172
if (a->flags)
173
f->flags |= a->flags;
174
if (a->width)
175
f->width = a->width;
176
if (a->base)
177
f->base = a->base;
178
if (a->code >= 0)
179
f->code = a->code;
180
break;
181
}
182
}
183
s = t;
184
}
185
}
186
last:
187
if (!cx || !isalpha(*s))
188
{
189
type = (!cx || (s == b)) ? (Cxtype_t*)0 : cxtype(cx, "number", disc);
190
if (p)
191
*p = (char*)s;
192
}
193
else
194
{
195
if (*t)
196
{
197
if ((t - s) >= sizeof(buf))
198
{
199
if (p)
200
*p = (char*)s;
201
return 0;
202
}
203
memcpy(buf, s, t - s);
204
buf[t - s] = 0;
205
e = buf;
206
}
207
else
208
e = (char*)s;
209
if (type = cxtype(cx, e, disc))
210
s = t;
211
else if (s != b)
212
type = cxtype(cx, "number", disc);
213
if (p)
214
*p = (char*)s;
215
}
216
if (type && (f->flags & CX_FLOAT))
217
f->base = 0;
218
return type;
219
}
220
221