2 /* Copyright Gerhard Rieger and contributors (see file CHANGES) */
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. */
17 /* test structure to find maximal alignment */
23 /* test structure to find minimal alignment */
29 /* test union to find kind of byte ordering */
33 } byteorder
= { "01" };
35 struct dalan_opts_s dalan_opts
= {
44 /* fill the dalan_opts structure with machine dependent defaults values. */
45 static void _dalan_dflts(struct dalan_opts_s
*dlo
) {
46 dlo
->c_int
= sizeof(int);
47 dlo
->c_short
= sizeof(short);
48 dlo
->c_long
= sizeof(long);
49 dlo
->c_char
= sizeof(char);
50 dlo
->c_float
= sizeof(float);
51 dlo
->c_double
= sizeof(double);
52 dlo
->maxalign
= (char *)&maxalign
.b
-&maxalign
.a
;
53 dlo
->minalign
= &minalign
.b
-&minalign
.a
;
54 dlo
->byteorder
= (byteorder
.b
!=7711);
57 /* allocate a new dalan_opts structure, fills it with machine dependent
58 defaults values, and returns the pointer. */
59 struct dalan_opts_s
*dalan_props(void) {
60 struct dalan_opts_s
*dlo
;
61 dlo
= malloc(sizeof(struct dalan_opts_s
));
69 void dalan_init(void) {
70 _dalan_dflts(&dalan_opts
);
73 /* read data description from line, write result to data; do not write
74 so much data that *p exceeds n !
75 p must be initialized to 0.
77 -1 if the data was cut due to n limit,
78 1 if a syntax error occurred
79 *p is a global data counter; especially it must be used when calculating
80 alignment. On successful return from the function *p must be actual!
82 int dalan(const char *line
, char *data
, size_t *p
, size_t n
) {
83 int align
, mask
, i
, x
;
87 /*fputs(line, stderr); fputc('\n', stderr);*/
97 while (*line
== ',') {
101 mask
= align
- 1; /* create the bitmask */
102 i
= (align
- (p1
& mask
)) & mask
;
103 while (i
&& p1
<n
) data
[p1
++] = 0, --i
;
104 if (i
) { *p
= p1
; return -1; }
107 align
= dalan_opts
.c_int
;
109 i
= (align
- (p1
& mask
)) & mask
;
110 while (i
&& p1
<n
) data
[p1
++] = 0, --i
;
111 if (i
) { *p
= p1
; return -1; }
115 switch (c
= *line
++) {
116 case '\0': fputs("unterminated string\n", stderr
);
121 if (!(c
= *line
++)) {
122 fputs("continuation line not implemented\n", stderr
);
126 case 'n': c
= '\n'; break;
127 case 'r': c
= '\r'; break;
128 case 't': c
= '\t'; break;
129 case 'f': c
= '\f'; break;
130 case 'b': c
= '\b'; break;
131 case 'a': c
= '\a'; break;
133 case 'e': c
= '\e'; break;
135 case 'e': c
= '\033'; break;
137 case '0': c
= '\0'; break;
141 if (p1
>= n
) { *p
= p1
; return -1; }
150 switch (c
= *line
++) {
151 case '\0': fputs("unterminated character\n", stderr
);
153 case '\'': fputs("error in character\n", stderr
);
156 if (!(c
= *line
++)) {
157 fputs("continuation line not implemented\n", stderr
);
161 case 'n': c
= '\n'; break;
162 case 'r': c
= '\r'; break;
163 case 't': c
= '\t'; break;
164 case 'f': c
= '\f'; break;
165 case 'b': c
= '\b'; break;
166 case 'a': c
= '\a'; break;
168 case 'e': c
= '\e'; break;
170 case 'e': c
= '\033'; break;
175 if (p1
>= n
) { *p
= p1
; return -1; }
180 fputs("error in character termination\n", stderr
);
190 } else if (isdigit(c
&0xff)) {
198 /* expecting hex data, must be an even number of digits!! */
201 if (isdigit(c
&0xff)) {
203 } else if (isxdigit(c
&0xff)) {
204 x
= ((c
&0x07) + 9) << 4;
209 if (isdigit(c
&0xff)) {
211 } else if (isxdigit(c
&0xff)) {
214 fputs("odd number of hexadecimal digits\n", stderr
);
218 if (p1
>= n
) { *p
= p1
; return -1; }
224 default: fprintf(stderr
, "syntax error in \"%s\"\n", line
-1);