1 /*****************************************************************************/
2 /* LibreDWG - free implementation of the DWG file format */
3 /* */
4 /* Copyright (C) 2018-2020 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 /*
14 * dwggrep.c: search a string in all text values in a DWG
15 * TODO scan the dwg.spec for all text DXF codes, per object.
16 *
17 * written by Reini Urban
18 */
19
20 #define _GNU_SOURCE
21 #include "../src/config.h"
22 #include <stdio.h>
23 #include <stdlib.h>
24 #ifdef HAVE_STRCASESTR
25 # undef __DARWIN_C_LEVEL
26 # define __DARWIN_C_LEVEL __DARWIN_C_FULL
27 # ifndef __USE_GNU
28 # define __USE_GNU
29 # endif
30 # ifndef __BSD_VISIBLE
31 # define __BSD_VISIBLE 1
32 # endif
33 # include <string.h>
34 #else
35 # include <string.h>
36 # include <ctype.h>
37 #endif
38 #include "my_getopt.h"
39 #ifdef HAVE_PCRE2_H
40 // use both, 8 and 16 (r2007+)
41 # define PCRE2_CODE_UNIT_WIDTH 0
42 # include <pcre2.h>
43 #endif
44
45 static const int verbose = 0;
46
47 #include "dwg.h"
48 #include "logging.h"
49 #include "dwg_api.h"
50 #include "common.h"
51 #include "bits.h"
52
53 #ifndef HAVE_PCRE2_H
54 # define PCRE2_MULTILINE 1
55 # define PCRE2_CASELESS 2
56 # define PCRE2_EXTENDED 3
57 # define PCRE2_NO_AUTO_CAPTURE 4
58 # define PCRE2_NO_DOTSTAR_ANCHOR 5
59 #else
60 # define PCRE2_JIT_MATCH_OPTIONS \
61 (PCRE2_NO_UTF_CHECK | PCRE2_NOTBOL | PCRE2_NOTEOL | PCRE2_NOTEMPTY \
62 | PCRE2_NOTEMPTY_ATSTART)
63 # define PCRE2_JIT_COMPILE_OPTIONS (PCRE2_JIT_COMPLETE)
64 #endif
65
66 char *pattern;
67 char buf[4096];
68 // partial to find substrings, not only complete matches
69 int options
70 = PCRE2_MULTILINE | PCRE2_NO_AUTO_CAPTURE | PCRE2_NO_DOTSTAR_ANCHOR;
71 int opt_count = 0;
72 int opt_text = 0;
73 int opt_blocks = 0;
74 int opt_tables = 0;
75 int opt_filename = 1;
76 short numdxf = 0;
77 short numtype = 0;
78 static short dxf[10]; // ensure zero-fill
79 static char *type[10]; // ensure zero-fill
80
81 /* the current version per spec block */
82 static unsigned int cur_ver = 0;
83
84 #ifdef HAVE_PCRE2_H
85 # undef USE_MATCH_CONTEXT
86 /* pcre2_compile */
87 static pcre2_code_8 *ri8;
88 static pcre2_match_data_8 *match_data8;
89 static pcre2_match_context_8 *match_context8 = NULL;
90 # ifdef HAVE_PCRE2_16
91 static pcre2_code_16 *ri16;
92 static pcre2_match_data_16 *match_data16;
93 static pcre2_match_context_16 *match_context16 = NULL;
94 # endif
95
96 # ifdef USE_MATCH_CONTEXT
97 static pcre2_jit_stack_8 *jit_stack8 = NULL;
98 static pcre2_compile_context_8 *compile_context8 = NULL;
99 # ifdef HAVE_PCRE2_16
100 static pcre2_jit_stack_16 *jit_stack16 = NULL;
101 static pcre2_compile_context_16 *compile_context16 = NULL;
102 # endif
103 # endif
104 #endif
105
106 static int
107 usage (void)
108 {
109 printf ("\nUsage: dwggrep [-cRr] pattern *.dwg\n");
110 return 1;
111 }
112 static int
113 opt_version (void)
114 {
115 printf ("dwggrep %s\n", PACKAGE_VERSION);
116 return 0;
117 }
118 static int
119 help (void)
120 {
121 printf ("\nUsage: dwggrep [OPTIONS]... pattern files\n");
122 #ifdef HAVE_PCRE2_H
123 printf ("Search regex pattern in a list of DWGs.\n\n");
124 #else
125 printf ("Search string (no regex) in a list of DWGs.\n\n");
126 #endif
127 printf (" -i Case-insensitive pattern\n");
128 #ifdef HAVE_PCRE2_H
129 printf (" -x Extended regex pattern\n");
130 #endif
131 printf (" -c, --count Print only the count of matched "
132 "elements.\n");
133 printf (" -h, --no-filename Print no filename.\n");
134 #if 0
135 printf(" -R, -r, --recursive Recursively search subdirectories listed.\n");
136 #endif
137 printf (
138 " -y, --type NAME Search only NAME entities or objects.\n");
139 printf (" -d, --dxf NUM Search only DXF group NUM fields.\n");
140 printf (" -t, --text Search only in TEXT-like entities.\n");
141 printf (
142 " -b, --blocks Search also in all block definitions.\n");
143 printf (" --tables Search only in table names.\n");
144 #ifdef HAVE_GETOPT_LONG
145 printf (" --help Display this help and exit\n");
146 printf (" --version Output version information and exit\n"
147 "\n");
148 #else
149 printf (" -u Display this help and exit\n");
150 printf (" -v Output version information and exit\n"
151 "\n");
152 #endif
153 printf ("GNU LibreDWG online manual: "
154 "<https://www.gnu.org/software/libredwg/>\n");
155 return 0;
156 }
157
158 static void
159 print_match (const int is16, const char *restrict filename,
160 const char *restrict entity, const int dxfgroup,
161 char *restrict text)
162 {
163 if (is16)
164 text = bit_convert_TU ((BITCODE_TU)text);
165 printf ("%s %s %d: %s\n", opt_filename ? filename : "", entity, dxfgroup,
166 text);
167 if (is16)
168 free (text);
169 }
170
171 static int
172 do_match (const int is16, const char *restrict filename,
173 const char *restrict entity, const int dxfgroup, char *restrict text)
174 {
175 #ifdef HAVE_PCRE2_H
176 int rc;
177 # ifdef HAVE_PCRE2_16
178 if (is16)
179 rc = pcre2_match_16 (ri16, (PCRE2_SPTR16)text, PCRE2_ZERO_TERMINATED, 0,
180 PCRE2_JIT_MATCH_OPTIONS,
181 match_data16, /* block for storing the result */
182 match_context16); /* disabled */
183 else
184 # endif
185 // already converted to UTF-8 before
186 rc = pcre2_match_8 (ri8, (PCRE2_SPTR8)text, PCRE2_ZERO_TERMINATED, 0,
187 PCRE2_JIT_MATCH_OPTIONS,
188 match_data8, /* block for storing the result */
189 match_context8); /* disabled */
190 if (rc >= 0)
191 {
192 if (!opt_count)
193 print_match (is16, filename, entity, dxfgroup, text);
194 return 1;
195 }
196 else if (rc < -2)
197 { // not PCRE2_ERROR_NOMATCH nor PCRE2_ERROR_PARTIAL
198 pcre2_get_error_message_8 (rc, (PCRE2_UCHAR8 *)buf, 4096);
199 LOG_WARN ("pcre2 match error %s with %s", buf, pattern);
200 }
201 return 0;
202
203 #else
204
205 if (options & PCRE2_CASELESS)
206 {
207 # ifndef HAVE_STRCASESTR
208 size_t i, len;
209 size_t dmax;
210 char *dest = text;
211 size_t dlen = dmax = strlen (text);
212 char *src = pattern;
213 size_t slen = strlen (pattern);
214
215 while (*dest && dmax)
216 {
217 i = 0;
218 len = slen;
219 dlen = dmax;
220 while (dest[i] && dlen)
221 {
222 if (toupper ((unsigned char)dest[i])
223 != toupper ((unsigned char)src[i]))
224 {
225 break;
226 }
227 /* move to the next char */
228 i++;
229 len--;
230 dlen--;
231
232 if (src[i] == '\0' || !len)
233 {
234 if (!opt_count)
235 print_match (0, filename, entity, dxfgroup, text);
236 return 1;
237 }
238 }
239 dest++;
240 dmax--;
241 }
242 # else
243 if (strcasestr (text, pattern))
244 {
245 if (!opt_count)
246 print_match (0, filename, entity, dxfgroup, text);
247 return 1;
248 }
249 # endif
250 }
251 else
252 {
253 if (strstr (text, pattern))
254 {
255 if (!opt_count)
256 print_match (0, filename, entity, dxfgroup, text);
257 return 1;
258 }
259 }
260 return 0;
261 #endif
262 }
263
264 // check matching dxfgroup first to avoid costly utf8 conversions
265 #define MATCH_DXF(type, ENTITY, text_field, dxfgroup) \
266 if (numdxf) \
267 { \
268 int dxfok = 0; \
269 for (int _i = 0; _i < numdxf; _i++) \
270 { \
271 if (dxf[_i] == dxfgroup) \
272 { \
273 dxfok = 1; \
274 break; \
275 } \
276 } \
277 if (dxfok) \
278 { \
279 MATCH_TYPE (type, ENTITY, text_field, dxfgroup); \
280 } \
281 } \
282 else \
283 { \
284 MATCH_TYPE (type, ENTITY, text_field, dxfgroup); \
285 }
286
287 // 8bit only
288 #define MATCH_NO16(type, ENTITY, text_field, dxfgroup) \
289 text = (char *)obj->tio.type->tio.ENTITY->text_field; \
290 if (text && numdxf) \
291 { \
292 int dxfok = 0; \
293 for (int i = 0; i < numdxf; i++) \
294 { \
295 if (dxf[i] == dxfgroup) \
296 { \
297 dxfok = 1; \
298 break; \
299 } \
300 } \
301 if (dxfok) \
302 { \
303 found += do_match (0, filename, #ENTITY, dxfgroup, text); \
304 } \
305 } \
306 else if (text) \
307 { \
308 found += do_match (0, filename, #ENTITY, dxfgroup, text); \
309 }
310
311 #ifdef HAVE_PCRE2_16
312 # define MATCH_TYPE(type, ENTITY, text_field, dxfgroup) \
313 text = (char *)obj->tio.type->tio.ENTITY->text_field; \
314 if (text) \
315 found += do_match (obj->parent->header.version >= R_2007, filename, \
316 #ENTITY, dxfgroup, text)
317 #else
318 # define MATCH_TYPE(type, ENTITY, text_field, dxfgroup) \
319 text = (char *)obj->tio.type->tio.ENTITY->text_field; \
320 if (text) \
321 { \
322 if (obj->parent->header.version >= R_2007) \
323 text = bit_convert_TU ((BITCODE_TU)text); \
324 found += do_match (obj->parent->header.version >= R_2007, filename, \
325 #ENTITY, dxfgroup, text); \
326 if (obj->parent->header.version >= R_2007) \
327 free (text); \
328 }
329 #endif
330
331 #define MATCH_ENTITY(ENTITY, text_field, dxf) \
332 MATCH_DXF (entity, ENTITY, text_field, dxf)
333 #define MATCH_OBJECT(ENTITY, text_field, dxf) \
334 MATCH_DXF (object, ENTITY, text_field, dxf)
335 #define MATCH_TABLE(ENTITY, handle, TABLE, dxf) \
336 { \
337 }
338
339 static int
340 match_TEXT (const char *restrict filename, const Dwg_Object *restrict obj)
341 {
342 char *text;
343 int found = 0;
344 MATCH_ENTITY (TEXT, text_value, 1);
345 if (!opt_text)
346 {
347 MATCH_TABLE (TEXT, style, STYLE, 7);
348 }
349 return found;
350 }
351
352 static int
353 match_ARCALIGNEDTEXT (const char *restrict filename,
354 const Dwg_Object *restrict obj)
355 {
356 char *text;
357 int found = 0;
358 MATCH_ENTITY (ARCALIGNEDTEXT, text_value, 1);
359 if (!opt_text)
360 {
361 // ignore the various sizes stored as text
362 MATCH_ENTITY (ARCALIGNEDTEXT, style, 7);
363 }
364 return found;
365 }
366
367 static int
368 match_ATTRIB (const char *restrict filename, const Dwg_Object *restrict obj)
369 {
370 char *text;
371 int found = 0;
372 // printf("--ATTRIB %lX %s\n", obj->handle.value, filename);
373 MATCH_ENTITY (ATTRIB, text_value, 1);
374 MATCH_ENTITY (ATTRIB, tag, 2);
375 if (!opt_text)
376 {
377 MATCH_TABLE (ATTRIB, style, STYLE, 7);
378 }
379 return found;
380 }
381
382 static int
383 match_ATTDEF (const char *restrict filename, const Dwg_Object *restrict obj)
384 {
385 char *text;
386 int found = 0;
387 MATCH_ENTITY (ATTDEF, default_value, 1);
388 MATCH_ENTITY (ATTDEF, tag, 2);
389 MATCH_ENTITY (ATTDEF, prompt, 3);
390 return found;
391 }
392
393 static int
394 match_MTEXT (const char *restrict filename, const Dwg_Object *restrict obj)
395 {
396 char *text;
397 int found = 0;
398 MATCH_ENTITY (MTEXT, text, 1);
399 return found;
400 }
401
402 static int
403 match_BLOCK (const char *restrict filename, const Dwg_Object *restrict obj)
404 {
405 char *text;
406 int found = 0;
407 MATCH_ENTITY (BLOCK, name, 2);
408 return found;
409 }
410
411 static int
412 match_DIMENSION (const char *restrict filename, const Dwg_Object *restrict obj)
413 {
414 char *text;
415 int found = 0;
416 // int is16 = obj->parent->header.version >= R_2007;
417
418 text = obj->tio.entity->tio.DIMENSION_ORDINATE->user_text;
419 if (text)
420 found += do_match (0, filename, "DIMENSION", 1, text);
421 return found;
422 }
423
424 static int
425 match_VIEWPORT (const char *restrict filename, const Dwg_Object *restrict obj)
426 {
427 char *text;
428 int found = 0;
429 MATCH_ENTITY (VIEWPORT, style_sheet, 1);
430 return found;
431 }
432 static int
433 match_LEADER (const char *restrict filename, const Dwg_Object *restrict obj)
434 {
435 char *text;
436 int found = 0;
437 // MATCH_ENTITY (LEADER, text, 1);
438 return found;
439 }
440 static int
441 match_MULTILEADER (const char *restrict filename,
442 const Dwg_Object *restrict obj)
443 {
444 char *text;
445 int found = 0;
446 const Dwg_Entity_MULTILEADER *_obj = obj->tio.entity->tio.MULTILEADER;
447 if (_obj->ctx.has_content_txt)
448 {
449 MATCH_ENTITY (MULTILEADER, ctx.content.txt.default_text, 304);
450 }
451 // SUB_FIELD_T (blocklabels[rcount1],label_text, 302);
452 return found;
453 }
454
455 static int
456 match_3DSOLID (const char *restrict filename, const Dwg_Object *restrict obj)
457 {
458 char *text = NULL;
459 int found = 0;
460 BITCODE_BL j;
461 Dwg_Entity_3DSOLID *_obj;
462
463 if (!obj || !obj->tio.entity)
464 return 0;
465 _obj = obj->tio.entity->tio._3DSOLID;
466 if (!_obj)
467 return 0;
468 if (_obj->acis_data)
469 {
470 MATCH_NO16 (entity, _3DSOLID, acis_data, 1);
471 // MATCH_ENTITY (_3DSOLID, acis_data, 1);
472 // found += do_match(0, filename, "3DSOLID", 1, (char*)_obj->acis_data);
473 }
474 /*
475 if (!_obj->encr_sat_data) return 0;
476 for (j=0; j<_obj->num_blocks; j++)
477 {
478 //text = _obj->encr_sat_data[j];
479 //if (text)
480 // found += do_match(0, filename, "3DSOLID", 301, text);
481 MATCH_NO16 (entity, _3DSOLID, encr_sat_data[j], 301);
482 }
483 */
484 return found;
485 }
486
487 static int
488 match_DICTIONARY (const char *restrict filename,
489 const Dwg_Object *restrict obj)
490 {
491 char *text;
492 int found = 0;
493 BITCODE_BL i;
494 Dwg_Object_DICTIONARY *_obj = obj->tio.object->tio.DICTIONARY;
495
496 for (i = 0; i < _obj->numitems; i++)
497 {
498 MATCH_OBJECT (DICTIONARY, texts[i], 3);
499 }
500 return found;
501 }
502
503 static int
504 match_STYLE (const char *restrict filename, const Dwg_Object *restrict obj)
505 {
506 char *text;
507 int found = 0;
508 MATCH_OBJECT (STYLE, name, 2);
509 if (!opt_tables)
510 {
511 MATCH_OBJECT (STYLE, font_file, 3);
512 MATCH_OBJECT (STYLE, bigfont_file, 4);
513 }
514 return found;
515 }
516
517 static int
518 match_LTYPE (const char *restrict filename, const Dwg_Object *restrict obj)
519 {
520 char *text;
521 int found = 0;
522 MATCH_OBJECT (LTYPE, name, 2);
523 MATCH_OBJECT (LTYPE, description, 3);
524 if (!opt_tables)
525 {
526 MATCH_OBJECT (LTYPE, strings_area, 3);
527 }
528 return found;
529 }
530 static int
531 match_LAYER (const char *restrict filename, const Dwg_Object *restrict obj)
532 {
533 char *text;
534 int found = 0;
535 MATCH_OBJECT (LAYER, name, 2);
536 return found;
537 }
538 static int
539 match_VIEW (const char *restrict filename, const Dwg_Object *restrict obj)
540 {
541 char *text;
542 int found = 0;
543 MATCH_OBJECT (VIEW, name, 2);
544 return found;
545 }
546 static int
547 match_VPORT (const char *restrict filename, const Dwg_Object *restrict obj)
548 {
549 char *text;
550 int found = 0;
551 MATCH_OBJECT (VPORT, name, 2);
552 return found;
553 }
554 static int
555 match_UCS (const char *restrict filename, const Dwg_Object *restrict obj)
556 {
557 char *text;
558 int found = 0;
559 MATCH_OBJECT (UCS, name, 2);
560 return found;
561 }
562 static int
563 match_VX_TABLE_RECORD (const char *restrict filename,
564 const Dwg_Object *restrict obj)
565 {
566 char *text;
567 int found = 0;
568 MATCH_OBJECT (VX_TABLE_RECORD, name, 2);
569 return found;
570 }
571
572 static int
573 match_DIMSTYLE (const char *restrict filename, const Dwg_Object *restrict obj)
574 {
575 char *text;
576 int found = 0;
577 MATCH_OBJECT (DIMSTYLE, name, 2);
578 if (!opt_tables)
579 {
580 MATCH_OBJECT (DIMSTYLE, DIMPOST, 3);
581 MATCH_OBJECT (DIMSTYLE, DIMAPOST, 4);
582 MATCH_OBJECT (DIMSTYLE, DIMBLK_T, 5);
583 MATCH_OBJECT (DIMSTYLE, DIMBLK1_T, 6);
584 MATCH_OBJECT (DIMSTYLE, DIMBLK2_T, 7);
585 MATCH_OBJECT (DIMSTYLE, DIMMZS, 0);
586 MATCH_OBJECT (DIMSTYLE, DIMALTMZS, 0);
587 }
588 return found;
589 }
590
591 static int
592 match_GROUP (const char *restrict filename, const Dwg_Object *restrict obj)
593 {
594 char *text;
595 int found = 0;
596 MATCH_OBJECT (GROUP, name, 3);
597 return found;
598 }
599
600 static int
601 match_MLINESTYLE (const char *restrict filename,
602 const Dwg_Object *restrict obj)
603 {
604 char *text;
605 int found = 0;
606 MATCH_OBJECT (MLINESTYLE, name, 2);
607 MATCH_OBJECT (MLINESTYLE, description, 3);
608 return found;
609 }
610
611 static int
612 match_DICTIONARYVAR (const char *restrict filename,
613 const Dwg_Object *restrict obj)
614 {
615 char *text;
616 int found = 0;
617 MATCH_OBJECT (DICTIONARYVAR, strvalue, 1);
618 return found;
619 }
620
621 static int
622 match_HATCH (const char *restrict filename, const Dwg_Object *restrict obj)
623 {
624 char *text;
625 int found = 0;
626 MATCH_ENTITY (HATCH, name, 2);
627 MATCH_ENTITY (HATCH, gradient_name, 470);
628 return found;
629 }
630 static int
631 match_TOLERANCE (const char *restrict filename, const Dwg_Object *restrict obj)
632 {
633 char *text;
634 int found = 0;
635 MATCH_ENTITY (TOLERANCE, text_value, 1);
636 return found;
637 }
638
639 static int
640 match_IMAGEDEF (const char *restrict filename, const Dwg_Object *restrict obj)
641 {
642 char *text;
643 int found = 0;
644 MATCH_OBJECT (IMAGEDEF, file_path, 1);
645 return found;
646 }
647
648 static int
649 match_SCALE (const char *restrict filename, const Dwg_Object *restrict obj)
650 {
651 char *text;
652 int found = 0, i;
653 // const Dwg_Object_SCALE *_obj = obj->tio.object->tio.SCALE;
654 MATCH_OBJECT (SCALE, name, 1);
655 return found;
656 }
657
658 static int
659 match_LAYER_INDEX (const char *restrict filename,
660 const Dwg_Object *restrict obj)
661 {
662 char *text;
663 int found = 0;
664 BITCODE_BL i;
665 const Dwg_Object_LAYER_INDEX *_obj = obj->tio.object->tio.LAYER_INDEX;
666 for (i = 0; i < _obj->num_entries; i++)
667 {
668 MATCH_OBJECT (LAYER_INDEX, entries[i].name, 8);
669 }
670 return found;
671 }
672
673 static int
674 match_LAYOUT (const char *restrict filename, const Dwg_Object *restrict obj)
675 {
676 char *text;
677 int found = 0;
678 BITCODE_BL i;
679 const Dwg_Object_LAYOUT *_obj = obj->tio.object->tio.LAYOUT;
680
681 MATCH_OBJECT (LAYOUT, plotsettings.printer_cfg_file, 1);
682 MATCH_OBJECT (LAYOUT, plotsettings.paper_size, 2);
683 MATCH_OBJECT (LAYOUT, plotsettings.canonical_media_name, 4);
684 MATCH_TABLE (LAYOUT, plotsettings.plotview, VIEW, 6);
685 MATCH_OBJECT (LAYOUT, plotsettings.plotview_name, 6);
686 MATCH_OBJECT (LAYOUT, plotsettings.stylesheet, 7);
687
688 MATCH_OBJECT (LAYOUT, layout_name, 1);
689 MATCH_TABLE (LAYOUT, block_header, BLOCK, 330);
690 MATCH_TABLE (LAYOUT, active_viewport, VIEWPORT, 331);
691 MATCH_TABLE (LAYOUT, shadeplot, VISUALSTYLE, 333);
692 MATCH_TABLE (LAYOUT, base_ucs, UCS, 346);
693 MATCH_TABLE (LAYOUT, named_ucs, UCS, 345);
694 for (i = 0; i < _obj->num_viewports; i++)
695 {
696 MATCH_TABLE (LAYOUT, viewports[i], VPORT, 0);
697 }
698 return found;
699 }
700
701 static int
702 match_FIELD (const char *restrict filename, const Dwg_Object *restrict obj)
703 {
704 char *text;
705 int found = 0;
706 BITCODE_BL i;
707 const Dwg_Object_FIELD *_obj = obj->tio.object->tio.FIELD;
708
709 MATCH_OBJECT (FIELD, format, 4);
710 MATCH_OBJECT (FIELD, evaluation_error_msg, 300);
711 MATCH_OBJECT (FIELD, value.format_string, 300);
712 MATCH_OBJECT (FIELD, value.value_string, 300);
713 MATCH_OBJECT (FIELD, value_string, 301);
714 for (i = 0; i < _obj->num_childval; i++)
715 {
716 MATCH_OBJECT (FIELD, childval[i].key, 6);
717 MATCH_OBJECT (FIELD, childval[i].value.format_string, 300);
718 MATCH_OBJECT (FIELD, childval[i].value.value_string, 302);
719 }
720 return found;
721 }
722
723 static int
724 match_TABLE (const char *restrict filename, const Dwg_Object *restrict obj)
725 {
726 char *text;
727 int found = 0;
728 BITCODE_BL i, j;
729 const Dwg_Entity_TABLE *_obj = obj->tio.entity->tio.TABLE;
730
731 for (i = 0; i < _obj->num_cells; i++)
732 {
733 if (_obj->cells[i].type == 1)
734 {
735 MATCH_ENTITY (TABLE, cells[i].text_value, 1);
736 }
737 else if (_obj->cells[i].type == 2
738 && _obj->cells[i].additional_data_flag == 1
739 && _obj->cells[i].num_attr_defs)
740 {
741 for (j = 0; j < _obj->cells[i].num_attr_defs; j++)
742 {
743 MATCH_ENTITY (TABLE, cells[i].attr_defs[j].text, 300);
744 }
745 }
746 }
747 return found;
748 }
749
750 static int
751 match_TABLECONTENT (const char *restrict filename,
752 const Dwg_Object *restrict obj)
753 {
754 char *text;
755 int found = 0;
756 BITCODE_BL i, j, k;
757 const Dwg_Object_TABLECONTENT *_obj = obj->tio.object->tio.TABLECONTENT;
758
759 MATCH_OBJECT (TABLECONTENT, ldata.name, 1);
760 MATCH_OBJECT (TABLECONTENT, ldata.description, 300);
761 for (i = 0; i < _obj->tdata.num_cols; i++)
762 {
763 MATCH_OBJECT (TABLECONTENT, tdata.cols[i].name, 300);
764 }
765 for (i = 0; i < _obj->tdata.num_rows; i++)
766 {
767 for (j = 0; j < _obj->tdata.rows[i].num_cells; j++)
768 {
769 MATCH_OBJECT (TABLECONTENT, tdata.rows[i].cells[j].tooltip, 300);
770 for (k = 0; k < _obj->tdata.rows[i].cells[j].num_customdata_items;
771 k++)
772 {
773 #define _custom tdata.rows[i].cells[j].customdata_items[k]
774 MATCH_OBJECT (TABLECONTENT, _custom.name, 300);
775 if (_obj->_custom.value.data_type == 4)
776 {
777 MATCH_OBJECT (TABLECONTENT, _custom.value.data_string, 302);
778 }
779 #undef _custom
780 }
781 for (k = 0; k < _obj->tdata.rows[i].cells[j].num_cell_contents; k++)
782 {
783 #define _content tdata.rows[i].cells[j].cell_contents[k]
784 if (_obj->_content.type == 1
785 && _obj->_content.value.data_type == 4)
786 {
787 MATCH_OBJECT (TABLECONTENT, _content.value.data_string, 302);
788 }
789 #undef _content
790 }
791 }
792 }
793 return found;
794 }
795
796 static int
797 match_GEODATA (const char *restrict filename, const Dwg_Object *restrict obj)
798 {
799 char *text;
800 int found = 0;
801 // const Dwg_Object_GEODATA *_obj = obj->tio.object->tio.GEODATA;
802
803 MATCH_OBJECT (GEODATA, coord_system_def, 0);
804 MATCH_OBJECT (GEODATA, geo_rss_tag, 302);
805 MATCH_OBJECT (GEODATA, observation_from_tag, 305);
806 MATCH_OBJECT (GEODATA, observation_to_tag, 306);
807 MATCH_OBJECT (GEODATA, observation_coverage_tag, 0);
808 // obsolete
809 MATCH_OBJECT (GEODATA, coord_system_datum, 0);
810 MATCH_OBJECT (GEODATA, coord_system_wkt, 0);
811 return found;
812 }
813
814 static int
815 match_GEOPOSITIONMARKER (const char *restrict filename,
816 const Dwg_Object *restrict obj)
817 {
818 char *text;
819 int found = 0;
820 // const Dwg_Entity_GEOPOSITIONMARKER *_obj =
821 // obj->tio.entity->tio.GEOPOSITIONMARKER;
822
823 MATCH_ENTITY (GEOPOSITIONMARKER, notes, 1);
824 // if enabled
825 // MATCH_ENTITY (GEOPOSITIONMARKER, mtext->tio.entity->tio.MTEXT->text, 3);
826 return found;
827 }
828
829 static int
830 match_UNDERLAYDEFINITION (const char *restrict filename,
831 const Dwg_Object *restrict obj)
832 {
833 char *text;
834 int found = 0;
835 // const Dwg_Object_PDFDEFINITION *_obj = obj->tio.object->tio.PDFDEFINITION;
836
837 MATCH_OBJECT (PDFDEFINITION, filename, 1);
838 MATCH_OBJECT (PDFDEFINITION, name, 2);
839 return found;
840 }
841
842 static int
843 match_VISUALSTYLE (const char *restrict filename,
844 const Dwg_Object *restrict obj)
845 {
846 char *text;
847 int found = 0, i;
848 // const Dwg_Object_VISUALSTYLE *_obj = obj->tio.object->tio.VISUALSTYLE;
849 MATCH_OBJECT (VISUALSTYLE, description, 1);
850 return found;
851 }
852
853 static int
854 match_TABLESTYLE (const char *restrict filename,
855 const Dwg_Object *restrict obj)
856 {
857 char *text;
858 int found = 0, i;
859 // const Dwg_Object_TABLESTYLE *_obj = obj->tio.object->tio.TABLESTYLE;
860 MATCH_OBJECT (TABLESTYLE, name, 2);
861 return found;
862 }
863 static int
864 match_LIGHT (const char *restrict filename, const Dwg_Object *restrict obj)
865 {
866 char *text;
867 int found = 0;
868 // const Dwg_Entity_LIGHT *_obj = obj->tio.entity->tio.LIGHT;
869 MATCH_ENTITY (LIGHT, name, 1);
870 // MATCH_ENTITY (LIGHT, web_file, 1);
871 return found;
872 }
873
874 static int
875 match_SUNSTUDY (const char *restrict filename, const Dwg_Object *restrict obj)
876 {
877 char *text;
878 int found = 0;
879 // const Dwg_Object_SUNSTUDY *_obj = obj->tio.object->tio.SUNSTUDY;
880 MATCH_OBJECT (SUNSTUDY, setup_name, 1);
881 MATCH_OBJECT (SUNSTUDY, description, 2);
882 MATCH_OBJECT (SUNSTUDY, sheet_set_name, 3);
883 return found;
884 }
885
886 static int
887 match_LIGHTLIST (const char *restrict filename, const Dwg_Object *restrict obj)
888 {
889 char *text;
890 int found = 0;
891 const Dwg_Object_LIGHTLIST *_obj = obj->tio.object->tio.LIGHTLIST;
892
893 for (BITCODE_BL i = 0; i < _obj->num_lights; i++)
894 {
895 MATCH_OBJECT (LIGHTLIST, lights[i].name, 1);
896 }
897 return found;
898 }
899
900 static int
901 match_DBCOLOR (const char *restrict filename, const Dwg_Object *restrict obj)
902 {
903 char *text;
904 int found = 0;
905 // const Dwg_Object_DBCOLOR *_obj = obj->tio.object->tio.DBCOLOR;
906 MATCH_OBJECT (DBCOLOR, color.name, 430);
907 MATCH_OBJECT (DBCOLOR, color.book_name, 430);
908 return found;
909 }
910
911 static int
912 match_MATERIAL (const char *restrict filename, const Dwg_Object *restrict obj)
913 {
914 char *text;
915 int found = 0;
916 // const Dwg_Object_MATERIAL *_obj = obj->tio.object->tio.MATERIAL;
917 MATCH_OBJECT (MATERIAL, name, 1);
918 MATCH_OBJECT (MATERIAL, description, 2);
919 MATCH_OBJECT (MATERIAL, diffusemap.filename, 3);
920 MATCH_OBJECT (MATERIAL, specularmap.filename, 4);
921 MATCH_OBJECT (MATERIAL, reflectionmap.filename, 6);
922 MATCH_OBJECT (MATERIAL, opacitymap.filename, 7);
923 MATCH_OBJECT (MATERIAL, bumpmap.filename, 8);
924 MATCH_OBJECT (MATERIAL, refractionmap.filename, 9);
925 // MATCH_OBJECT (MATERIAL, normalmap.filename, 3);
926 // MATCH_OBJECT (MATERIAL, genprocname, 300);
927 // MATCH_OBJECT (MATERIAL, genprocvaltext, 301);
928 // MATCH_OBJECT (MATERIAL, genprocvalcolorname, 430);
929 return found;
930 }
931
932 static int
933 match_PLOTSETTINGS (const char *restrict filename,
934 const Dwg_Object *restrict obj)
935 {
936 char *text;
937 int found = 0;
938 // const Dwg_Object_PLOTSETTINGS *_obj = obj->tio.object->tio.PLOTSETTINGS;
939 MATCH_OBJECT (PLOTSETTINGS, printer_cfg_file, 1);
940 MATCH_OBJECT (PLOTSETTINGS, paper_size, 2);
941 MATCH_OBJECT (PLOTSETTINGS, canonical_media_name, 4);
942 MATCH_OBJECT (PLOTSETTINGS, plotview_name, 6);
943 MATCH_TABLE (PLOTSETTINGS, VIEW, plotview, 6);
944 MATCH_OBJECT (PLOTSETTINGS, stylesheet, 7);
945 MATCH_TABLE (PLOTSETTINGS, VISUALSTYLE, shadeplot, 333);
946 return found;
947 }
948 static int
949 match_DIMASSOC (const char *restrict filename, const Dwg_Object *restrict obj)
950 {
951 char *text;
952 int found = 0;
953 const Dwg_Object_DIMASSOC *_obj = obj->tio.object->tio.DIMASSOC;
954 for (BITCODE_BL i = 0; i < 4; i++)
955 {
956 if (_obj->ref[i].classname)
957 {
958 MATCH_OBJECT (DIMASSOC, ref[i].classname, 0);
959 }
960 }
961 return found;
962 }
963
964 static int
965 match_ASSOCOSNAPPOINTREFACTIONPARAM (const char *restrict filename,
966 const Dwg_Object *restrict obj)
967 {
968 char *text;
969 int found = 0;
970 MATCH_OBJECT (ASSOCOSNAPPOINTREFACTIONPARAM, name, 1);
971 return found;
972 }
973 static int
974 match_ASSOCACTIONPARAM (const char *restrict filename,
975 const Dwg_Object *restrict obj)
976 {
977 char *text;
978 int found = 0;
979 MATCH_OBJECT (ASSOCACTIONPARAM, name, 1);
980 return found;
981 }
982 static int
983 match_ASSOCEDGEACTIONPARAM (const char *restrict filename,
984 const Dwg_Object *restrict obj)
985 {
986 char *text;
987 int found = 0;
988 MATCH_OBJECT (ASSOCEDGEACTIONPARAM, name, 1);
989 return found;
990 }
991 static int
992 match_ASSOCFACEACTIONPARAM (const char *restrict filename,
993 const Dwg_Object *restrict obj)
994 {
995 char *text;
996 int found = 0;
997 MATCH_OBJECT (ASSOCFACEACTIONPARAM, name, 1);
998 return found;
999 }
1000 static int
1001 match_ASSOCOBJECTACTIONPARAM (const char *restrict filename,
1002 const Dwg_Object *restrict obj)
1003 {
1004 char *text;
1005 int found = 0;
1006 MATCH_OBJECT (ASSOCOBJECTACTIONPARAM, name, 1);
1007 return found;
1008 }
1009 static int
1010 match_ASSOCPATHACTIONPARAM (const char *restrict filename,
1011 const Dwg_Object *restrict obj)
1012 {
1013 char *text;
1014 int found = 0;
1015 MATCH_OBJECT (ASSOCPATHACTIONPARAM, name, 1);
1016 return found;
1017 }
1018 static int
1019 match_ASSOCVERTEXACTIONPARAM (const char *restrict filename,
1020 const Dwg_Object *restrict obj)
1021 {
1022 char *text;
1023 int found = 0;
1024 MATCH_OBJECT (ASSOCVERTEXACTIONPARAM, name, 1);
1025 return found;
1026 }
1027
1028 // TODO match on its subclasses which holds the text:
1029 // ASSOCVARIABLE, EvalVariant
1030
1031 #define MATCH_AcDbAssocParamBasedActionBody(_type) \
1032 for (unsigned i = 0; i < _obj->pab.num_values; i++) \
1033 { \
1034 MATCH_OBJECT (_type, pab.values[i].name, 1); \
1035 for (unsigned j = 0; j < _obj->pab.values[i].num_vars; j++) \
1036 { \
1037 int _dxf = _obj->pab.values[i].vars[j].value.code; \
1038 if (dwg_resbuf_value_type (_dxf) == DWG_VT_STRING) \
1039 { \
1040 MATCH_OBJECT (_type, pab.values[i].vars[j].value.u.text, _dxf); \
1041 } \
1042 } \
1043 }
1044
1045 static int
1046 match_ASSOCMLEADERACTIONBODY (const char *restrict filename,
1047 const Dwg_Object *restrict obj)
1048 {
1049 char *text;
1050 int found = 0;
1051 const Dwg_Object_ASSOCMLEADERACTIONBODY *_obj
1052 = obj->tio.object->tio.ASSOCMLEADERACTIONBODY;
1053 MATCH_AcDbAssocParamBasedActionBody (ASSOCMLEADERACTIONBODY) return found;
1054 }
1055 static int
1056 match_ASSOC3POINTANGULARDIMACTIONBODY (const char *restrict filename,
1057 const Dwg_Object *restrict obj)
1058 {
1059 char *text;
1060 int found = 0;
1061 const Dwg_Object_ASSOC3POINTANGULARDIMACTIONBODY *_obj
1062 = obj->tio.object->tio.ASSOC3POINTANGULARDIMACTIONBODY;
1063 MATCH_AcDbAssocParamBasedActionBody (
1064 ASSOC3POINTANGULARDIMACTIONBODY) return found;
1065 }
1066 static int
1067 match_ASSOCALIGNEDDIMACTIONBODY (const char *restrict filename,
1068 const Dwg_Object *restrict obj)
1069 {
1070 char *text;
1071 int found = 0;
1072 const Dwg_Object_ASSOCALIGNEDDIMACTIONBODY *_obj
1073 = obj->tio.object->tio.ASSOCALIGNEDDIMACTIONBODY;
1074 MATCH_AcDbAssocParamBasedActionBody (ASSOCALIGNEDDIMACTIONBODY) return found;
1075 }
1076
1077 static int
1078 match_ASSOCORDINATEDIMACTIONBODY (const char *restrict filename,
1079 const Dwg_Object *restrict obj)
1080 {
1081 char *text;
1082 int found = 0;
1083 const Dwg_Object_ASSOCORDINATEDIMACTIONBODY *_obj
1084 = obj->tio.object->tio.ASSOCORDINATEDIMACTIONBODY;
1085 MATCH_AcDbAssocParamBasedActionBody (
1086 ASSOCORDINATEDIMACTIONBODY) return found;
1087 }
1088
1089 static int
1090 match_ASSOCROTATEDDIMACTIONBODY (const char *restrict filename,
1091 const Dwg_Object *restrict obj)
1092 {
1093 char *text;
1094 int found = 0;
1095 const Dwg_Object_ASSOCROTATEDDIMACTIONBODY *_obj
1096 = obj->tio.object->tio.ASSOCROTATEDDIMACTIONBODY;
1097 MATCH_AcDbAssocParamBasedActionBody (ASSOCROTATEDDIMACTIONBODY) return found;
1098 }
1099
1100 static int
1101 match_ASSOCPATCHSURFACEACTIONBODY (const char *restrict filename,
1102 const Dwg_Object *restrict obj)
1103 {
1104 char *text;
1105 int found = 0;
1106 const Dwg_Object_ASSOCPATCHSURFACEACTIONBODY *_obj
1107 = obj->tio.object->tio.ASSOCPATCHSURFACEACTIONBODY;
1108 MATCH_AcDbAssocParamBasedActionBody (
1109 ASSOCPATCHSURFACEACTIONBODY) return found;
1110 }
1111 static int
1112 match_ASSOCPLANESURFACEACTIONBODY (const char *restrict filename,
1113 const Dwg_Object *restrict obj)
1114 {
1115 char *text;
1116 int found = 0;
1117 const Dwg_Object_ASSOCPLANESURFACEACTIONBODY *_obj
1118 = obj->tio.object->tio.ASSOCPLANESURFACEACTIONBODY;
1119 MATCH_AcDbAssocParamBasedActionBody (
1120 ASSOCPLANESURFACEACTIONBODY) return found;
1121 }
1122 static int
1123 match_ASSOCEXTENDSURFACEACTIONBODY (const char *restrict filename,
1124 const Dwg_Object *restrict obj)
1125 {
1126 char *text;
1127 int found = 0;
1128 const Dwg_Object_ASSOCEXTENDSURFACEACTIONBODY *_obj
1129 = obj->tio.object->tio.ASSOCEXTENDSURFACEACTIONBODY;
1130 MATCH_AcDbAssocParamBasedActionBody (
1131 ASSOCEXTENDSURFACEACTIONBODY) return found;
1132 }
1133 static int
1134 match_ASSOCEXTRUDEDSURFACEACTIONBODY (const char *restrict filename,
1135 const Dwg_Object *restrict obj)
1136 {
1137 char *text;
1138 int found = 0;
1139 const Dwg_Object_ASSOCEXTRUDEDSURFACEACTIONBODY *_obj
1140 = obj->tio.object->tio.ASSOCEXTRUDEDSURFACEACTIONBODY;
1141 MATCH_AcDbAssocParamBasedActionBody (
1142 ASSOCEXTRUDEDSURFACEACTIONBODY) return found;
1143 }
1144 static int
1145 match_ASSOCFILLETSURFACEACTIONBODY (const char *restrict filename,
1146 const Dwg_Object *restrict obj)
1147 {
1148 char *text;
1149 int found = 0;
1150 const Dwg_Object_ASSOCFILLETSURFACEACTIONBODY *_obj
1151 = obj->tio.object->tio.ASSOCFILLETSURFACEACTIONBODY;
1152 MATCH_AcDbAssocParamBasedActionBody (
1153 ASSOCFILLETSURFACEACTIONBODY) return found;
1154 }
1155 static int
1156 match_ASSOCLOFTEDSURFACEACTIONBODY (const char *restrict filename,
1157 const Dwg_Object *restrict obj)
1158 {
1159 char *text;
1160 int found = 0;
1161 const Dwg_Object_ASSOCLOFTEDSURFACEACTIONBODY *_obj
1162 = obj->tio.object->tio.ASSOCLOFTEDSURFACEACTIONBODY;
1163 MATCH_AcDbAssocParamBasedActionBody (
1164 ASSOCLOFTEDSURFACEACTIONBODY) return found;
1165 }
1166 static int
1167 match_ASSOCNETWORKSURFACEACTIONBODY (const char *restrict filename,
1168 const Dwg_Object *restrict obj)
1169 {
1170 char *text;
1171 int found = 0;
1172 const Dwg_Object_ASSOCNETWORKSURFACEACTIONBODY *_obj
1173 = obj->tio.object->tio.ASSOCNETWORKSURFACEACTIONBODY;
1174 MATCH_AcDbAssocParamBasedActionBody (
1175 ASSOCNETWORKSURFACEACTIONBODY) return found;
1176 }
1177 static int
1178 match_ASSOCOFFSETSURFACEACTIONBODY (const char *restrict filename,
1179 const Dwg_Object *restrict obj)
1180 {
1181 char *text;
1182 int found = 0;
1183 const Dwg_Object_ASSOCOFFSETSURFACEACTIONBODY *_obj
1184 = obj->tio.object->tio.ASSOCOFFSETSURFACEACTIONBODY;
1185 MATCH_AcDbAssocParamBasedActionBody (
1186 ASSOCOFFSETSURFACEACTIONBODY) return found;
1187 }
1188 static int
1189 match_ASSOCREVOLVEDSURFACEACTIONBODY (const char *restrict filename,
1190 const Dwg_Object *restrict obj)
1191 {
1192 char *text;
1193 int found = 0;
1194 const Dwg_Object_ASSOCREVOLVEDSURFACEACTIONBODY *_obj
1195 = obj->tio.object->tio.ASSOCREVOLVEDSURFACEACTIONBODY;
1196 MATCH_AcDbAssocParamBasedActionBody (
1197 ASSOCREVOLVEDSURFACEACTIONBODY) return found;
1198 }
1199 static int
1200 match_ASSOCSWEPTSURFACEACTIONBODY (const char *restrict filename,
1201 const Dwg_Object *restrict obj)
1202 {
1203 char *text;
1204 int found = 0;
1205 const Dwg_Object_ASSOCSWEPTSURFACEACTIONBODY *_obj
1206 = obj->tio.object->tio.ASSOCSWEPTSURFACEACTIONBODY;
1207 MATCH_AcDbAssocParamBasedActionBody (
1208 ASSOCSWEPTSURFACEACTIONBODY) return found;
1209 }
1210 static int
1211 match_ASSOCTRIMSURFACEACTIONBODY (const char *restrict filename,
1212 const Dwg_Object *restrict obj)
1213 {
1214 char *text;
1215 int found = 0;
1216 const Dwg_Object_ASSOCTRIMSURFACEACTIONBODY *_obj
1217 = obj->tio.object->tio.ASSOCTRIMSURFACEACTIONBODY;
1218 MATCH_AcDbAssocParamBasedActionBody (
1219 ASSOCTRIMSURFACEACTIONBODY) return found;
1220 }
1221
1222 static int
1223 match_BLOCKPARAMDEPENDENCYBODY (const char *restrict filename,
1224 const Dwg_Object *restrict obj)
1225 {
1226 char *text;
1227 int found = 0;
1228 MATCH_OBJECT (BLOCKPARAMDEPENDENCYBODY, name, 1);
1229 return found;
1230 }
1231 static int
1232 match_BLOCKMOVEACTION (const char *restrict filename,
1233 const Dwg_Object *restrict obj)
1234 {
1235 char *text;
1236 int found = 0;
1237 MATCH_OBJECT (BLOCKMOVEACTION, conn_pts[0].name, 301);
1238 MATCH_OBJECT (BLOCKMOVEACTION, conn_pts[1].name, 302);
1239 return found;
1240 }
1241 static int
1242 match_BLOCKSTRETCHACTION (const char *restrict filename,
1243 const Dwg_Object *restrict obj)
1244 {
1245 char *text;
1246 int found = 0;
1247 MATCH_OBJECT (BLOCKSTRETCHACTION, conn_pts[0].name, 301);
1248 MATCH_OBJECT (BLOCKSTRETCHACTION, conn_pts[1].name, 302);
1249 return found;
1250 }
1251 static int
1252 match_BLOCKROTATEACTION (const char *restrict filename,
1253 const Dwg_Object *restrict obj)
1254 {
1255 char *text;
1256 int found = 0;
1257 MATCH_OBJECT (BLOCKROTATEACTION, conn_pts[0].name, 301);
1258 MATCH_OBJECT (BLOCKROTATEACTION, conn_pts[1].name, 302);
1259 MATCH_OBJECT (BLOCKROTATEACTION, conn_pts[2].name, 303);
1260 return found;
1261 }
1262 static int
1263 match_BLOCKVISIBILITYGRIP (const char *restrict filename,
1264 const Dwg_Object *restrict obj)
1265 {
1266 char *text;
1267 int found = 0;
1268 Dwg_Object_BLOCKVISIBILITYGRIP *_obj
1269 = obj->tio.object->tio.BLOCKVISIBILITYGRIP;
1270
1271 if (_obj->evalexpr.value_code == 1)
1272 {
1273 MATCH_OBJECT (BLOCKVISIBILITYGRIP, evalexpr.value.text1, 1);
1274 }
1275 MATCH_OBJECT (BLOCKVISIBILITYGRIP, name, 1);
1276 return found;
1277 }
1278 static int
1279 match_BLOCKGRIPLOCATIONCOMPONENT (const char *restrict filename,
1280 const Dwg_Object *restrict obj)
1281 {
1282 char *text;
1283 int found = 0;
1284 Dwg_Object_BLOCKGRIPLOCATIONCOMPONENT *_obj
1285 = obj->tio.object->tio.BLOCKGRIPLOCATIONCOMPONENT;
1286
1287 if (_obj->evalexpr.value_code == 1)
1288 {
1289 MATCH_OBJECT (BLOCKGRIPLOCATIONCOMPONENT, evalexpr.value.text1, 1);
1290 }
1291 MATCH_OBJECT (BLOCKGRIPLOCATIONCOMPONENT, grip_expr, 91);
1292 return found;
1293 }
1294 static int
1295 match_BLOCKBASEPOINTPARAMETER (const char *restrict filename,
1296 const Dwg_Object *restrict obj)
1297 {
1298 char *text;
1299 int found = 0;
1300 Dwg_Object_BLOCKBASEPOINTPARAMETER *_obj
1301 = obj->tio.object->tio.BLOCKBASEPOINTPARAMETER;
1302
1303 if (_obj->evalexpr.value_code == 1)
1304 {
1305 MATCH_OBJECT (BLOCKBASEPOINTPARAMETER, evalexpr.value.text1, 1);
1306 }
1307 MATCH_OBJECT (BLOCKBASEPOINTPARAMETER, name, 1);
1308 for (unsigned i = 0; i < _obj->prop1.num_connections; i++)
1309 {
1310 MATCH_OBJECT (BLOCKROTATIONPARAMETER, prop1.connections[i].name, 301);
1311 }
1312 for (unsigned i = 0; i < _obj->prop2.num_connections; i++)
1313 {
1314 MATCH_OBJECT (BLOCKROTATIONPARAMETER, prop2.connections[i].name, 302);
1315 }
1316 return found;
1317 }
1318 static int
1319 match_BLOCKLINEARPARAMETER (const char *restrict filename,
1320 const Dwg_Object *restrict obj)
1321 {
1322 char *text;
1323 int found = 0;
1324 Dwg_Object_BLOCKLINEARPARAMETER *_obj
1325 = obj->tio.object->tio.BLOCKLINEARPARAMETER;
1326
1327 if (_obj->evalexpr.value_code == 1)
1328 {
1329 MATCH_OBJECT (BLOCKLINEARPARAMETER, evalexpr.value.text1, 1);
1330 }
1331 MATCH_OBJECT (BLOCKLINEARPARAMETER, name, 1);
1332 for (unsigned i = 0; i < _obj->prop1.num_connections; i++)
1333 {
1334 MATCH_OBJECT (BLOCKLINEARPARAMETER, prop1.connections[i].name, 301);
1335 }
1336 for (unsigned i = 0; i < _obj->prop2.num_connections; i++)
1337 {
1338 MATCH_OBJECT (BLOCKLINEARPARAMETER, prop2.connections[i].name, 302);
1339 }
1340 for (unsigned i = 0; i < _obj->prop3.num_connections; i++)
1341 {
1342 MATCH_OBJECT (BLOCKLINEARPARAMETER, prop3.connections[i].name, 303);
1343 }
1344 for (unsigned i = 0; i < _obj->prop4.num_connections; i++)
1345 {
1346 MATCH_OBJECT (BLOCKLINEARPARAMETER, prop4.connections[i].name, 304);
1347 }
1348 MATCH_OBJECT (BLOCKLINEARPARAMETER, distance_name, 305);
1349 MATCH_OBJECT (BLOCKLINEARPARAMETER, distance_desc, 306);
1350 MATCH_OBJECT (BLOCKLINEARPARAMETER, value_set.desc, 307);
1351 return found;
1352 }
1353 static int
1354 match_BLOCKFLIPPARAMETER (const char *restrict filename,
1355 const Dwg_Object *restrict obj)
1356 {
1357 char *text;
1358 int found = 0;
1359 Dwg_Object_BLOCKFLIPPARAMETER *_obj
1360 = obj->tio.object->tio.BLOCKFLIPPARAMETER;
1361
1362 if (_obj->evalexpr.value_code == 1)
1363 {
1364 MATCH_OBJECT (BLOCKFLIPPARAMETER, evalexpr.value.text1, 1);
1365 }
1366 MATCH_OBJECT (BLOCKFLIPPARAMETER, name, 1);
1367 for (unsigned i = 0; i < _obj->prop1.num_connections; i++)
1368 {
1369 MATCH_OBJECT (BLOCKFLIPPARAMETER, prop1.connections[i].name, 301);
1370 }
1371 for (unsigned i = 0; i < _obj->prop2.num_connections; i++)
1372 {
1373 MATCH_OBJECT (BLOCKFLIPPARAMETER, prop2.connections[i].name, 302);
1374 }
1375 for (unsigned i = 0; i < _obj->prop3.num_connections; i++)
1376 {
1377 MATCH_OBJECT (BLOCKFLIPPARAMETER, prop3.connections[i].name, 303);
1378 }
1379 for (unsigned i = 0; i < _obj->prop4.num_connections; i++)
1380 {
1381 MATCH_OBJECT (BLOCKFLIPPARAMETER, prop4.connections[i].name, 304);
1382 }
1383 MATCH_OBJECT (BLOCKFLIPPARAMETER, flip_label, 305);
1384 MATCH_OBJECT (BLOCKFLIPPARAMETER, flip_label_desc, 306);
1385 MATCH_OBJECT (BLOCKFLIPPARAMETER, base_state_label, 307);
1386 MATCH_OBJECT (BLOCKFLIPPARAMETER, flipped_state_label, 308);
1387 MATCH_OBJECT (BLOCKFLIPPARAMETER, tooltip, 309);
1388 return found;
1389 }
1390 static int
1391 match_BLOCKROTATIONPARAMETER (const char *restrict filename,
1392 const Dwg_Object *restrict obj)
1393 {
1394 char *text;
1395 int found = 0;
1396 Dwg_Object_BLOCKROTATIONPARAMETER *_obj
1397 = obj->tio.object->tio.BLOCKROTATIONPARAMETER;
1398
1399 if (_obj->evalexpr.value_code == 1)
1400 {
1401 MATCH_OBJECT (BLOCKROTATIONPARAMETER, evalexpr.value.text1, 1);
1402 }
1403 MATCH_OBJECT (BLOCKROTATIONPARAMETER, name, 1);
1404 for (unsigned i = 0; i < _obj->prop1.num_connections; i++)
1405 {
1406 MATCH_OBJECT (BLOCKROTATIONPARAMETER, prop1.connections[i].name, 301);
1407 }
1408 for (unsigned i = 0; i < _obj->prop2.num_connections; i++)
1409 {
1410 MATCH_OBJECT (BLOCKROTATIONPARAMETER, prop2.connections[i].name, 302);
1411 }
1412 for (unsigned i = 0; i < _obj->prop3.num_connections; i++)
1413 {
1414 MATCH_OBJECT (BLOCKROTATIONPARAMETER, prop3.connections[i].name, 303);
1415 }
1416 for (unsigned i = 0; i < _obj->prop4.num_connections; i++)
1417 {
1418 MATCH_OBJECT (BLOCKROTATIONPARAMETER, prop4.connections[i].name, 304);
1419 }
1420 MATCH_OBJECT (BLOCKROTATIONPARAMETER, angle_name, 305);
1421 MATCH_OBJECT (BLOCKROTATIONPARAMETER, angle_desc, 306);
1422 MATCH_OBJECT (BLOCKROTATIONPARAMETER, angle_value_set.desc, 307);
1423 return found;
1424 }
1425 static int
1426 match_BLOCKXYPARAMETER (const char *restrict filename,
1427 const Dwg_Object *restrict obj)
1428 {
1429 char *text;
1430 int found = 0;
1431 Dwg_Object_BLOCKXYPARAMETER *_obj = obj->tio.object->tio.BLOCKXYPARAMETER;
1432
1433 if (_obj->evalexpr.value_code == 1)
1434 {
1435 MATCH_OBJECT (BLOCKXYPARAMETER, evalexpr.value.text1, 1);
1436 }
1437 MATCH_OBJECT (BLOCKXYPARAMETER, name, 1);
1438 for (unsigned i = 0; i < _obj->prop1.num_connections; i++)
1439 {
1440 MATCH_OBJECT (BLOCKXYPARAMETER, prop1.connections[i].name, 301);
1441 }
1442 for (unsigned i = 0; i < _obj->prop2.num_connections; i++)
1443 {
1444 MATCH_OBJECT (BLOCKXYPARAMETER, prop2.connections[i].name, 302);
1445 }
1446 for (unsigned i = 0; i < _obj->prop3.num_connections; i++)
1447 {
1448 MATCH_OBJECT (BLOCKXYPARAMETER, prop3.connections[i].name, 303);
1449 }
1450 for (unsigned i = 0; i < _obj->prop4.num_connections; i++)
1451 {
1452 MATCH_OBJECT (BLOCKXYPARAMETER, prop4.connections[i].name, 304);
1453 }
1454 MATCH_OBJECT (BLOCKXYPARAMETER, x_label, 305);
1455 MATCH_OBJECT (BLOCKXYPARAMETER, x_label_desc, 306);
1456 MATCH_OBJECT (BLOCKXYPARAMETER, y_label, 307);
1457 MATCH_OBJECT (BLOCKXYPARAMETER, y_label_desc, 308);
1458 MATCH_OBJECT (BLOCKXYPARAMETER, x_value_set.desc, 410);
1459 MATCH_OBJECT (BLOCKXYPARAMETER, y_value_set.desc, 309);
1460 return found;
1461 }
1462 static int
1463 match_BLOCKVISIBILITYPARAMETER (const char *restrict filename,
1464 const Dwg_Object *restrict obj)
1465 {
1466 char *text;
1467 int found = 0;
1468 Dwg_Object_BLOCKVISIBILITYPARAMETER *_obj
1469 = obj->tio.object->tio.BLOCKVISIBILITYPARAMETER;
1470
1471 if (_obj->evalexpr.value_code == 1)
1472 {
1473 MATCH_OBJECT (BLOCKVISIBILITYPARAMETER, evalexpr.value.text1, 1);
1474 }
1475 MATCH_OBJECT (BLOCKVISIBILITYPARAMETER, name, 1);
1476 for (unsigned i = 0; i < _obj->prop1.num_connections; i++)
1477 {
1478 MATCH_OBJECT (BLOCKVISIBILITYPARAMETER, prop1.connections[i].name, 301);
1479 }
1480 for (unsigned i = 0; i < _obj->prop2.num_connections; i++)
1481 {
1482 MATCH_OBJECT (BLOCKVISIBILITYPARAMETER, prop2.connections[i].name, 302);
1483 }
1484 MATCH_OBJECT (BLOCKVISIBILITYPARAMETER, blockvisi_name, 301);
1485 MATCH_OBJECT (BLOCKVISIBILITYPARAMETER, blockvisi_desc, 302);
1486 for (unsigned i = 0; i < _obj->num_states; i++)
1487 {
1488 MATCH_OBJECT (BLOCKVISIBILITYPARAMETER, states[i].name, 303);
1489 }
1490 return found;
1491 }
1492 static int
1493 match_NAVISWORKSMODELDEF (const char *restrict filename,
1494 const Dwg_Object *restrict obj)
1495 {
1496 char *text;
1497 int found = 0;
1498 MATCH_OBJECT (NAVISWORKSMODELDEF, path, 1);
1499 return found;
1500 }
1501
1502 static int
1503 match_OBJECTS (const char *restrict filename, Dwg_Data *restrict dwg)
1504 {
1505 int found = 0;
1506 char *text;
1507
1508 if (!dwg)
1509 return 0;
1510 for (BITCODE_BL i = 0; i < dwg->num_objects; i++)
1511 {
1512 const Dwg_Object *obj = &dwg->object[i];
1513 if (obj->supertype != DWG_SUPERTYPE_OBJECT)
1514 continue;
1515 // processed later, --tables finds BLOCK
1516 if (obj->fixedtype == DWG_TYPE_BLOCK_HEADER)
1517 continue;
1518 if (numtype) // search for allowed --type and skip if not
1519 {
1520 int typeok = 0;
1521 for (int j = 0; j < numtype; j++)
1522 {
1523 if (obj->dxfname && !strcmp (type[j], obj->dxfname))
1524 {
1525 typeok = 1;
1526 break;
1527 }
1528 }
1529 if (!typeok) // next obj
1530 continue;
1531 }
1532
1533 #define ELSEMATCH(OBJECT) \
1534 else if (obj->fixedtype == DWG_TYPE_##OBJECT) found \
1535 += match_##OBJECT (filename, obj);
1536
1537 if (obj->fixedtype == DWG_TYPE_LAYER)
1538 found += match_LAYER (filename, obj);
1539 ELSEMATCH (LTYPE)
1540 ELSEMATCH (STYLE)
1541 ELSEMATCH (VIEW)
1542 ELSEMATCH (VPORT)
1543 ELSEMATCH (DIMSTYLE)
1544 ELSEMATCH (UCS)
1545 ELSEMATCH (VX_TABLE_RECORD)
1546 if (opt_tables)
1547 continue;
1548
1549 if (obj->fixedtype == DWG_TYPE_DICTIONARY
1550 || obj->fixedtype == DWG_TYPE_DICTIONARYWDFLT)
1551 found += match_DICTIONARY (filename, obj);
1552 ELSEMATCH (GROUP)
1553 ELSEMATCH (MLINESTYLE)
1554 ELSEMATCH (DICTIONARYVAR)
1555 ELSEMATCH (IMAGEDEF)
1556 ELSEMATCH (LAYER_INDEX)
1557 ELSEMATCH (LAYOUT)
1558 ELSEMATCH (PLOTSETTINGS)
1559 ELSEMATCH (SCALE)
1560 ELSEMATCH (FIELD)
1561 ELSEMATCH (TABLECONTENT)
1562 ELSEMATCH (GEODATA)
1563 else if (obj->fixedtype == DWG_TYPE_PDFDEFINITION) found
1564 += match_UNDERLAYDEFINITION (filename, obj);
1565 else if (obj->fixedtype == DWG_TYPE_DGNDEFINITION) found
1566 += match_UNDERLAYDEFINITION (filename, obj);
1567 else if (obj->fixedtype == DWG_TYPE_DWFDEFINITION) found
1568 += match_UNDERLAYDEFINITION (filename, obj);
1569 ELSEMATCH (VISUALSTYLE)
1570 ELSEMATCH (TABLESTYLE)
1571 ELSEMATCH (SUNSTUDY)
1572 ELSEMATCH (LIGHTLIST)
1573 ELSEMATCH (DBCOLOR)
1574 ELSEMATCH (MATERIAL)
1575 ELSEMATCH (DIMASSOC)
1576 ELSEMATCH (ASSOCOSNAPPOINTREFACTIONPARAM)
1577 ELSEMATCH (ASSOCACTIONPARAM)
1578 ELSEMATCH (ASSOCEDGEACTIONPARAM)
1579 ELSEMATCH (ASSOCFACEACTIONPARAM)
1580 ELSEMATCH (ASSOCOBJECTACTIONPARAM)
1581 ELSEMATCH (ASSOCPATHACTIONPARAM)
1582 ELSEMATCH (ASSOCVERTEXACTIONPARAM)
1583 ELSEMATCH (ASSOCPATCHSURFACEACTIONBODY)
1584 ELSEMATCH (ASSOCPLANESURFACEACTIONBODY)
1585 ELSEMATCH (ASSOCEXTENDSURFACEACTIONBODY)
1586 ELSEMATCH (ASSOCEXTRUDEDSURFACEACTIONBODY)
1587 ELSEMATCH (ASSOCFILLETSURFACEACTIONBODY)
1588 ELSEMATCH (ASSOCLOFTEDSURFACEACTIONBODY)
1589 ELSEMATCH (ASSOCNETWORKSURFACEACTIONBODY)
1590 ELSEMATCH (ASSOCOFFSETSURFACEACTIONBODY)
1591 ELSEMATCH (ASSOCREVOLVEDSURFACEACTIONBODY)
1592 ELSEMATCH (ASSOCSWEPTSURFACEACTIONBODY)
1593 ELSEMATCH (ASSOCTRIMSURFACEACTIONBODY)
1594 ELSEMATCH (ASSOCMLEADERACTIONBODY)
1595 ELSEMATCH (ASSOC3POINTANGULARDIMACTIONBODY)
1596 ELSEMATCH (ASSOCALIGNEDDIMACTIONBODY)
1597 ELSEMATCH (ASSOCORDINATEDIMACTIONBODY)
1598 ELSEMATCH (ASSOCROTATEDDIMACTIONBODY)
1599 ELSEMATCH (BLOCKPARAMDEPENDENCYBODY)
1600 ELSEMATCH (BLOCKBASEPOINTPARAMETER)
1601 ELSEMATCH (BLOCKFLIPPARAMETER)
1602 ELSEMATCH (BLOCKLINEARPARAMETER)
1603 ELSEMATCH (BLOCKROTATIONPARAMETER)
1604 ELSEMATCH (BLOCKXYPARAMETER)
1605 ELSEMATCH (BLOCKVISIBILITYPARAMETER)
1606 ELSEMATCH (BLOCKMOVEACTION)
1607 ELSEMATCH (BLOCKSTRETCHACTION)
1608 ELSEMATCH (BLOCKROTATEACTION)
1609 ELSEMATCH (BLOCKVISIBILITYGRIP)
1610 ELSEMATCH (BLOCKGRIPLOCATIONCOMPONENT)
1611 ELSEMATCH (NAVISWORKSMODELDEF)
1612 }
1613 return found;
1614 }
1615
1616 static int
1617 match_preR13_entities (const char *restrict filename,
1618 const Dwg_Data *restrict dwg, const bool blocks)
1619 {
1620 int found = 0;
1621 char *text;
1622
1623 // TODO skip block entities for now
1624 if (blocks)
1625 return found;
1626 for (unsigned j = 0; j < dwg->num_objects; j++)
1627 {
1628 const Dwg_Object *obj = &dwg->object[j];
1629 if (obj->fixedtype == DWG_TYPE_UNUSED)
1630 continue;
1631 if (verbose)
1632 fprintf (stderr, "%s [%d]\n", obj->name, obj->index);
1633 if (numtype) // search for allowed --type and skip if not
1634 {
1635 int typeok = 0;
1636 for (int i = 0; i < numtype; i++)
1637 {
1638 if (obj->dxfname && !strcmp (type[i], obj->dxfname))
1639 {
1640 typeok = 1;
1641 break;
1642 }
1643 }
1644 if (!typeok) // next obj
1645 continue;
1646 }
1647
1648 if (obj->fixedtype == DWG_TYPE_TEXT)
1649 found += match_TEXT (filename, obj);
1650 #ifdef WITH_SUBENTS
1651 ELSEMATCH (ATTRIB)
1652 #endif
1653 ELSEMATCH (ATTDEF)
1654 if (!opt_text)
1655 {
1656 if (obj->type == DWG_TYPE_DIMENSION_r11)
1657 found += match_DIMENSION (filename, obj);
1658 ELSEMATCH (VIEWPORT)
1659 ELSEMATCH (BLOCK)
1660 }
1661 if (!opt_text)
1662 {
1663 // common entity names
1664 MATCH_TABLE (ENTITY, layer, LAYER, 8);
1665 MATCH_TABLE (ENTITY, ltype, LTYPE, 8);
1666 }
1667 }
1668 return found;
1669 }
1670
1671 static int
1672 match_BLOCK_HEADER (const char *restrict filename,
1673 Dwg_Object_Ref *restrict ref)
1674 {
1675 int found = 0;
1676 const Dwg_Object *hdr;
1677 const Dwg_Object *obj;
1678 char *text;
1679
1680 if (!ref)
1681 return 0;
1682 obj = hdr = ref->obj;
1683 if (!hdr || hdr->supertype != DWG_SUPERTYPE_OBJECT
1684 || hdr->type != DWG_TYPE_BLOCK_HEADER)
1685 return 0;
1686
1687 MATCH_OBJECT (BLOCK_HEADER, name, 2);
1688 if (opt_tables)
1689 return found;
1690 MATCH_OBJECT (BLOCK_HEADER, xref_pname, 1);
1691 MATCH_OBJECT (BLOCK_HEADER, description, 4);
1692
1693 if (verbose)
1694 fprintf (stderr, "HDR: %d, HANDLE: " FORMAT_RLLx "\n", hdr->index,
1695 hdr->handle.value);
1696 for (obj = get_first_owned_entity (hdr); obj;
1697 obj = get_next_owned_entity (hdr, obj)) // without subentities
1698 {
1699 if (!obj)
1700 break;
1701 if (verbose)
1702 fprintf (stderr, "%s [%d], HANDLE: " FORMAT_RLLx "\n", obj->name,
1703 obj->index, obj->handle.value);
1704 if (numtype) // search for allowed --type and skip if not
1705 {
1706 int typeok = 0;
1707 for (int i = 0; i < numtype; i++)
1708 {
1709 if (obj->dxfname && !strcmp (type[i], obj->dxfname))
1710 {
1711 typeok = 1;
1712 break;
1713 }
1714 }
1715 if (!typeok) // next obj
1716 continue;
1717 }
1718
1719 if (obj->fixedtype == DWG_TYPE_TEXT)
1720 found += match_TEXT (filename, obj);
1721 #ifdef WITH_SUBENTS
1722 ELSEMATCH (ATTRIB)
1723 #endif
1724 ELSEMATCH (ATTDEF)
1725 ELSEMATCH (MTEXT)
1726 ELSEMATCH (ARCALIGNEDTEXT)
1727 else if (obj->fixedtype == DWG_TYPE_INSERT)
1728 {
1729 #ifndef WITH_SUBENTS
1730 const Dwg_Data *dwg = obj->parent;
1731 Dwg_Entity_INSERT *_obj = obj->tio.entity->tio.INSERT;
1732 if (_obj->has_attribs)
1733 {
1734 if (dwg->header.version >= R_13b1 && dwg->header.version <= R_2000)
1735 {
1736 Dwg_Object *last_attrib = _obj->last_attrib->obj;
1737 Dwg_Object *o
1738 = _obj->first_attrib ? _obj->first_attrib->obj : NULL;
1739 while (o && o->type == DWG_TYPE_ATTRIB)
1740 {
1741 found += match_ATTRIB (filename, o);
1742 o = dwg_next_entity (o);
1743 if (o == last_attrib)
1744 break;
1745 }
1746 }
1747 else if (dwg->header.version >= R_2004)
1748 {
1749 Dwg_Object *o;
1750 for (BITCODE_BL j = 0; j < _obj->num_owned; j++)
1751 {
1752 o = _obj->attribs[j] ? _obj->attribs[j]->obj : NULL;
1753 if (o && o->type == DWG_TYPE_ATTRIB)
1754 found += match_ATTRIB (filename, o);
1755 }
1756 }
1757 }
1758 #endif
1759 }
1760 else if (obj->fixedtype == DWG_TYPE_MINSERT)
1761 {
1762 #ifndef WITH_SUBENTS
1763 const Dwg_Data *dwg = obj->parent;
1764 Dwg_Entity_MINSERT *_obj = obj->tio.entity->tio.MINSERT;
1765 if (_obj->has_attribs)
1766 {
1767 if (dwg->header.version >= R_13b1 && dwg->header.version <= R_2000)
1768 {
1769 Dwg_Object *last_attrib = _obj->last_attrib->obj;
1770 Dwg_Object *o
1771 = _obj->first_attrib ? _obj->first_attrib->obj : NULL;
1772 while (o && o->type == DWG_TYPE_ATTRIB)
1773 {
1774 found += match_ATTRIB (filename, o);
1775 o = dwg_next_entity (o);
1776 if (o == last_attrib)
1777 break;
1778 }
1779 }
1780 else if (dwg->header.version >= R_2004)
1781 {
1782 Dwg_Object *o;
1783 for (BITCODE_BL j = 0; j < _obj->num_owned; j++)
1784 {
1785 o = _obj->attribs[j] ? _obj->attribs[j]->obj : NULL;
1786 if (o && o->type == DWG_TYPE_ATTRIB)
1787 found += match_ATTRIB (filename, o);
1788 }
1789 }
1790 }
1791 #endif
1792 }
1793 if (!opt_text)
1794 {
1795 if (obj->fixedtype == DWG_TYPE_DIMENSION_ORDINATE
1796 || obj->fixedtype == DWG_TYPE_DIMENSION_LINEAR
1797 || obj->fixedtype == DWG_TYPE_DIMENSION_ALIGNED
1798 || obj->fixedtype == DWG_TYPE_DIMENSION_ANG3PT
1799 || obj->fixedtype == DWG_TYPE_DIMENSION_ANG2LN
1800 || obj->fixedtype == DWG_TYPE_DIMENSION_RADIUS
1801 || obj->fixedtype == DWG_TYPE_DIMENSION_DIAMETER)
1802 found += match_DIMENSION (filename, obj);
1803 ELSEMATCH (VIEWPORT)
1804 else if (obj->fixedtype == DWG_TYPE__3DSOLID
1805 || obj->fixedtype == DWG_TYPE_BODY
1806 || obj->fixedtype == DWG_TYPE_REGION) found
1807 += match_3DSOLID (filename, obj);
1808
1809 ELSEMATCH (BLOCK)
1810 ELSEMATCH (HATCH)
1811 ELSEMATCH (TOLERANCE)
1812 ELSEMATCH (TABLE)
1813 ELSEMATCH (GEOPOSITIONMARKER)
1814 ELSEMATCH (LEADER)
1815 ELSEMATCH (MULTILEADER)
1816 ELSEMATCH (LIGHT)
1817 }
1818
1819 if (!opt_text)
1820 {
1821 // common entity names
1822 MATCH_TABLE (ENTITY, layer, LAYER, 8);
1823 MATCH_TABLE (ENTITY, ltype, LTYPE, 8);
1824 if (obj->parent->header.version >= R_2000)
1825 {
1826 MATCH_TABLE (ENTITY, plotstyle, PLOTSTYLE, 8);
1827 }
1828 if (obj->parent->header.version >= R_2007)
1829 {
1830 MATCH_TABLE (ENTITY, material, MATERIAL, 8);
1831 MATCH_TABLE (ENTITY, shadow, DICTIONARY, 8);
1832 }
1833 if (obj->parent->header.version >= R_2010)
1834 {
1835 MATCH_TABLE (ENTITY, full_visualstyle, VISUALSTYLE, 8);
1836 MATCH_TABLE (ENTITY, face_visualstyle, VISUALSTYLE, 8);
1837 MATCH_TABLE (ENTITY, edge_visualstyle, VISUALSTYLE, 8);
1838 }
1839 }
1840 }
1841 return found;
1842 }
1843
1844 int
1845 main (int argc, char *argv[])
1846 {
1847 int error = 0;
1848 int i = 1, j;
1849 char *filename;
1850 Dwg_Data dwg;
1851 size_t plen;
1852 int errcode;
1853 #ifdef HAVE_PCRE2_H
1854 PCRE2_SIZE erroffset;
1855 int have_jit;
1856 # ifdef HAVE_PCRE2_16
1857 BITCODE_TU pattern16;
1858 # endif
1859 #endif
1860 int opt_recurse = 0;
1861 int count = 0;
1862 int c;
1863 #ifdef HAVE_GETOPT_LONG
1864 int option_index = 0;
1865 static struct option long_options[]
1866 = { { "case", 0, 0, 'i' }, { "extended", 0, 0, 'x' },
1867 { "count", 0, 0, 'c' }, { "no-filename", 0, 0, 'h' },
1868 { "recursive", 0, 0, 'r' }, { "recursive", 0, 0, 'R' },
1869 { "type", 1, 0, 'y' }, { "dxf", 1, 0, 'd' },
1870 { "text", 0, 0, 't' }, { "blocks", 0, 0, 'b' },
1871 { "tables", 0, 0, 0 }, { "help", 0, 0, 0 },
1872 { "version", 0, 0, 0 }, { NULL, 0, NULL, 0 } };
1873 #endif
1874
1875 // check args
1876 if (argc < 2)
1877 return usage ();
1878 memset (dxf, 0, 10 * sizeof (short));
1879
1880 while
1881 #ifdef HAVE_GETOPT_LONG
1882 ((c = getopt_long (argc, argv, "ixchrRy:d:tb", long_options,
1883 &option_index))
1884 != -1)
1885 #else
1886 ((c = getopt (argc, argv, "ixchrRy:d:tbvu")) != -1)
1887 #endif
1888 {
1889 if (c == -1)
1890 break;
1891 switch (c)
1892 {
1893 #ifdef HAVE_GETOPT_LONG
1894 case 0:
1895 if (!strcmp (long_options[option_index].name, "help"))
1896 return help ();
1897 if (!strcmp (long_options[option_index].name, "version"))
1898 return opt_version ();
1899 if (!strcmp (long_options[option_index].name, "tables"))
1900 opt_tables = 1;
1901 break;
1902 #else
1903 case 'v':
1904 return opt_version ();
1905 #endif
1906 #ifdef HAVE_PCRE2_H
1907 case 'x':
1908 options |= PCRE2_EXTENDED;
1909 break;
1910 #endif
1911 case 'i':
1912 options |= PCRE2_CASELESS;
1913 break;
1914 case 'c':
1915 opt_count = 1;
1916 break;
1917 case 'h':
1918 opt_filename = 0;
1919 break;
1920 case 'r':
1921 case 'R':
1922 opt_recurse = 1;
1923 break;
1924 case 't':
1925 opt_text = 1;
1926 break;
1927 case 'b':
1928 opt_blocks = 1;
1929 break;
1930 case 'y':
1931 if (numtype >= 10)
1932 return usage (); // too many
1933 type[numtype++] = optarg; // a string
1934 break;
1935 case 'd':
1936 if (numdxf >= 10)
1937 return usage (); // too many
1938 // a integer group
1939 dxf[numdxf++] = (short)strtol (optarg, NULL, 10);
1940 break;
1941
1942 case 'u':
1943 return help ();
1944 case '?':
1945 fprintf (stderr, "%s: invalid option '-%c' ignored\n", argv[0],
1946 optopt);
1947 break;
1948 default:
1949 return usage ();
1950 }
1951 }
1952 i = optind;
1953 if (i > argc - 2) // need 2 more args. TODO: unless -R given
1954 return usage ();
1955
1956 pattern = argv[i];
1957 plen = strlen (pattern);
1958 #ifdef HAVE_PCRE2_H
1959 pcre2_config_8 (PCRE2_CONFIG_JIT, &have_jit);
1960 ri8 = pcre2_compile_8 ((PCRE2_SPTR8)pattern, /* pattern */
1961 plen & 0xFFFFFFFF, /* uint32_t */
1962 options, /* options */
1963 &errcode, /* errors */
1964 &erroffset, /* error offset */
1965 # ifdef USE_MATCH_CONTEXT
1966 compile_context
1967 # else
1968 NULL
1969 # endif
1970 );
1971 if (errcode != 0 && errcode != 100)
1972 {
1973 pcre2_get_error_message_8 (errcode, (PCRE2_UCHAR8 *)buf, 4096);
1974 // cppcheck-suppress preprocessorErrorDirective
1975 LOG_ERROR ("pcre2_compile_8 error %d: %s with %s", errcode, buf,
1976 pattern);
1977 return 1;
1978 }
1979 match_data8 = pcre2_match_data_create_from_pattern_8 (ri8, NULL);
1980 if (have_jit)
1981 pcre2_jit_compile_8 (ri8, PCRE2_JIT_COMPILE_OPTIONS);
1982
1983 # ifdef HAVE_PCRE2_16
1984 pcre2_config_16 (PCRE2_CONFIG_JIT, &have_jit);
1985 pattern16 = bit_utf8_to_TU (pattern, 0);
1986 ri16 = pcre2_compile_16 ((PCRE2_SPTR16)pattern16, /* pattern */
1987 plen & 0xFFFFFFFF, /* uint32_t */
1988 options, /* options */
1989 &errcode, /* errors */
1990 &erroffset, /* error offset */
1991 # ifdef USE_MATCH_CONTEXT
1992 compile_context
1993 # else
1994 NULL
1995 # endif
1996 );
1997 free (pattern16);
1998 if (errcode != 0 && errcode != 100)
1999 {
2000 pcre2_get_error_message_8 (errcode, (PCRE2_UCHAR8 *)buf, 4096);
2001 LOG_ERROR ("pcre2_compile_16 error %d: %s with %s", errcode, buf,
2002 pattern);
2003 return 1;
2004 }
2005 match_data16 = pcre2_match_data_create_from_pattern_16 (ri16, NULL);
2006 if (have_jit)
2007 pcre2_jit_compile_16 (ri16, PCRE2_JIT_COMPILE_OPTIONS);
2008 # endif
2009 #endif
2010
2011 // for all filenames...
2012 for (j = i + 1; j < argc; j++)
2013 {
2014 Dwg_Object_Ref *mspace_ref = NULL;
2015 filename = argv[j];
2016 memset (&dwg, 0, sizeof (Dwg_Data));
2017 dwg.opts = 0;
2018 error = dwg_read_file (filename, &dwg);
2019 if (error > DWG_ERR_CRITICAL)
2020 {
2021 fprintf (stderr, "Error: Could not read DWG file %s, error: 0x%x\n",
2022 filename, error);
2023 continue;
2024 }
2025
2026 if (!opt_text)
2027 count += match_OBJECTS (filename, &dwg);
2028 if (dwg.header.version < R_13b1)
2029 { // FIXME hack
2030 // mspace_ref = (Dwg_Object_Ref *)calloc (1, sizeof
2031 // (Dwg_Object_Ref)); mspace_ref->obj = &dwg.object[0];
2032 count += match_preR13_entities (filename, &dwg, false);
2033 }
2034 else
2035 mspace_ref = dwg_model_space_ref (&dwg);
2036
2037 if (!opt_tables)
2038 count += match_BLOCK_HEADER (filename, mspace_ref);
2039 if (opt_blocks)
2040 {
2041 if (dwg.header.version < R_13b1)
2042 count += match_preR13_entities (filename, &dwg, true);
2043 else
2044 for (long k = 0; k < dwg.block_control.num_entries; k++)
2045 {
2046 count += match_BLOCK_HEADER (filename,
2047 dwg.block_control.entries[k]);
2048 }
2049 }
2050 if (!opt_tables)
2051 count += match_BLOCK_HEADER (filename, dwg_paper_space_ref (&dwg));
2052
2053 fflush (stdout);
2054 // if (dwg.header.version < R_13b1)
2055 // free (mspace_ref);
2056 if (j < argc)
2057 dwg_free (&dwg); // skip the last free
2058 }
2059 if (opt_count)
2060 printf ("%d\n", count);
2061
2062 return count ? 0 : 1;
2063 }