1 /*****************************************************************************/
2 /* LibreDWG - free implementation of the DWG file format */
3 /* */
4 /* Copyright (C) 2018-2024 Free Software Foundation, Inc. */
5 /* */
6 /* This library is free software, licensed under the terms of the GNU */
7 /* General Public License as published by the Free Software Foundation, */
8 /* either version 3 of the License, or (at your option) any later version. */
9 /* You should have received a copy of the GNU General Public License */
10 /* along with this program. If not, see <http://www.gnu.org/licenses/>. */
11 /*****************************************************************************/
12
13 #ifndef SPEC_H
14 # define SPEC_H
15
16 # undef _GNU_SOURCE
17 # define _GNU_SOURCE
18 # include <string.h>
19 # include "bits.h"
20 # include "codepages.h"
21 # include "decode.h"
22
23 # define DECODER if (0)
24 # define ENCODER if (0)
25 # define PRINT if (0)
26 /* DECODER_ENCODER_OR_JSON really, or just NOT_DXF */
27 # define DECODER_OR_ENCODER if (0)
28 # define DXF_OR_PRINT if (0)
29 # define DXF_OR_FREE if (0)
30 # define DXF if (0)
31 # define JSON if (0)
32 # define FREE if (0)
33 # define IF_FREE_OR_SINCE(x) SINCE (x)
34 # define IF_FREE_OR_VERSIONS(x, y) VERSIONS (x, y)
35 # ifndef IF_ENCODE_FROM_EARLIER
36 # define IF_ENCODE_FROM_EARLIER if (0)
37 # define IF_ENCODE_FROM_EARLIER_OR_DXF if (0)
38 # define IF_ENCODE_FROM_PRE_R13 if (0)
39 # define IF_ENCODE_FROM_PRE_R2000 if (0)
40 # endif
41 # ifndef IF_ENCODE_SINCE_R13
42 # define IF_ENCODE_SINCE_R13 if (0)
43 # endif
44 # define IF_IS_ENCODER 0
45 # define IF_IS_DECODER 0
46 # define IF_IS_DXF 0
47 # define IF_IS_FREE 0
48
49 # ifndef ACTION
50 # error ACTION define missing: decode, encode, dxf, json, ...
51 # endif
52 # define _DWG_FUNC_N(ACTION, name) dwg_##ACTION##_##name
53 # define DWG_FUNC_N(ACTION, name) _DWG_FUNC_N (ACTION, name)
54 # define _DWG_PRIVATE_N(ACTION, name) dwg_##ACTION##_##name##_private
55 # define DWG_PRIVATE_N(ACTION, name) _DWG_PRIVATE_N (ACTION, name)
56
57 # define SET_PARENT(field, obj)
58 # define SET_PARENT_OBJ(field)
59 # define SET_PARENT_FIELD(field, what_parent, obj)
60
61 # ifndef ISFIRST
62 # define ISFIRST
63 # define SETFIRST
64 # define CLEARFIRST
65 # endif
66
67 // for compile-time range checks with n=3,10,1000,5000,10000,20000,100000
68 // # define LOG2_APPROX(n) (size_t)((-0.344845 * (n) * (n)) + (2.024658 * (n))
69 //- 1.674873) # define _IN_RANGE (sizeof (_obj->field) >= LOG2_APPROX
70 //(maxvalue) / 8)
71 # define _IN_RANGE(var, n) \
72 ((sizeof (var) == 1 && n <= 0xff) || (sizeof (var) == 2 && n <= 0xffff) \
73 || (sizeof (var) >= 4))
74
75 # ifndef IS_FREE
76 # define VALUEOUTOFBOUNDS(field, maxvalue) \
77 if (_IN_RANGE (_obj->field, maxvalue) && _obj->field > maxvalue) \
78 { \
79 LOG_ERROR ("Invalid %s." #field " %lu", obj ? obj->name : "", \
80 (unsigned long)_obj->field); \
81 _obj->field = 0; \
82 return DWG_ERR_VALUEOUTOFBOUNDS; \
83 }
84 # define SUB_VALUEOUTOFBOUNDS(o, field, maxvalue) \
85 if (_IN_RANGE (_obj->o.field, maxvalue) && _obj->o.field > maxvalue) \
86 { \
87 LOG_ERROR ("Invalid %s." #field " %lu", obj ? obj->name : "", \
88 (unsigned long)_obj->o.field); \
89 _obj->o.field = 0; \
90 return DWG_ERR_VALUEOUTOFBOUNDS; \
91 }
92 # else
93 # define VALUEOUTOFBOUNDS(field, maxvalue) \
94 if (_IN_RANGE (_obj->field, maxvalue) && _obj->field > maxvalue) \
95 { \
96 return DWG_ERR_VALUEOUTOFBOUNDS; \
97 }
98 # define SUB_VALUEOUTOFBOUNDS(o, field, maxvalue) \
99 if (_IN_RANGE (_obj->o.field, maxvalue) && _obj->o.field > maxvalue) \
100 { \
101 return DWG_ERR_VALUEOUTOFBOUNDS; \
102 }
103 # endif
104
105 #endif /* SPEC_H */
106
107 #ifndef VALUE_HANDLE
108 # define VALUE_HANDLE(value, nam, handle_code, dxf)
109 #endif
110 #ifndef VALUE_B
111 # define VALUE_B(value, dxf)
112 #endif
113 #ifndef VALUE_TV
114 # define VALUE_TV(value, dxf)
115 #endif
116 #ifndef VALUE_TF
117 # define VALUE_TF(value, dxf)
118 #endif
119 #ifndef VALUE_TFF
120 # define VALUE_TFF(value, dxf)
121 #endif
122 #ifndef VALUE_3BD
123 # define VALUE_3BD(value, dxf)
124 #endif
125 #ifndef VALUE_2RD
126 # define VALUE_2RD(value, dxf)
127 #endif
128 #ifndef VALUE_2BD
129 # define VALUE_2BD(value, dxf) VALUE_2RD (value, dxf)
130 #endif
131 #ifndef VALUE_3RD
132 # define VALUE_3RD(value, dxf) VALUE_3BD (value, dxf)
133 #endif
134 #ifndef VALUE_BS
135 # define VALUE_BS(value, dxf)
136 #endif
137 #ifndef VALUE_BSd
138 # define VALUE_BSd(value, dxf)
139 #endif
140 #ifndef VALUE_RSd
141 # define VALUE_RSd(value, dxf)
142 #endif
143 #ifndef VALUE_BL
144 # define VALUE_BL(value, dxf)
145 #endif
146 #ifndef VALUE_RLx
147 # define VALUE_RLx(value, dxf) VALUE_RL (value, dxf)
148 #endif
149 #ifndef KEY
150 # define KEY(nam)
151 #endif
152 #ifndef BLOCK_NAME
153 # define BLOCK_NAME(nam, dxf) FIELD_T (nam, dxf)
154 #endif
155 // sub fields
156 #ifndef FIELDG
157 # define FIELDG(nam, type, dxf) FIELD (nam, type)
158 #endif
159 #ifndef SUB_FIELD_BSd
160 # define SUB_FIELD_BSd(o, nam, dxf) FIELD_BSd (o.nam, dxf)
161 #endif
162 #ifndef SUB_FIELD_BSx
163 # define SUB_FIELD_BSx(o, nam, dxf) FIELD_BSx (o.nam, dxf)
164 #endif
165 #ifndef SUB_FIELD_RSx
166 # define SUB_FIELD_RSx(o, nam, dxf) FIELD_RSx (o.nam, dxf)
167 #endif
168 #ifndef SUB_FIELD_RLLd
169 # define SUB_FIELD_RLLd(o, nam, dxf) FIELD_RLLd (o.nam, dxf)
170 #endif
171 #ifndef SUB_FIELD_TU
172 # define SUB_FIELD_TU(o, nam, dxf) FIELD_TU (o.nam, dxf)
173 #endif
174 #ifndef SUB_FIELD_T
175 # define SUB_FIELD_T(o, nam, dxf) FIELD_T (o.nam, dxf)
176 #endif
177 #ifndef SUB_FIELD_TV
178 # define SUB_FIELD_TV(o, nam, dxf) FIELD_TV (o.nam, dxf)
179 #endif
180 #ifndef SUB_FIELD_TF
181 # define SUB_FIELD_TF(o, nam, len, dxf) FIELD_TF (o.nam, _obj->o.len, dxf)
182 #endif
183 #ifndef SUB_FIELD_BLx
184 # define SUB_FIELD_BLx(o, nam, dxf) FIELD_BLx (o.nam, dxf)
185 #endif
186 #ifndef SUB_FIELD_RC
187 # define SUB_FIELD_RC(o, nam, dxf) SUB_FIELD (o, nam, RC, dxf)
188 #endif
189 #ifndef SUB_FIELD_BL
190 # define SUB_FIELD_B(o, nam, dxf) FIELDG (o.nam, B, dxf)
191 # define SUB_FIELD_BB(o, nam, dxf) FIELDG (o.nam, BB, dxf)
192 # define SUB_FIELD_3B(o, nam, dxf) FIELDG (o.nam, 3B, dxf)
193 # define SUB_FIELD_BS(o, nam, dxf) FIELDG (o.nam, BS, dxf)
194 # define SUB_FIELD_BL(o, nam, dxf) FIELDG (o.nam, BL, dxf)
195 # define SUB_FIELD_BLd(o, nam, dxf) FIELD_BLd (o.nam, dxf)
196 # define SUB_FIELD_RS(o, nam, dxf) FIELDG (o.nam, RS, dxf)
197 # define SUB_FIELD_RL(o, nam, dxf) FIELDG (o.nam, RL, dxf)
198 # define SUB_FIELD_BLL(o, nam, dxf) FIELDG (o.nam, BLL, dxf)
199 # define SUB_FIELD_RLL(o, nam, dxf) FIELDG (o.nam, RLL, dxf)
200 # define SUB_FIELD_BD(o, nam, dxf) FIELD_BD (o.nam, dxf)
201 # define SUB_FIELD_RD(o, nam, dxf) FIELD_RD (o.nam, dxf)
202 # define SUB_FIELD_2RD(o, nam, dxf) FIELD_2RD (o.nam, dxf)
203 # define SUB_FIELD_2BD(o, nam, dxf) FIELD_2BD (o.nam, dxf)
204 # define SUB_FIELD_2BD_1(o, nam, dxf) FIELD_2BD_1 (o.nam, dxf)
205 # define SUB_FIELD_3RD(o, nam, dxf) FIELD_3RD (o.nam, dxf)
206 # define SUB_FIELD_3BD(o, nam, dxf) FIELD_3BD (o.nam, dxf)
207 # define SUB_FIELD_3BD_inl(o, nam, dxf) FIELD_3BD (o, dxf)
208 # define SUB_FIELD_3DPOINT(o, nam, dxf) FIELD_3BD (o.nam, dxf)
209 // # define SUB_FIELD_ENC(o,nam,dxf1,dxf2) FIELD_ENC(o.nam, dxf1,dxf2)
210 #endif
211
212 #ifndef SUB_HANDLE_VECTOR
213 # define SUB_HANDLE_VECTOR(o, nam, sizefield, code, dxf) \
214 if (_obj->o.sizefield && _obj->o.nam) \
215 { \
216 BITCODE_BL _size = _obj->o.sizefield; \
217 for (vcount = 0; vcount < _size; vcount++) \
218 { \
219 SUB_FIELD_HANDLE (o, nam[vcount], code, dxf); \
220 } \
221 }
222 #endif
223
224 #ifndef SUB_FIELD_VECTOR
225 # define SUB_FIELD_VECTOR(o, nam, type, sizefield, dxf) \
226 if (_obj->o.sizefield && _obj->o.nam) \
227 { \
228 BITCODE_BL _size = _obj->o.sizefield; \
229 for (vcount = 0; vcount < _size; vcount++) \
230 { \
231 SUB_FIELD (o, nam[vcount], type, dxf); \
232 } \
233 }
234 #endif
235 #ifndef SUB_FIELD_VECTOR_N
236 # define SUB_FIELD_VECTOR_N(o, nam, type, size, dxf) \
237 if (size > 0 && _obj->o.nam != NULL) \
238 { \
239 BITCODE_BL _size = (BITCODE_BL)size; \
240 for (vcount = 0; vcount < _size; vcount++) \
241 { \
242 SUB_FIELD (o, nam[vcount], type, dxf); \
243 } \
244 }
245 #endif
246 #ifndef FIELD_VECTOR_INL
247 # define FIELD_VECTOR_INL(nam, type, size, dxf) \
248 FIELD_VECTOR_N (nam, type, size, dxf)
249 #endif
250 #ifndef SUB_FIELD_VECTOR_INL
251 # define SUB_FIELD_VECTOR_INL(o, nam, type, size, dxf) \
252 SUB_FIELD_VECTOR_N (o, nam, type, size, dxf)
253 #endif
254 #ifndef SUB_FIELD_2RD_VECTOR
255 # define SUB_FIELD_2RD_VECTOR(o, name, size, dxf) \
256 if (_obj->o.size > 0) \
257 { \
258 for (vcount = 0; vcount < (BITCODE_BL)_obj->o.size; vcount++) \
259 { \
260 SUB_FIELD_2RD (o, name[vcount], dxf); \
261 } \
262 }
263 #endif
264 #ifndef SUB_FIELD_3BD_VECTOR
265 # define SUB_FIELD_3BD_VECTOR(o, name, size, dxf) \
266 if (_obj->o.size > 0) \
267 { \
268 for (vcount = 0; vcount < (BITCODE_BL)_obj->o.size; vcount++) \
269 { \
270 SUB_FIELD_3BD (o, name[vcount], dxf); \
271 } \
272 }
273 #endif
274 #ifndef FIELD_VECTOR_T1
275 # define FIELD_VECTOR_T1(nam, type, size, dxf) \
276 FIELD_VECTOR_T (nam, type, size, dxf)
277 #endif
278 #ifndef SUB_FIELD_VECTOR_TYPESIZE
279 # define SUB_FIELD_VECTOR_TYPESIZE(o, nam, size, typesize, dxf) \
280 if (_obj->o.size && _obj->o.nam) \
281 { \
282 for (vcount = 0; vcount < (BITCODE_BL)_obj->o.size; vcount++) \
283 { \
284 switch (typesize) \
285 { \
286 case 0: \
287 break; \
288 case 1: \
289 SUB_FIELD (o, nam[vcount], RC, dxf); \
290 break; \
291 case 2: \
292 SUB_FIELD (o, nam[vcount], RS, dxf); \
293 break; \
294 case 4: \
295 SUB_FIELD (o, nam[vcount], RL, dxf); \
296 break; \
297 case 8: \
298 SUB_FIELD (o, nam[vcount], RLL, dxf); \
299 break; \
300 default: \
301 LOG_ERROR ("Unknown SUB_FIELD_VECTOR_TYPE " #nam \
302 " typesize %d", \
303 typesize); \
304 break; \
305 } \
306 } \
307 }
308 #endif
309
310 #ifndef REPEAT_F
311 // not allocating versions checked
312 # define _REPEAT_F(times, size, nam, type, idx) \
313 if (_obj->times > (BITCODE_BL)size) \
314 { \
315 LOG_ERROR ("Invalid %s " FORMAT_BL " > %u", #nam, \
316 FIELD_VALUE (times), (unsigned)size); \
317 FIELD_VALUE (times) = (BITCODE_BL)size; \
318 } \
319 for (rcount##idx = 0; rcount##idx < (BITCODE_BL)_obj->times; rcount##idx++)
320 # define REPEAT_F(times, size, nam, type) \
321 _REPEAT_F (times, size, nam, type, 1)
322 #endif
323
324 // logging format overrides
325 #ifndef FIELD_RLx
326 # define FIELD_RLx(name, dxf) FIELD_RL (name, dxf)
327 #endif
328 #ifndef FIELD_RSx
329 # define FIELD_RSx(name, dxf) FIELD_RS (name, dxf)
330 #endif
331 #ifndef FIELD_RCx
332 # define FIELD_RCx(name, dxf) FIELD_RC (name, dxf)
333 #endif
334 #ifndef FIELD_BLx
335 # define FIELD_BLx(name, dxf) FIELD_BL (name, dxf)
336 #endif
337 #ifndef FIELD_TFv
338 # define FIELD_TFv(name, len, dxf) FIELD_TV (name, dxf)
339 #endif
340 #ifndef FIELD_TFFx
341 # define FIELD_TFFx(name, len, dxf) FIELD_TFF (name, len, dxf)
342 #endif
343 #ifndef FIELD_TU32
344 # define FIELD_TU32(name, dxf) FIELD_TV (name, dxf)
345 #endif
346 #ifndef FIELD_RLd
347 # define FIELD_RLd(name, dxf) FIELD_RL (name, dxf)
348 #endif
349 #ifndef FIELD_BLd
350 # define FIELD_BLd(name, dxf) FIELD_BL (name, dxf)
351 #endif
352 #ifndef FIELD_BSx
353 # define FIELD_BSx(name, dxf) FIELD_BS (name, dxf)
354 #endif
355 #ifndef FIELD_BSd
356 # define FIELD_BSd(name, dxf) FIELD_BS (name, dxf)
357 #endif
358 #ifndef FIELD_RSd
359 # define FIELD_RSd(name, dxf) FIELD_RS (name, dxf)
360 #endif
361 #ifndef FIELD_RLLd
362 # define FIELD_RLLd(name, dxf) FIELD_RLL (name, dxf)
363 #endif
364 #ifndef FIELD_RCu
365 # define FIELD_RCu(name, dxf) FIELD_RC (name, dxf)
366 #endif
367 #ifndef FIELD_RCd
368 # define FIELD_RCd(name, dxf) FIELD_RC (name, dxf)
369 #endif
370 #ifndef VALUE_BINARY
371 # define VALUE_BINARY(value, len, dxf)
372 #endif
373 #ifndef FIELD_BINARY
374 # define FIELD_BINARY(name, len, dxf) FIELD_TF (name, len, dxf)
375 #endif
376 // force truecolor
377 #ifndef FIELD_CMTC
378 # define FIELD_CMTC(name, dxf) \
379 { \
380 Dwg_Version_Type _ver = dat->version; \
381 if (dat->version < R_2004) \
382 dat->version = R_2004; \
383 FIELD_CMC (name, dxf); \
384 if (_ver != dat->version) \
385 dat->version = _ver; \
386 }
387 #endif
388 #ifndef SUB_FIELD_CMTC
389 # define SUB_FIELD_CMTC(o, name, dxf) \
390 { \
391 Dwg_Version_Type _ver = dat->version; \
392 Dwg_Version_Type _fver = dat->from_version; \
393 if (dat->version < R_2004) \
394 dat->version = R_2004; \
395 if (dat->from_version < R_2004) \
396 dat->from_version = R_2004; \
397 SUB_FIELD_CMC (o, name, dxf); \
398 if (_ver != dat->version) \
399 dat->version = _ver; \
400 if (_fver != dat->from_version) \
401 dat->from_version = _fver; \
402 }
403 #endif
404 // on DXF skip if 0
405 #ifndef FIELD_BD0
406 # define FIELD_2RD0(name, dxf) FIELD_2RD (name, dxf)
407 # define FIELD_RD0(name, dxf) FIELD_RD (name, dxf)
408 # define FIELD_RD1(name, dxf) FIELD_RD (name, dxf)
409 # define FIELD_BD0(name, dxf) FIELD_BD (name, dxf)
410 # define FIELD_BD1(name, dxf) FIELD_BD (name, dxf)
411 # define FIELD_BL0(name, dxf) FIELD_BL (name, dxf)
412 # define SUB_FIELD_BL0(o, name, dxf) SUB_FIELD_BL (o, name, dxf)
413 # define FIELD_B0(name, dxf) FIELD_B (name, dxf)
414 # define FIELD_BS0(name, dxf) FIELD_BS (name, dxf)
415 # define FIELD_BS1(name, dxf) FIELD_BS (name, dxf)
416 # define FIELD_RC0(name, dxf) FIELD_RC (name, dxf)
417 # define FIELD_RS0(name, dxf) FIELD_RS (name, dxf)
418 # define FIELD_RL0(name, dxf) FIELD_RL (name, dxf)
419 # define FIELD_BT0(name, dxf) FIELD_BT (name, dxf)
420 # define VALUE_T0(name, dxf) VALUE_T (name, dxf)
421 # define FIELD_TV0(name, dxf) FIELD_TV (name, dxf)
422 # define FIELD_T0(name, dxf) FIELD_T (name, dxf)
423 # define FIELD_CMC0(color, dxf) FIELD_CMC (color, dxf)
424 # define FIELD_HANDLE0(name, code, dxf) FIELD_HANDLE (name, code, dxf)
425 # define SUB_FIELD_HANDLE0(o, name, code, dxf) \
426 SUB_FIELD_HANDLE (o, name, code, dxf)
427 #endif
428 #ifndef VALUE_TV0
429 # define VALUE_TV0(name, dxf) VALUE_TV (name, dxf)
430 #endif
431
432 #ifndef FIELD_2RD_1
433 # define FIELD_2RD_1(nam, dxf) FIELD_2RD (nam, dxf)
434 #endif
435
436 // double to text
437 #ifndef FIELD_D2T
438 # define FIELD_D2T(name, dxf) FIELD_TV (name, dxf)
439 #endif
440 #ifndef LOG_TRACE_TF
441 # define LOG_TRACE_TF(var, len)
442 # define LOG_INSANE_TF(var, len)
443 #endif
444 #ifndef SUBCLASS
445 # define SUBCLASS(text)
446 #endif
447 #ifndef DXF_3DSOLID
448 # define DXF_3DSOLID
449 #endif
450 #ifndef JSON_3DSOLID
451 # define JSON_3DSOLID
452 #endif
453 #ifndef FIELD_2PT_TRACE
454 # define FIELD_2PT_TRACE(name, type, dxf) \
455 LOG_TRACE (#name ": (" FORMAT_BD ", " FORMAT_BD ") [" #type " %d]\n", \
456 _obj->name.x, _obj->name.y, dxf)
457 # define FIELD_3PT_TRACE(name, type, dxf) \
458 LOG_TRACE (#name ": (" FORMAT_BD ", " FORMAT_BD ", " FORMAT_BD \
459 ") [" #type " %d]\n", \
460 _obj->name.x, _obj->name.y, _obj->name.z, dxf)
461 #endif
462 #ifndef FIELD_ENC
463 # define FIELD_ENC(a, b, c) FIELD_CMC (a, b, c)
464 #endif
465 #ifndef SUB_FIELD_ENC
466 # define SUB_FIELD_ENC(a, b, c, d) SUB_FIELD_CMC (a, b, c, d)
467 #endif
468
469 #ifdef IS_ENCODER
470 # undef ENCODER
471 # undef IF_IS_ENCODER
472 # define IF_IS_ENCODER 1
473 # define ENCODER if (1)
474 # undef DECODER_OR_ENCODER
475 # define DECODER_OR_ENCODER if (1)
476 #endif
477
478 #ifdef IS_DECODER
479 # undef DECODER
480 # undef IF_IS_DECODER
481 # undef DECODER_OR_ENCODER
482 # define IF_IS_DECODER 1
483 # define DECODER if (1)
484 # define DECODER_OR_ENCODER if (1)
485 # undef SET_PARENT
486 # undef SET_PARENT_OBJ
487 # undef SET_PARENT_FIELD
488 # define SET_PARENT(field, to) _obj->field.parent = to
489 # define SET_PARENT_OBJ(field) SET_PARENT (field, _obj)
490 # define SET_PARENT_FIELD(field, what_parent, to) _obj->field.what_parent = to
491 #else
492 # define TRACE_DD
493 #endif
494
495 #if defined(IS_PRINT)
496 # undef PRINT
497 # define PRINT if (1)
498 # undef DXF_OR_PRINT
499 # define DXF_OR_PRINT if (1)
500 #endif
501
502 #if defined(IS_DXF)
503 # undef DXF
504 # define DXF if (1)
505 # undef DXF_OR_PRINT
506 # define DXF_OR_PRINT if (1)
507 # undef DXF_OR_FREE
508 # define DXF_OR_FREE if (1)
509 # undef IF_IS_DXF
510 # define IF_IS_DXF 1
511 #endif
512
513 #if defined(IS_JSON)
514 # undef JSON
515 # define JSON if (1)
516 # undef DXF_OR_PRINT
517 # define DXF_OR_PRINT if (1)
518 # undef DECODER_OR_ENCODER
519 # define DECODER_OR_ENCODER if (1)
520 #endif
521
522 #if defined(IS_FREE)
523 # undef FREE
524 # define FREE if (1)
525 # undef DXF_OR_FREE
526 # define DXF_OR_FREE if (1)
527 # undef IF_IS_FREE
528 # define IF_IS_FREE 1
529 # undef IF_FREE_OR_SINCE
530 # define IF_FREE_OR_SINCE(x) if (1)
531 # undef IF_FREE_OR_VERSIONS
532 # define IF_FREE_OR_VERSIONS(x, y) if (1)
533 #else
534 # ifndef END_REPEAT
535 # define END_REPEAT(field)
536 # endif
537 #endif
538
539 #ifndef END_REPEAT_F
540 # define END_REPEAT_F(field)
541 #endif
542
543 #ifndef R11OPTS
544 # define R11OPTS(b) (_ent->opts_r11 & (b))
545 # define R11FLAG(b) (_ent->flag_r11 & (b))
546 # define R11EXTRA(b) (_ent->extra_r11 & (b))
547 #endif
548
549 #if defined IS_JSON
550 # define HANDLE_UNKNOWN_BITS \
551 { \
552 unsigned num_bytes = obj->num_unknown_bits / 8; \
553 if (obj->num_unknown_bits & 8) \
554 num_bytes++; \
555 KEY (num_unknown_bits); \
556 VALUE_RL (obj->num_unknown_bits, 0); \
557 KEY (unknown_bits); \
558 VALUE_BINARY (obj->unknown_bits, num_bytes, 0); \
559 }
560 #elif defined IS_DECODER
561 # define HANDLE_UNKNOWN_BITS \
562 dwg_decode_unknown_bits (dat, (Dwg_Object *restrict)obj)
563 #elif defined IS_ENCODER
564 # define HANDLE_UNKNOWN_BITS \
565 if (dwg_encode_unknown_bits (dat, (Dwg_Object *restrict)obj)) \
566 { \
567 if (hdl_dat != dat && hdl_dat->chain != dat->chain) \
568 bit_chain_free (hdl_dat); \
569 return error; \
570 }
571 #elif defined IS_FREE
572 # define HANDLE_UNKNOWN_BITS VALUE_TF (obj->unknown_bits, 0)
573 #elif defined IS_PRINT
574 # define HANDLE_UNKNOWN_BITS \
575 LOG_TRACE ("unknown_bits: %u [TF]\n", (unsigned)obj->num_unknown_bits); \
576 LOG_TRACE_TF (obj->unknown_bits, obj->num_unknown_bits)
577 #else
578 # define HANDLE_UNKNOWN_BITS
579 #endif
580
581 #if defined IS_JSON
582 # define UNKNOWN_BITS_REST \
583 { \
584 unsigned num_bytes = obj->num_unknown_rest / 8; \
585 if (obj->num_unknown_rest & 8) \
586 num_bytes++; \
587 KEY (num_unknown_rest); \
588 VALUE_RL (obj->num_unknown_rest, 0); \
589 KEY (unknown_bits); \
590 VALUE_BINARY (obj->unknown_rest, num_bytes, 0); \
591 }
592 #elif defined IS_DECODER
593 # define UNKNOWN_BITS_REST \
594 dwg_decode_unknown_rest (dat, (Dwg_Object *restrict)obj)
595 #elif defined IS_ENCODER
596 # define UNKNOWN_BITS_REST \
597 dwg_encode_unknown_rest (dat, (Dwg_Object *restrict)obj)
598 #elif defined IS_FREE
599 # define UNKNOWN_BITS_REST VALUE_TF (obj->unknown_rest, 0)
600 #else
601 # define UNKNOWN_BITS_REST
602 #endif
603
604 #ifndef START_OBJECT_HANDLE_STREAM
605 # define START_OBJECT_HANDLE_STREAM \
606 START_HANDLE_STREAM; \
607 assert (obj->supertype == DWG_SUPERTYPE_OBJECT)
608 #endif
609
610 #ifndef CONTROL_HANDLE_STREAM
611 # define CONTROL_HANDLE_STREAM \
612 assert (obj->supertype == DWG_SUPERTYPE_OBJECT); \
613 PRE (R_2007) \
614 { \
615 hdl_dat->byte = dat->byte; \
616 hdl_dat->bit = dat->bit; \
617 } \
618 SINCE (R_13b1) \
619 { \
620 VALUE_HANDLE (obj->tio.object->ownerhandle, ownerhandle, 4, 0); \
621 REACTORS (4) \
622 XDICOBJHANDLE (3) \
623 }
624 #endif
625
626 #ifndef LOG_FLAG_W
627 # define LOG_FLAG_W(token, w) \
628 if (_obj->flag & FLAG_##token##_##w) \
629 LOG_TRACE (#w " (%d) ", FLAG_##token##_##w)
630 # define LOG_FLAG_TABLE_W(w) \
631 if (_obj->flag & FLAG_TABLE_##w) \
632 LOG_TRACE (#w " (%d) ", FLAG_TABLE_##w)
633 # define LOG_FLAG_TABLE_MAX(v) \
634 if (_obj->flag > v) \
635 LOG_WARN ("Unknown flag (%d)", _obj->flag)
636 # define LOG_FLAG_TABLE_COMMON \
637 if (_obj->flag) \
638 { \
639 LOG_TRACE (" "); \
640 LOG_FLAG_TABLE_W (IS_XREF_REF); \
641 LOG_FLAG_TABLE_W (IS_XREF_RESOLVED); \
642 LOG_FLAG_TABLE_W (IS_XREF_DEP); \
643 LOG_FLAG_TABLE_W (IS_REMOVED); \
644 LOG_FLAG_TABLE_MAX (255); \
645 LOG_TRACE ("\n"); \
646 }
647 # define LOG_FLAG_BLOCK_W(w) \
648 if (_obj->flag & FLAG_BLOCK_##w) \
649 LOG_TRACE (#w " (%d) ", FLAG_BLOCK_##w)
650 # define LOG_FLAG_Block \
651 if (_obj->flag) \
652 { \
653 LOG_TRACE (" "); \
654 LOG_FLAG_W (BLOCK, ANONYMOUS); \
655 LOG_FLAG_W (BLOCK, HAS_ATTRIBS); \
656 LOG_FLAG_W (BLOCK, IS_EXT_REF); \
657 LOG_FLAG_W (BLOCK, IS_XREF_OVERLAY); \
658 LOG_FLAG_TABLE_W (IS_XREF_REF); \
659 LOG_FLAG_TABLE_W (IS_XREF_RESOLVED); \
660 LOG_FLAG_TABLE_W (IS_XREF_DEP); \
661 LOG_FLAG_TABLE_W (IS_REMOVED); \
662 LOG_FLAG_TABLE_MAX (255); \
663 LOG_TRACE ("\n"); \
664 }
665 # define LOG_FLAG_Layer \
666 if (_obj->flag) \
667 { \
668 LOG_TRACE (" "); \
669 LOG_FLAG_W (LAYER, FROZEN); \
670 LOG_FLAG_W (LAYER, FROZEN_IN_NEW); \
671 LOG_FLAG_W (LAYER, LOCKED); \
672 LOG_FLAG_W (LAYER, PLOTFLAG); \
673 LOG_FLAG_TABLE_W (IS_XREF_REF); \
674 LOG_FLAG_TABLE_W (IS_XREF_RESOLVED); \
675 LOG_FLAG_TABLE_W (IS_XREF_DEP); \
676 LOG_FLAG_TABLE_W (IS_REMOVED); \
677 LOG_FLAG_TABLE_MAX (255); \
678 LOG_TRACE ("\n"); \
679 }
680 # define LOG_FLAG_TextStyle \
681 if (_obj->flag) \
682 { \
683 LOG_TRACE (" "); \
684 LOG_FLAG_W (STYLE, SHAPE); \
685 LOG_FLAG_W (STYLE, VERTICAL_TEXT); \
686 LOG_FLAG_TABLE_W (IS_XREF_REF); \
687 LOG_FLAG_TABLE_W (IS_XREF_RESOLVED); \
688 LOG_FLAG_TABLE_W (IS_XREF_DEP); \
689 LOG_FLAG_TABLE_W (IS_REMOVED); \
690 LOG_FLAG_TABLE_MAX (255); \
691 LOG_TRACE ("\n"); \
692 }
693 # define LOG_FLAG_View \
694 if (_obj->flag) \
695 { \
696 LOG_TRACE (" "); \
697 LOG_FLAG_W (VIEW, PSPACE); \
698 LOG_FLAG_TABLE_W (IS_XREF_REF); \
699 LOG_FLAG_TABLE_W (IS_XREF_RESOLVED); \
700 LOG_FLAG_TABLE_W (IS_XREF_DEP); \
701 LOG_FLAG_TABLE_W (IS_REMOVED); \
702 LOG_FLAG_TABLE_MAX (255); \
703 LOG_TRACE ("\n"); \
704 }
705 # define LOG_FLAG_VX \
706 if (_obj->flag) \
707 { \
708 LOG_TRACE (" "); \
709 LOG_FLAG_W (VX, IS_ON); \
710 LOG_FLAG_TABLE_W (IS_XREF_REF); \
711 LOG_FLAG_TABLE_W (IS_XREF_RESOLVED); \
712 LOG_FLAG_TABLE_W (IS_XREF_DEP); \
713 LOG_FLAG_TABLE_W (IS_REMOVED); \
714 LOG_FLAG_TABLE_MAX (255); \
715 LOG_TRACE ("\n"); \
716 }
717 # define LOG_FLAG_Viewport LOG_FLAG_TABLE_COMMON
718 # define LOG_FLAG_RegApp LOG_FLAG_TABLE_COMMON
719 # define LOG_FLAG_DimStyle LOG_FLAG_TABLE_COMMON
720 # define LOG_FLAG_Linetype LOG_FLAG_TABLE_COMMON
721 # define LOG_FLAG_UCS LOG_FLAG_TABLE_COMMON
722 #endif
723
724 #ifndef COMMON_TABLE_FLAGS
725 # define COMMON_TABLE_FLAGS(acdbname) \
726 assert (obj->supertype == DWG_SUPERTYPE_OBJECT); \
727 PRE (R_13b1) \
728 { \
729 if (strcmp (#acdbname, "Layer") == 0) \
730 { \
731 FIELD_CAST (flag, RC, RS, 70); \
732 } \
733 else \
734 { \
735 FIELD_CAST (flag, RC, RC, 70); \
736 } \
737 DECODER_OR_ENCODER { LOG_FLAG_##acdbname } \
738 FIELD_TFv (name, 32, 2); \
739 VERSION (R_11) \
740 FIELD_RSd (used, 0); \
741 } \
742 LATER_VERSIONS \
743 { \
744 FIELD_T (name, 2); \
745 UNTIL (R_2004) \
746 { \
747 FIELD_B (is_xref_ref, 0); /* always 1, 70 bit 6 */ \
748 FIELD_BS (is_xref_resolved, 0); /* 0 or 256 */ \
749 FIELD_B (is_xref_dep, 0); /* 70 bit 4 */ \
750 } \
751 LATER_VERSIONS \
752 { \
753 FIELD_VALUE (is_xref_ref) = 1; \
754 FIELD_BS (is_xref_resolved, 0); /* 0 or 256 */ \
755 if (FIELD_VALUE (is_xref_resolved) == 256) \
756 FIELD_VALUE (is_xref_dep) = 1; \
757 } \
758 FIELD_HANDLE (xref, 5, 0); /* NULLHDL without is_xref_dep */ \
759 FIELD_VALUE (flag) \
760 |= FIELD_VALUE (is_xref_dep) << 4 | FIELD_VALUE (is_xref_ref) << 6; \
761 } \
762 RESET_VER
763 #endif
764
765 #ifndef FIELD_VECTOR_N1
766 # define FIELD_VECTOR_N1(name, type, size, dxf) \
767 FIELD_VECTOR_N (name, type, size, dxf)
768 #endif
769
770 #ifndef REPEAT_BLOCK
771 # define REPEAT_BLOCK {
772 # define END_REPEAT_BLOCK }
773 #endif
774
775 /* REPEAT names:
776 _ adds idx
777 C does no checks
778 N does constant times (else _obj->times)
779 F does not calloc/free
780 */
781
782 // unchecked with constant times
783 #ifndef REPEAT
784 # define REPEAT_CN(times, name, type) \
785 if (_obj->name != NULL) \
786 for (rcount1 = 0; rcount1 < (BITCODE_BL)times; rcount1++)
787 // checked with constant times
788 # define REPEAT_N(times, name, type) \
789 if (dat->version >= R_2000 && (BITCODE_BL)times > 20000) \
790 { \
791 LOG_ERROR ("Invalid %s." #name " rcount1 %ld", SAFEDXFNAME, \
792 (long)times); \
793 return DWG_ERR_VALUEOUTOFBOUNDS; \
794 } \
795 if (_obj->name != NULL) \
796 for (rcount1 = 0; rcount1 < (BITCODE_BL)times; rcount1++)
797
798 // checked with var. times
799 # define _REPEAT(times, name, type, idx) \
800 if (dat->version >= R_2000 && (BITCODE_BL)_obj->times > 20000) \
801 { \
802 LOG_ERROR ("Invalid %s." #name " rcount" #idx " %ld", SAFEDXFNAME, \
803 (long)_obj->times); \
804 return DWG_ERR_VALUEOUTOFBOUNDS; \
805 } \
806 if (_obj->times > 0 && _obj->name != NULL) \
807 for (rcount##idx = 0; rcount##idx < (BITCODE_BL)_obj->times; \
808 rcount##idx++)
809 // unchecked with var. times
810 # ifndef _REPEAT_C
811 # define _REPEAT_C(times, name, type, idx) \
812 if (_obj->times > 0 && _obj->name != NULL) \
813 for (rcount##idx = 0; rcount##idx < (BITCODE_BL)_obj->times; \
814 rcount##idx++)
815 # endif
816 # define REPEAT(times, name, type) _REPEAT (times, name, type, 1)
817 # define REPEAT2(times, name, type) _REPEAT (times, name, type, 2)
818 # define REPEAT3(times, name, type) _REPEAT (times, name, type, 3)
819 # define REPEAT4(times, name, type) _REPEAT (times, name, type, 4)
820 # define REPEAT_C(times, name, type) _REPEAT_C (times, name, type, 1)
821 # define REPEAT2_C(times, name, type) _REPEAT_C (times, name, type, 2)
822 # define REPEAT3_C(times, name, type) _REPEAT_C (times, name, type, 3)
823 # define REPEAT4_C(times, name, type) _REPEAT_C (times, name, type, 4)
824 #endif
825 // unchecked with constant times
826 #ifndef _REPEAT_CN
827 # define _REPEAT_CN(times, name, type, idx) \
828 if (_obj->name != NULL) \
829 for (rcount##idx = 0; rcount##idx < (BITCODE_BL)times; rcount##idx++)
830 #endif
831 // not allocating versions:
832 // unchecked
833 #ifndef _REPEAT_CNF
834 # define _REPEAT_CNF(times, name, type, idx) \
835 if (_obj->name != NULL) \
836 for (rcount##idx = 0; rcount##idx < (BITCODE_BL)times; rcount##idx++)
837 #endif
838 #ifndef _REPEAT_NF
839 // checked
840 # define _REPEAT_NF(times, name, type, idx) \
841 if (dat->version >= R_2000 && times > 0x7ff) \
842 { \
843 LOG_ERROR ("Invalid %s." #name " rcount" #idx " %ld", SAFEDXFNAME, \
844 (long)times); \
845 return DWG_ERR_VALUEOUTOFBOUNDS; \
846 } \
847 if (_obj->name != NULL) \
848 for (rcount##idx = 0; rcount##idx < (BITCODE_BL)times; rcount##idx++)
849 #endif
850
851 #define DWG_SUBCLASS_DECL(parenttype, subtype) \
852 static int DWG_PRIVATE_N (ACTION, parenttype##_##subtype) ( \
853 Dwg_Object_##parenttype *restrict _obj, Bit_Chain * dat, \
854 Bit_Chain * hdl_dat, Bit_Chain * str_dat, Dwg_Object *restrict obj)
855
856 #define DWG_SUBCLASS(parenttype, subtype) \
857 static int DWG_PRIVATE_N (ACTION, parenttype##_##subtype) ( \
858 Dwg_Object_##parenttype *restrict _obj, Bit_Chain * dat, \
859 Bit_Chain * hdl_dat, Bit_Chain * str_dat, Dwg_Object *restrict obj) \
860 { \
861 BITCODE_BL vcount, rcount3, rcount4; \
862 Dwg_Data *dwg = obj->parent; \
863 int error = 0; \
864 subtype##_fields; \
865 return error; \
866 }
867
868 #define CALL_SUBCLASS(_xobj, parenttype, subtype) \
869 error |= DWG_PRIVATE_N (ACTION, parenttype##_##subtype) ( \
870 _xobj, dat, hdl_dat, str_dat, (Dwg_Object *)obj)
871 // if the name is compile-time known
872 #define CALL_ENTITY(name, xobj) \
873 error |= DWG_PRIVATE_N (ACTION, name) (dat, hdl_dat, str_dat, \
874 (Dwg_Object *)xobj)
875 // TODO: dispatch on the type
876 #define CALL_SUBENT(hdl, dxf)
877 // error |= DWG_PRIVATE_N (ACTION, xobj->fixedtype) (dat, hdl_dat, str_dat,
878 // (Dwg_Object *)xobj)
879 #define CALL_SUBCURVE(hdl, curvetype)
880
881 #ifndef UNKNOWN_UNTIL
882 # define UNKNOWN_UNTIL(pos) \
883 LOG_TRACE ("unknown (%ld): ", pos - dat->byte); \
884 dat->byte = pos
885 #endif
886
887 #define LOG_FLAG_MAX(value, w) \
888 if (value > w) \
889 LOG_WARN ("Unknown flag (0x%x)", value & ~(w))
890
891 #ifndef LOG_TEXT_GENERATION
892 # define LOG_TEXT_GENERATION_W(w) \
893 if (_obj->generation & TEXT_GENERATION_##w) \
894 LOG_TRACE (#w "(0x%x) ", TEXT_GENERATION_##w)
895 # define LOG_TEXT_GENERATION \
896 DECODER_OR_ENCODER \
897 { \
898 if (_obj->generation) \
899 { \
900 LOG_TRACE (" "); \
901 LOG_TEXT_GENERATION_W (BACKWARDS); \
902 LOG_TEXT_GENERATION_W (UPSIDE_DOWN); \
903 LOG_FLAG_MAX (_obj->generation, 7); \
904 LOG_TRACE ("\n"); \
905 } \
906 }
907 #endif
908
909 #ifndef LOG_HORIZ_ALIGNMENT
910 # define LOG_HORIZ_ALIGNMENT_W(w) \
911 if (_obj->horiz_alignment == HORIZ_ALIGNMENT_##w) \
912 LOG_TRACE (#w "(0x%x) ", HORIZ_ALIGNMENT_##w)
913 # define LOG_HORIZ_ALIGNMENT \
914 DECODER_OR_ENCODER \
915 { \
916 if (_obj->horiz_alignment) \
917 { \
918 LOG_TRACE (" "); \
919 LOG_HORIZ_ALIGNMENT_W (LEFT); \
920 LOG_HORIZ_ALIGNMENT_W (CENTER); \
921 LOG_HORIZ_ALIGNMENT_W (RIGHT); \
922 LOG_HORIZ_ALIGNMENT_W (ALIGNED); \
923 LOG_HORIZ_ALIGNMENT_W (MIDDLE); \
924 LOG_HORIZ_ALIGNMENT_W (FIT); \
925 LOG_FLAG_MAX (_obj->horiz_alignment, HORIZ_ALIGNMENT_FIT); \
926 LOG_TRACE ("\n"); \
927 } \
928 }
929 #endif
930
931 #ifndef LOG_VERT_ALIGNMENT
932 # define LOG_VERT_ALIGNMENT_W(w) \
933 if (_obj->vert_alignment == VERT_ALIGNMENT_##w) \
934 LOG_TRACE (#w "(0x%x) ", VERT_ALIGNMENT_##w)
935 # define LOG_VERT_ALIGNMENT \
936 DECODER_OR_ENCODER \
937 { \
938 if (_obj->vert_alignment) \
939 { \
940 LOG_TRACE (" "); \
941 LOG_VERT_ALIGNMENT_W (BASELINE); \
942 LOG_VERT_ALIGNMENT_W (BOTTOM); \
943 LOG_VERT_ALIGNMENT_W (MIDDLE); \
944 LOG_VERT_ALIGNMENT_W (TOP); \
945 LOG_FLAG_MAX (_obj->vert_alignment, VERT_ALIGNMENT_TOP); \
946 LOG_TRACE ("\n"); \
947 } \
948 }
949 #endif
950
951 #ifndef LOG_FLAG_ATTDEF
952 # define LOG_FLAG_ATTDEF_W(w) \
953 if (_obj->flags & FLAG_ATTDEF_##w) \
954 LOG_TRACE (#w "(0x%x) ", FLAG_ATTDEF_##w)
955 # define LOG_FLAG_ATTDEF \
956 DECODER_OR_ENCODER \
957 { \
958 if (_obj->flags) \
959 { \
960 LOG_TRACE (" "); \
961 LOG_FLAG_ATTDEF_W (INVISIBLE); \
962 LOG_FLAG_ATTDEF_W (CONSTANT); \
963 LOG_FLAG_ATTDEF_W (VERIFY); \
964 LOG_FLAG_ATTDEF_W (PRESET); \
965 LOG_FLAG_MAX (_obj->flags, 15); \
966 LOG_TRACE ("\n"); \
967 } \
968 }
969 #endif
970
971 #ifndef LOG_FLAG_ATTRIB
972 # define LOG_FLAG_ATTRIB_W(w) \
973 if (_obj->flags & FLAG_ATTRIB_##w) \
974 LOG_TRACE (#w "(0x%x) ", FLAG_ATTRIB_##w)
975 # define LOG_FLAG_ATTRIB \
976 DECODER_OR_ENCODER \
977 { \
978 if (_obj->flags) \
979 { \
980 LOG_TRACE (" "); \
981 LOG_FLAG_ATTRIB_W (INVISIBLE); \
982 LOG_FLAG_ATTRIB_W (CONSTANT); \
983 LOG_FLAG_ATTRIB_W (VERIFY); \
984 LOG_FLAG_ATTRIB_W (PRESET); \
985 LOG_FLAG_MAX (_obj->flags, 15); \
986 LOG_TRACE ("\n"); \
987 } \
988 }
989 #endif
990
991 #ifndef LOG_FLAG_LWPOLYLINE
992 # define LOG_FLAG_LWPOLYLINE_W(w) \
993 if (_obj->flag & FLAG_LWPOLYLINE_##w) \
994 LOG_TRACE (#w "(0x%x) ", FLAG_LWPOLYLINE_##w)
995 # define LOG_FLAG_LWPOLYLINE \
996 DECODER_OR_ENCODER \
997 { \
998 if (_obj->flag) \
999 { \
1000 LOG_TRACE (" "); \
1001 LOG_FLAG_LWPOLYLINE_W (HAS_EXTRUSION); \
1002 LOG_FLAG_LWPOLYLINE_W (HAS_THICKNESS); \
1003 LOG_FLAG_LWPOLYLINE_W (HAS_CONSTWIDTH); \
1004 LOG_FLAG_LWPOLYLINE_W (HAS_ELEVATION); \
1005 LOG_FLAG_LWPOLYLINE_W (HAS_NUM_BULGES); \
1006 LOG_FLAG_LWPOLYLINE_W (HAS_NUM_WIDTHS); \
1007 LOG_FLAG_LWPOLYLINE_W (UNKNOWN_64); \
1008 LOG_FLAG_LWPOLYLINE_W (PLINEGEN); \
1009 LOG_FLAG_LWPOLYLINE_W (UNKNOWN_256); \
1010 LOG_FLAG_LWPOLYLINE_W (CLOSED); \
1011 LOG_FLAG_LWPOLYLINE_W (VERTEXIDCOUNT); \
1012 LOG_FLAG_MAX (_obj->flag, 2047); \
1013 LOG_TRACE ("\n"); \
1014 } \
1015 }
1016 #endif
1017
1018 #ifndef LOG_FLAG_POLYLINE
1019 # define LOG_FLAG_POLYLINE_W(w) \
1020 if (_obj->flag & FLAG_POLYLINE_##w) \
1021 LOG_TRACE (#w "(0x%x) ", FLAG_POLYLINE_##w)
1022 # define LOG_FLAG_POLYLINE \
1023 DECODER_OR_ENCODER \
1024 { \
1025 if (_obj->flag) \
1026 { \
1027 LOG_TRACE (" "); \
1028 LOG_FLAG_POLYLINE_W (CLOSED); \
1029 LOG_FLAG_POLYLINE_W (CURVE_FIT); \
1030 LOG_FLAG_POLYLINE_W (SPLINE_FIT); \
1031 LOG_FLAG_POLYLINE_W (3D); \
1032 LOG_FLAG_POLYLINE_W (MESH); \
1033 LOG_FLAG_POLYLINE_W (MESH_CLOSED); \
1034 LOG_FLAG_POLYLINE_W (PFACE_MESH); \
1035 LOG_FLAG_POLYLINE_W (LT_PATTERN_CONTINUES); \
1036 LOG_FLAG_MAX (_obj->flag, 255); \
1037 LOG_TRACE ("\n"); \
1038 } \
1039 }
1040 #endif
1041
1042 #ifndef LOG_FLAG_VERTEX
1043 # define LOG_FLAG_VERTEX_W(w) \
1044 if (_obj->flag & FLAG_VERTEX_##w) \
1045 LOG_TRACE (#w "(0x%x) ", FLAG_VERTEX_##w)
1046 # define LOG_FLAG_VERTEX \
1047 DECODER_OR_ENCODER \
1048 { \
1049 if (_obj->flag) \
1050 { \
1051 LOG_TRACE (" "); \
1052 LOG_FLAG_VERTEX_W (EXTRA_VERTEX); \
1053 LOG_FLAG_VERTEX_W (CURVE_FIT); \
1054 LOG_FLAG_VERTEX_W (UNUSED_4); \
1055 LOG_FLAG_VERTEX_W (SPLINE_FIT); \
1056 LOG_FLAG_VERTEX_W (SPLINE_FRAME_CONTROL_POINT); \
1057 LOG_FLAG_VERTEX_W (3D); \
1058 LOG_FLAG_VERTEX_W (MESH); \
1059 LOG_FLAG_VERTEX_W (PFACE_MESH); \
1060 LOG_FLAG_MAX (_obj->flag, 255); \
1061 LOG_TRACE ("\n"); \
1062 } \
1063 }
1064 #endif
1065
1066 #ifndef LOG_POLYLINE_CURVETYPE
1067 # define LOG_POLYLINE_CURVETYPE_W(w) \
1068 if (_obj->curve_type == POLYLINE_CURVETYPE_##w) \
1069 LOG_TRACE (#w "(0x%x) ", POLYLINE_CURVETYPE_##w)
1070 # define LOG_POLYLINE_CURVETYPE \
1071 DECODER_OR_ENCODER \
1072 { \
1073 if (_obj->curve_type) \
1074 { \
1075 LOG_TRACE (" "); \
1076 LOG_POLYLINE_CURVETYPE_W (DEFAULT); \
1077 LOG_POLYLINE_CURVETYPE_W (QUADR_BSPLINE); \
1078 LOG_POLYLINE_CURVETYPE_W (CUBIC_BSPLINE); \
1079 LOG_POLYLINE_CURVETYPE_W (BEZIER_SURFACE); \
1080 LOG_FLAG_MAX (_obj->curve_type, 8); \
1081 LOG_TRACE ("\n"); \
1082 } \
1083 }
1084 #endif
1085
1086 #ifndef LOG_LEADER_PATHTYPE
1087 # define LOG_LEADER_PATHTYPE_W(w) \
1088 if (_obj->path_type == LEADER_PATHTYPE_##w) \
1089 LOG_TRACE (#w "(0x%x) ", LEADER_PATHTYPE_##w)
1090 # define LOG_LEADER_PATHTYPE \
1091 DECODER_OR_ENCODER \
1092 { \
1093 if (_obj->path_type) \
1094 { \
1095 LOG_TRACE (" "); \
1096 LOG_LEADER_PATHTYPE_W (STRAIGHT); \
1097 LOG_LEADER_PATHTYPE_W (SPLINE); \
1098 LOG_FLAG_MAX (_obj->path_type, 3); \
1099 LOG_TRACE ("\n"); \
1100 } \
1101 }
1102 #endif
1103
1104 #ifndef LOG_LEADER_ANNOTTYPE
1105 # define LOG_LEADER_ANNOTTYPE_W(w) \
1106 if (_obj->annot_type == LEADER_ANNOTTYPE_##w) \
1107 LOG_TRACE (#w "(0x%x) ", LEADER_ANNOTTYPE_##w)
1108 # define LOG_LEADER_ANNOTTYPE \
1109 DECODER_OR_ENCODER \
1110 { \
1111 if (_obj->annot_type) \
1112 { \
1113 LOG_TRACE (" "); \
1114 LOG_LEADER_ANNOTTYPE_W (MTEXT); \
1115 LOG_LEADER_ANNOTTYPE_W (TOLERANCE); \
1116 LOG_LEADER_ANNOTTYPE_W (INSERT); \
1117 LOG_LEADER_ANNOTTYPE_W (NO_ANNOT); \
1118 LOG_FLAG_MAX (_obj->annot_type, 15); \
1119 LOG_TRACE ("\n"); \
1120 } \
1121 }
1122 #endif
1123
1124 #ifndef LOG_MLINE_FLAGS
1125 # define LOG_MLINE_FLAGS_W(w) \
1126 if (_obj->flags & MLINE_FLAGS_##w) \
1127 LOG_TRACE (#w "(0x%x) ", MLINE_FLAGS_##w)
1128 # define LOG_MLINE_FLAGS \
1129 DECODER_OR_ENCODER \
1130 { \
1131 if (_obj->flags) \
1132 { \
1133 LOG_TRACE (" "); \
1134 LOG_MLINE_FLAGS_W (HAS_VERTEX); \
1135 LOG_MLINE_FLAGS_W (CLOSED); \
1136 LOG_MLINE_FLAGS_W (SUPPRESS_START_CAPS); \
1137 LOG_MLINE_FLAGS_W (SUPPRESS_END_CAPS); \
1138 LOG_FLAG_MAX (_obj->flags, 15); \
1139 LOG_TRACE ("\n"); \
1140 } \
1141 }
1142 #endif
1143
1144 #ifndef LOG_MLINE_JUSTIFICATION
1145 # define LOG_MLINE_JUSTIFICATION_W(w) \
1146 if (_obj->justification == MLINE_JUSTIFICATION_##w) \
1147 LOG_TRACE (#w "(0x%x) ", MLINE_JUSTIFICATION_##w)
1148 # define LOG_MLINE_JUSTIFICATION \
1149 DECODER_OR_ENCODER \
1150 { \
1151 if (_obj->justification) \
1152 { \
1153 LOG_TRACE (" "); \
1154 LOG_MLINE_JUSTIFICATION_W (TOP); \
1155 LOG_MLINE_JUSTIFICATION_W (MIDDLE); \
1156 LOG_MLINE_JUSTIFICATION_W (BOTTOM); \
1157 LOG_FLAG_MAX (_obj->justification, 3); \
1158 LOG_TRACE ("\n"); \
1159 } \
1160 }
1161 #endif
1162
1163 #ifndef LOG_SPLINE_SCENARIO
1164 # define LOG_SPLINE_SCENARIO_W(w) \
1165 if (_obj->scenario == SPLINE_SCENARIO_##w) \
1166 LOG_TRACE (#w "(0x%x) ", SPLINE_SCENARIO_##w)
1167 # define LOG_SPLINE_SCENARIO \
1168 DECODER_OR_ENCODER \
1169 { \
1170 if (_obj->scenario) \
1171 { \
1172 LOG_TRACE (" "); \
1173 LOG_SPLINE_SCENARIO_W (SPLINE); \
1174 LOG_SPLINE_SCENARIO_W (BEZIER); \
1175 LOG_FLAG_MAX (_obj->scenario, 2); \
1176 LOG_TRACE ("\n"); \
1177 } \
1178 }
1179 #endif
1180 #ifndef LOG_SPLINE_SPLINEFLAGS
1181 # define LOG_SPLINE_SPLINEFLAGS_W(w) \
1182 if (_obj->splineflags & SPLINE_SPLINEFLAGS_##w) \
1183 LOG_TRACE (#w "(0x%x) ", SPLINE_SPLINEFLAGS_##w)
1184 # define LOG_SPLINE_SPLINEFLAGS \
1185 DECODER_OR_ENCODER \
1186 { \
1187 if (_obj->splineflags) \
1188 { \
1189 LOG_TRACE (" "); \
1190 LOG_SPLINE_SPLINEFLAGS_W (METHOD_FIT_POINTS); \
1191 LOG_SPLINE_SPLINEFLAGS_W (CV_FRAME_SHOW); \
1192 LOG_SPLINE_SPLINEFLAGS_W (CLOSED); \
1193 LOG_FLAG_MAX (_obj->splineflags, 7); \
1194 LOG_TRACE ("\n"); \
1195 } \
1196 }
1197 #endif
1198 #ifndef LOG_SPLINE_KNOTPARAM
1199 # define LOG_SPLINE_KNOTPARAM_W(w) \
1200 if (_obj->knotparam == SPLINE_KNOTPARAM_##w) \
1201 LOG_TRACE (#w "(0x%x) ", SPLINE_KNOTPARAM_##w)
1202 # define LOG_SPLINE_KNOTPARAM \
1203 DECODER_OR_ENCODER \
1204 { \
1205 if (_obj->knotparam) \
1206 { \
1207 LOG_TRACE (" "); \
1208 LOG_SPLINE_KNOTPARAM_W (CHORD); \
1209 LOG_SPLINE_KNOTPARAM_W (SQUARE_ROOT); \
1210 LOG_SPLINE_KNOTPARAM_W (UNIFORM); \
1211 LOG_SPLINE_KNOTPARAM_W (CUSTOM); \
1212 LOG_FLAG_MAX (_obj->knotparam, 15); \
1213 LOG_TRACE ("\n"); \
1214 } \
1215 }
1216 #endif
1217
1218 #ifndef LOG_LIGHT_TYPE
1219 # define LOG_LIGHT_TYPE_W(w) \
1220 if (_obj->type == LIGHT_TYPE_##w) \
1221 LOG_TRACE (#w "(0x%x) ", LIGHT_TYPE_##w)
1222 # define LOG_LIGHT_TYPE \
1223 DECODER_OR_ENCODER \
1224 { \
1225 if (_obj->type) \
1226 { \
1227 LOG_TRACE (" "); \
1228 LOG_LIGHT_TYPE_W (DISTANT); \
1229 LOG_LIGHT_TYPE_W (POINT); \
1230 LOG_LIGHT_TYPE_W (SPOT); \
1231 LOG_FLAG_MAX (_obj->type, 3); \
1232 LOG_TRACE ("\n"); \
1233 } \
1234 }
1235 #endif
1236
1237 #ifndef LOG_LIGHT_ATTENUATION_TYPE
1238 # define LOG_LIGHT_ATTENUATION_W(w) \
1239 if (_obj->attenuation_type == LIGHT_ATTENUATION_TYPE_##w) \
1240 LOG_TRACE (#w "(0x%x) ", LIGHT_ATTENUATION_TYPE_##w)
1241 # define LOG_LIGHT_ATTENUATION_TYPE \
1242 DECODER_OR_ENCODER \
1243 { \
1244 LOG_TRACE (" "); \
1245 LOG_LIGHT_ATTENUATION_W (NONE); \
1246 LOG_LIGHT_ATTENUATION_W (INV_LINEAR); \
1247 LOG_LIGHT_ATTENUATION_W (INV_SQUARE); \
1248 LOG_FLAG_MAX (_obj->attenuation_type, 2); \
1249 LOG_TRACE ("\n"); \
1250 }
1251 #endif
1252
1253 #ifndef LOG_LIGHT_EXTLIGHT_SHAPE
1254 # define LOG_EXTLIGHT_SHAPE_W(w) \
1255 if (_obj->extlight_shape == LIGHT_EXTLIGHT_SHAPE_##w) \
1256 LOG_TRACE (#w "(0x%x) ", LIGHT_EXTLIGHT_SHAPE_##w)
1257 # define LOG_LIGHT_EXTLIGHT_SHAPE \
1258 DECODER_OR_ENCODER \
1259 { \
1260 LOG_TRACE (" "); \
1261 LOG_EXTLIGHT_SHAPE_W (LINEAR); \
1262 LOG_EXTLIGHT_SHAPE_W (RECT); \
1263 LOG_EXTLIGHT_SHAPE_W (DISK); \
1264 LOG_EXTLIGHT_SHAPE_W (CYLINDER); \
1265 LOG_EXTLIGHT_SHAPE_W (SPHERE); \
1266 LOG_FLAG_MAX (_obj->extlight_shape, 4); \
1267 LOG_TRACE ("\n"); \
1268 }
1269 #endif
1270
1271 #ifndef LOG_3DFACE_INVISIBLE
1272 # define LOG_INVISIBLE_W(w) \
1273 if (_obj->invis_flags & _3DFACE_INVISIBLE_##w) \
1274 LOG_TRACE (#w "(0x%x) ", _3DFACE_INVISIBLE_##w)
1275 # define LOG_3DFACE_INVISIBLE \
1276 DECODER_OR_ENCODER \
1277 { \
1278 if (_obj->invis_flags) \
1279 { \
1280 LOG_TRACE (" "); \
1281 LOG_INVISIBLE_W (EDGE1); \
1282 LOG_INVISIBLE_W (EDGE2); \
1283 LOG_INVISIBLE_W (EDGE3); \
1284 LOG_INVISIBLE_W (EDGE4); \
1285 LOG_FLAG_MAX (_obj->invis_flags, 15); \
1286 LOG_TRACE ("\n"); \
1287 } \
1288 }
1289 #endif
1290
1291 #ifdef IS_DECODER
1292 # define PRER13_SECTION_HDR(name) \
1293 if (decode_preR13_section_hdr (#name, SECTION_##name, dat, dwg)) \
1294 return DWG_ERR_SECTIONNOTFOUND
1295 #elif defined IS_ENCODER
1296 # define PRER13_SECTION_HDR(name) \
1297 encode_preR13_section_hdr (#name, SECTION_##name, dat, dwg)
1298 # define DWG_TABLE(token) DWG_OBJECT (token)
1299 #else
1300 # define PRER13_SECTION_HDR(name)
1301 # define DWG_TABLE(token) DWG_OBJECT (token)
1302 #endif