2 /* Copyright Gerhard Rieger 2001-2008 */
3 /* Published under the GNU General Public License V.2, see file COPYING */
5 /* idea of a low level data description language. currently only a most
6 primitive subset exists. */
13 /* test structure to find maximal alignment */
19 /* test structure to find minimal alignment */
25 /* test union to find kind of byte ordering */
29 } byteorder
= { "01" };
31 struct dalan_opts_s dalan_opts
= {
40 /* fill the dalan_opts structure with machine dependent defaults values. */
41 static void _dalan_dflts(struct dalan_opts_s
*dlo
) {
42 dlo
->c_int
= sizeof(int);
43 dlo
->c_short
= sizeof(short);
44 dlo
->c_long
= sizeof(long);
45 dlo
->c_char
= sizeof(char);
46 dlo
->c_float
= sizeof(float);
47 dlo
->c_double
= sizeof(double);
48 dlo
->maxalign
= (char *)&maxalign
.b
-&maxalign
.a
;
49 dlo
->minalign
= &minalign
.b
-&minalign
.a
;
50 dlo
->byteorder
= (byteorder
.b
!=7711);
53 /* allocate a new dalan_opts structure, fills it with machine dependent
54 defaults values, and returns the pointer. */
55 struct dalan_opts_s
*dalan_props(void) {
56 struct dalan_opts_s
*dlo
;
57 dlo
= malloc(sizeof(struct dalan_opts_s
));
65 void dalan_init(void) {
66 _dalan_dflts(&dalan_opts
);
69 /* read data description from line, write result to data; do not write
70 so much data that *p exceeds n !
71 p must be initialized to 0.
73 -1 if the data was cut due to n limit,
74 1 if a syntax error occurred
75 *p is a global data counter; especially it must be used when calculating
76 alignment. On successful return from the function *p must be actual!
78 int dalan(const char *line
, char *data
, size_t *p
, size_t n
) {
79 int align
, mask
, i
, x
;
83 /*fputs(line, stderr); fputc('\n', stderr);*/
93 while (*line
== ',') {
97 mask
= align
- 1; /* create the bitmask */
98 i
= (align
- (p1
& mask
)) & mask
;
99 while (i
&& p1
<n
) data
[p1
++] = 0, --i
;
100 if (i
) { *p
= p1
; return -1; }
103 align
= dalan_opts
.c_int
;
105 i
= (align
- (p1
& mask
)) & mask
;
106 while (i
&& p1
<n
) data
[p1
++] = 0, --i
;
107 if (i
) { *p
= p1
; return -1; }
111 switch (c
= *line
++) {
112 case '\0': fputs("unterminated string\n", stderr
);
117 if (!(c
= *line
++)) {
118 fputs("continuation line not implemented\n", stderr
);
122 case 'n': c
= '\n'; break;
123 case 'r': c
= '\r'; break;
124 case 't': c
= '\t'; break;
125 case 'f': c
= '\f'; break;
126 case 'b': c
= '\b'; break;
127 case 'a': c
= '\a'; break;
129 case 'e': c
= '\e'; break;
131 case 'e': c
= '\033'; break;
133 case '0': c
= '\0'; break;
137 if (p1
>= n
) { *p
= p1
; return -1; }
146 switch (c
= *line
++) {
147 case '\0': fputs("unterminated character\n", stderr
);
149 case '\'': fputs("error in character\n", stderr
);
152 if (!(c
= *line
++)) {
153 fputs("continuation line not implemented\n", stderr
);
157 case 'n': c
= '\n'; break;
158 case 'r': c
= '\r'; break;
159 case 't': c
= '\t'; break;
160 case 'f': c
= '\f'; break;
161 case 'b': c
= '\b'; break;
162 case 'a': c
= '\a'; break;
164 case 'e': c
= '\e'; break;
166 case 'e': c
= '\033'; break;
171 if (p1
>= n
) { *p
= p1
; return -1; }
176 fputs("error in character termination\n", stderr
);
186 } else if (isdigit(c
&0xff)) {
194 /* expecting hex data, must be an even number of digits!! */
197 if (isdigit(c
&0xff)) {
199 } else if (isxdigit(c
&0xff)) {
200 x
= ((c
&0x07) + 9) << 4;
205 if (isdigit(c
&0xff)) {
207 } else if (isxdigit(c
&0xff)) {
210 fputs("odd number of hexadecimal digits\n", stderr
);
214 if (p1
>= n
) { *p
= p1
; return -1; }
220 default: fprintf(stderr
, "syntax error in \"%s\"\n", line
-1);