Index: trunk/src_plugins/io_altium/altium_parser/Makefile =================================================================== --- trunk/src_plugins/io_altium/altium_parser/Makefile (nonexistent) +++ trunk/src_plugins/io_altium/altium_parser/Makefile (revision 35284) @@ -0,0 +1,13 @@ +SPHASH=src_3rd/sphash/sphash +CFLAGS = -Wall -g -Isrc_3rd + +main: main.o pcbdoc_ascii.o altium_kw.o + +main.o: main.c pcbdoc_ascii.h + +pcbdoc_ascii.o: pcbdoc_ascii.c pcbdoc_ascii.h + +altium_kw.c altium_kw.h: altium_kw.sphash + $(SPHASH) $(VERBOSE) -i --multi --prefix altium_kw --out altium_kw < altium_kw.sphash + +altium_kw.o: altium_kw.c altium_kw.h \ No newline at end of file Index: trunk/src_plugins/io_altium/altium_parser/altium_kw.sphash =================================================================== --- trunk/src_plugins/io_altium/altium_parser/altium_kw.sphash (nonexistent) +++ trunk/src_plugins/io_altium/altium_parser/altium_kw.sphash (revision 35284) @@ -0,0 +1,16 @@ +record + misc + board + class + net + component + polygon + arc + pad + via + track + text + componentbody +field + layer + locked Index: trunk/src_plugins/io_altium/altium_parser/config.h =================================================================== --- trunk/src_plugins/io_altium/altium_parser/config.h (nonexistent) +++ trunk/src_plugins/io_altium/altium_parser/config.h (revision 35284) @@ -0,0 +1,2 @@ +#define TODO(s) + Index: trunk/src_plugins/io_altium/altium_parser/main.c =================================================================== --- trunk/src_plugins/io_altium/altium_parser/main.c (nonexistent) +++ trunk/src_plugins/io_altium/altium_parser/main.c (revision 35284) @@ -0,0 +1,56 @@ +#include +#include +#include "pcbdoc_ascii.h" + +static void dump_tree(altium_tree_t *tree) +{ + altium_record_t *rec; + int n; + + for(n = 0; n < altium_kw_record_SPHASH_MAXVAL+1; n++) { + printf("Records in %s:\n", altium_kw_keyname(n)); + for(rec = gdl_first(&tree->rec[n]); rec != NULL; rec = gdl_next(&tree->rec[n], rec)) { + altium_field_t *field; + printf(" %s\n", rec->type_s); + for(field = gdl_first(&rec->fields); field != NULL; field = gdl_next(&rec->fields, field)) { + printf(" %s=%s\n", field->key, field->val); + } + } + } +} + +int main(int argc, char *argv[]) +{ + const char *fn = "A.PcbDoc"; + FILE *f; + altium_tree_t tree = {0}; + int res; + + if (argc > 1) + fn = argv[1]; + + f = fopen(fn, "r"); + if (f == NULL) { + fprintf(stderr, "can't open %s for read\n", fn); + return -1; + } + res = pcbdoc_ascii_test_parse(NULL, 0, fn, f); + fclose(f); + + if (!res) { + fprintf(stderr, "test parse says '%s' is not a PcbDoc\n", fn); + return -1; + } + + if (pcbdoc_ascii_parse_file(NULL, &tree, fn) != 0) { + altium_tree_free(&tree); + fprintf(stderr, "failed to parse '%s'\n", fn); + return -1; + } + + + dump_tree(&tree); + + altium_tree_free(&tree); + return 0; +} Index: trunk/src_plugins/io_altium/altium_parser/pcbdoc_ascii.c =================================================================== --- trunk/src_plugins/io_altium/altium_parser/pcbdoc_ascii.c (nonexistent) +++ trunk/src_plugins/io_altium/altium_parser/pcbdoc_ascii.c (revision 35284) @@ -0,0 +1,288 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * altium pcbdoc ASCII plugin - low level read: parse into a tree in mem + * pcb-rnd Copyright (C) 2021 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include + +#include "pcbdoc_ascii.h" + +#define block_size 65536L + +/* optional trace */ +#if 0 +# define tprintf printf +#else + static int tprintf(const char *fmt, ...) { return 0; } +#endif + +int pcbdoc_ascii_test_parse(pcb_plug_io_t *ctx, pcb_plug_iot_t typ, const char *file_name, FILE *f) +{ + char line[256], *s; + + /* first line should comply to the low level file format */ + fgets(line, sizeof(line), f); + + s = line; + if (*s == '|') s++; + + /* every line must start with a RECORD field, the first one too */ + if (strncmp(s,"RECORD=", 7) != 0) + return 0; + + /* there must be a field separator */ + if (strchr(s, '|') == NULL) + return 0; + + return 1; +} + +static int pcbdoc_ascii_load_blocks(altium_tree_t *tree, FILE *f, long max) +{ + long curr = 0, next; + + for(;;) { + int c; + altium_block_t *blk; + + /* seek at potential end-of-block */ + next = curr + block_size; + if (next > max-1) + next = max-1; + fseek(f, next, SEEK_SET); + + /* seek first record separator (or eof) */ + for(;;) { + c = fgetc(f); + if (c == EOF) + break; + next++; + if ((c == '\r') || (c == '\n')) + break; + } + + if (c != EOF) { + /* seek end of record separator section (typica: \r\n) */ + for(;;) { + c = fgetc(f); + if (c == EOF) + break; + if ((c != '\r') && (c != '\n')) + break; + next++; + } + } + + if (next == curr) + break; + + /* by now "next" points to the first character of the next block */ + blk = malloc(sizeof(altium_block_t) + (next-curr) + 1); + if (blk == NULL) { + fprintf(stderr, "pcbdoc_ascii_load_blocks: failed to alloc memory\n"); + return -1; + } + memset(&blk->link, 0, sizeof(blk->link)); + blk->size = next-curr; + fseek(f, curr, SEEK_SET); + if (fread(&blk->raw, blk->size, 1, f) != 1) { + free(blk); + fprintf(stderr, "pcbdoc_ascii_load_blocks: can't read that many: %ld from %ld (%ld; max is %ld)\n", blk->size, curr, curr+blk->size, max); + return -1; + } + blk->raw[blk->size] = '\0'; + gdl_append(&tree->blocks, blk, link); +/* printf("curr=%ld next=%ld\n", curr, next);*/ + curr = next; + } + + return 0; +} + + +TODO("these two 'new' functions should use stack-slabs from umalloc") +static altium_record_t *pcbdoc_ascii_new_rec(altium_tree_t *tree, const char *type_s) +{ + altium_record_t *rec = calloc(sizeof(altium_record_t), 1); + int kw = altium_kw_sphash(type_s); + + if ((kw < altium_kw_record_SPHASH_MINVAL) || (kw > altium_kw_record_SPHASH_MAXVAL)) + kw = altium_kw_record_misc; + + rec->type = kw; + rec->type_s = type_s; + + gdl_append(&tree->rec[kw], rec, link); + + return rec; +} + +static altium_field_t *pcbdoc_ascii_new_field(altium_tree_t *tree, altium_record_t *rec, const char *key, const char *val) +{ + altium_field_t *field = calloc(sizeof(altium_field_t), 1); + int kw = altium_kw_sphash(key); + + if ((kw < altium_kw_field_SPHASH_MINVAL) || (kw > altium_kw_field_SPHASH_MAXVAL)) + kw = altium_kw_record_SPHASH_INVALID; + + field->type = kw; + field->key = key; + field->val = val; + + gdl_append(&rec->fields, field, link); + + return field; +} + +static int pcbdoc_ascii_parse_blocks(altium_tree_t *tree, const char *fn) +{ + altium_block_t *blk; + long line = 1; + + for(blk = gdl_first(&tree->blocks); blk != NULL; blk = gdl_next(&tree->blocks, blk)) { + char *s = blk->raw, *end; + + tprintf("---blk---\n"); + + for(;;) { /* parse each line within the block */ + altium_record_t *rec; + int nl = 0; + + /* ignore leading seps and newlines, exit if ran out of the string */ + while((*s == '|') || (*s == '\r') || (*s == '\n')) s++; + if (*s == '\0') + break; + + /* parse the record header */ + if (strncmp(s, "RECORD=", 7) != 0) { + fprintf(stderr, "First field must be record in %s:%ld\n", fn, line); + return -1; + } + s+=7; + end = strpbrk(s, "|\r\n"); + if (end == NULL) { + fprintf(stderr, "Unterminated record in %s:%ld\n", fn, line); + return -1; + } + *end = '\0'; + tprintf("rec='%s'\n", s); + rec = pcbdoc_ascii_new_rec(tree, s); + s = end+1; + + + /* parse fields */ + for(;;) { + char *key, *val; + + /* ignore leading seps and newlines, exit if ran out of the string */ + while(*s == '|') s++; + if (*s == '\0') + break; + + /* find sep */ + end = strpbrk(s, "|\r\n"); + if (end == NULL) { + fprintf(stderr, "Unterminated field in %s:%ld\n", fn, line); + return -1; + } + if (*end != '|') + nl = 1; + *end = '\0'; + + key = s; + val = strchr(s, '='); + if (val != NULL) { + *val = '\0'; + val++; + } + else + val = end; + + tprintf(" %s=%s\n", key, val); + pcbdoc_ascii_new_field(tree, rec, key, val); + s = end+1; + if (nl) + break; + } + } + } + + return 0; +} + +int pcbdoc_ascii_parse_file(rnd_hidlib_t *hidlib, altium_tree_t *tree, const char *fn) +{ + FILE *f; + int res; + long filesize; + + filesize = rnd_file_size(hidlib, fn); + if (filesize <= 0) + return -1; + + f = fopen(fn, "rb"); + if (f == NULL) + return -1; + + res = pcbdoc_ascii_load_blocks(tree, f, filesize); + fclose(f); + + if (res != 0) + return -1; + + + return pcbdoc_ascii_parse_blocks(tree, fn); +} + + +void altium_tree_free(altium_tree_t *tree) +{ + altium_block_t *blk; + altium_record_t *rec; + int n; + + for(blk = gdl_first(&tree->blocks); blk != NULL; blk = gdl_first(&tree->blocks)) { + gdl_remove(&tree->blocks, blk, link); + free(blk); + } + + for(n = 0; n < altium_kw_record_SPHASH_MAXVAL+1; n++) { + for(rec = gdl_first(&tree->rec[n]); rec != NULL; rec = gdl_first(&tree->rec[n])) { + altium_field_t *field; + + for(field = gdl_first(&rec->fields); field != NULL; field = gdl_first(&rec->fields)) { + gdl_remove(&rec->fields, field, link); + free(field); + } + gdl_remove(&tree->rec[n], rec, link); + free(rec); + } + } +} + Index: trunk/src_plugins/io_altium/altium_parser/pcbdoc_ascii.h =================================================================== --- trunk/src_plugins/io_altium/altium_parser/pcbdoc_ascii.h (nonexistent) +++ trunk/src_plugins/io_altium/altium_parser/pcbdoc_ascii.h (revision 35284) @@ -0,0 +1,34 @@ +#include "plug_io.h" +#include +#include "altium_kw.h" + +typedef struct altium_field_s { + altium_kw_field_keys_t type; /* derived from ->key */ + const char *key; + const char *val; + gdl_elem_t link; /* in parent record */ +} altium_field_t; + +typedef struct altium_record_s { + altium_kw_record_keys_t type; /* derived from ->type_s */ + const char *type_s; + gdl_list_t fields; + gdl_elem_t link; /* in tree records */ +} altium_record_t; + +typedef struct altium_block_s { + gdl_elem_t link; /* in tree blocks */ + long size; /* allocated size of raw */ + char raw[1]; /* bytes read from the file */ +} altium_block_t; + +typedef struct altium_tree_s { + gdl_list_t rec[altium_kw_record_SPHASH_MAXVAL+1]; /* ordered list of records per type */ + gdl_list_t blocks; +} altium_tree_t; + +int pcbdoc_ascii_test_parse(pcb_plug_io_t *ctx, pcb_plug_iot_t typ, const char *file_name, FILE *f); +int pcbdoc_ascii_parse_file(rnd_hidlib_t *hidlib, altium_tree_t *tree, const char *fn); + +void altium_tree_free(altium_tree_t *tree); + Index: trunk/src_plugins/io_altium/altium_parser/plug_io.h =================================================================== --- trunk/src_plugins/io_altium/altium_parser/plug_io.h (nonexistent) +++ trunk/src_plugins/io_altium/altium_parser/plug_io.h (revision 35284) @@ -0,0 +1,29 @@ +#ifndef PLUG_IO_H +#define PLUG_IO_H +#include +#include +#include + +typedef struct { + int dummy; +} rnd_hidlib_t; + +typedef struct { + int dummy; +} pcb_plug_io_t; + +typedef enum { + pcb_plug_iot_dummy +} pcb_plug_iot_t; + +static inline long rnd_file_size(rnd_hidlib_t *hidlib, const char *path) +{ + struct stat st; + if (stat(path, &st) != 0) + return -1; + if (st.st_size > LONG_MAX) + return -1; + return st.st_size; +} + +#endif Index: work/alien_formats/altium_parser/altium_kw.sphash =================================================================== --- work/alien_formats/altium_parser/altium_kw.sphash (revision 35283) +++ work/alien_formats/altium_parser/altium_kw.sphash (nonexistent) @@ -1,16 +0,0 @@ -record - misc - board - class - net - component - polygon - arc - pad - via - track - text - componentbody -field - layer - locked Index: work/alien_formats/altium_parser/pcbdoc_ascii.c =================================================================== --- work/alien_formats/altium_parser/pcbdoc_ascii.c (revision 35283) +++ work/alien_formats/altium_parser/pcbdoc_ascii.c (nonexistent) @@ -1,288 +0,0 @@ -/* - * COPYRIGHT - * - * pcb-rnd, interactive printed circuit board design - * - * altium pcbdoc ASCII plugin - low level read: parse into a tree in mem - * pcb-rnd Copyright (C) 2021 Tibor 'Igor2' Palinkas - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Contact: - * Project page: http://repo.hu/projects/pcb-rnd - * lead developer: http://repo.hu/projects/pcb-rnd/contact.html - * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") - */ - -#include "config.h" - -#include -#include - -#include "pcbdoc_ascii.h" - -#define block_size 65536L - -/* optional trace */ -#if 0 -# define tprintf printf -#else - static int tprintf(const char *fmt, ...) { return 0; } -#endif - -int pcbdoc_ascii_test_parse(pcb_plug_io_t *ctx, pcb_plug_iot_t typ, const char *file_name, FILE *f) -{ - char line[256], *s; - - /* first line should comply to the low level file format */ - fgets(line, sizeof(line), f); - - s = line; - if (*s == '|') s++; - - /* every line must start with a RECORD field, the first one too */ - if (strncmp(s,"RECORD=", 7) != 0) - return 0; - - /* there must be a field separator */ - if (strchr(s, '|') == NULL) - return 0; - - return 1; -} - -static int pcbdoc_ascii_load_blocks(altium_tree_t *tree, FILE *f, long max) -{ - long curr = 0, next; - - for(;;) { - int c; - altium_block_t *blk; - - /* seek at potential end-of-block */ - next = curr + block_size; - if (next > max-1) - next = max-1; - fseek(f, next, SEEK_SET); - - /* seek first record separator (or eof) */ - for(;;) { - c = fgetc(f); - if (c == EOF) - break; - next++; - if ((c == '\r') || (c == '\n')) - break; - } - - if (c != EOF) { - /* seek end of record separator section (typica: \r\n) */ - for(;;) { - c = fgetc(f); - if (c == EOF) - break; - if ((c != '\r') && (c != '\n')) - break; - next++; - } - } - - if (next == curr) - break; - - /* by now "next" points to the first character of the next block */ - blk = malloc(sizeof(altium_block_t) + (next-curr) + 1); - if (blk == NULL) { - fprintf(stderr, "pcbdoc_ascii_load_blocks: failed to alloc memory\n"); - return -1; - } - memset(&blk->link, 0, sizeof(blk->link)); - blk->size = next-curr; - fseek(f, curr, SEEK_SET); - if (fread(&blk->raw, blk->size, 1, f) != 1) { - free(blk); - fprintf(stderr, "pcbdoc_ascii_load_blocks: can't read that many: %ld from %ld (%ld; max is %ld)\n", blk->size, curr, curr+blk->size, max); - return -1; - } - blk->raw[blk->size] = '\0'; - gdl_append(&tree->blocks, blk, link); -/* printf("curr=%ld next=%ld\n", curr, next);*/ - curr = next; - } - - return 0; -} - - -TODO("these two 'new' functions should use stack-slabs from umalloc") -static altium_record_t *pcbdoc_ascii_new_rec(altium_tree_t *tree, const char *type_s) -{ - altium_record_t *rec = calloc(sizeof(altium_record_t), 1); - int kw = altium_kw_sphash(type_s); - - if ((kw < altium_kw_record_SPHASH_MINVAL) || (kw > altium_kw_record_SPHASH_MAXVAL)) - kw = altium_kw_record_misc; - - rec->type = kw; - rec->type_s = type_s; - - gdl_append(&tree->rec[kw], rec, link); - - return rec; -} - -static altium_field_t *pcbdoc_ascii_new_field(altium_tree_t *tree, altium_record_t *rec, const char *key, const char *val) -{ - altium_field_t *field = calloc(sizeof(altium_field_t), 1); - int kw = altium_kw_sphash(key); - - if ((kw < altium_kw_field_SPHASH_MINVAL) || (kw > altium_kw_field_SPHASH_MAXVAL)) - kw = altium_kw_record_SPHASH_INVALID; - - field->type = kw; - field->key = key; - field->val = val; - - gdl_append(&rec->fields, field, link); - - return field; -} - -static int pcbdoc_ascii_parse_blocks(altium_tree_t *tree, const char *fn) -{ - altium_block_t *blk; - long line = 1; - - for(blk = gdl_first(&tree->blocks); blk != NULL; blk = gdl_next(&tree->blocks, blk)) { - char *s = blk->raw, *end; - - tprintf("---blk---\n"); - - for(;;) { /* parse each line within the block */ - altium_record_t *rec; - int nl = 0; - - /* ignore leading seps and newlines, exit if ran out of the string */ - while((*s == '|') || (*s == '\r') || (*s == '\n')) s++; - if (*s == '\0') - break; - - /* parse the record header */ - if (strncmp(s, "RECORD=", 7) != 0) { - fprintf(stderr, "First field must be record in %s:%ld\n", fn, line); - return -1; - } - s+=7; - end = strpbrk(s, "|\r\n"); - if (end == NULL) { - fprintf(stderr, "Unterminated record in %s:%ld\n", fn, line); - return -1; - } - *end = '\0'; - tprintf("rec='%s'\n", s); - rec = pcbdoc_ascii_new_rec(tree, s); - s = end+1; - - - /* parse fields */ - for(;;) { - char *key, *val; - - /* ignore leading seps and newlines, exit if ran out of the string */ - while(*s == '|') s++; - if (*s == '\0') - break; - - /* find sep */ - end = strpbrk(s, "|\r\n"); - if (end == NULL) { - fprintf(stderr, "Unterminated field in %s:%ld\n", fn, line); - return -1; - } - if (*end != '|') - nl = 1; - *end = '\0'; - - key = s; - val = strchr(s, '='); - if (val != NULL) { - *val = '\0'; - val++; - } - else - val = end; - - tprintf(" %s=%s\n", key, val); - pcbdoc_ascii_new_field(tree, rec, key, val); - s = end+1; - if (nl) - break; - } - } - } - - return 0; -} - -int pcbdoc_ascii_parse_file(rnd_hidlib_t *hidlib, altium_tree_t *tree, const char *fn) -{ - FILE *f; - int res; - long filesize; - - filesize = rnd_file_size(hidlib, fn); - if (filesize <= 0) - return -1; - - f = fopen(fn, "rb"); - if (f == NULL) - return -1; - - res = pcbdoc_ascii_load_blocks(tree, f, filesize); - fclose(f); - - if (res != 0) - return -1; - - - return pcbdoc_ascii_parse_blocks(tree, fn); -} - - -void altium_tree_free(altium_tree_t *tree) -{ - altium_block_t *blk; - altium_record_t *rec; - int n; - - for(blk = gdl_first(&tree->blocks); blk != NULL; blk = gdl_first(&tree->blocks)) { - gdl_remove(&tree->blocks, blk, link); - free(blk); - } - - for(n = 0; n < altium_kw_record_SPHASH_MAXVAL+1; n++) { - for(rec = gdl_first(&tree->rec[n]); rec != NULL; rec = gdl_first(&tree->rec[n])) { - altium_field_t *field; - - for(field = gdl_first(&rec->fields); field != NULL; field = gdl_first(&rec->fields)) { - gdl_remove(&rec->fields, field, link); - free(field); - } - gdl_remove(&tree->rec[n], rec, link); - free(rec); - } - } -} - Index: work/alien_formats/altium_parser/plug_io.h =================================================================== --- work/alien_formats/altium_parser/plug_io.h (revision 35283) +++ work/alien_formats/altium_parser/plug_io.h (nonexistent) @@ -1,29 +0,0 @@ -#ifndef PLUG_IO_H -#define PLUG_IO_H -#include -#include -#include - -typedef struct { - int dummy; -} rnd_hidlib_t; - -typedef struct { - int dummy; -} pcb_plug_io_t; - -typedef enum { - pcb_plug_iot_dummy -} pcb_plug_iot_t; - -static inline long rnd_file_size(rnd_hidlib_t *hidlib, const char *path) -{ - struct stat st; - if (stat(path, &st) != 0) - return -1; - if (st.st_size > LONG_MAX) - return -1; - return st.st_size; -} - -#endif Index: work/alien_formats/altium_parser/main.c =================================================================== --- work/alien_formats/altium_parser/main.c (revision 35283) +++ work/alien_formats/altium_parser/main.c (nonexistent) @@ -1,56 +0,0 @@ -#include -#include -#include "pcbdoc_ascii.h" - -static void dump_tree(altium_tree_t *tree) -{ - altium_record_t *rec; - int n; - - for(n = 0; n < altium_kw_record_SPHASH_MAXVAL+1; n++) { - printf("Records in %s:\n", altium_kw_keyname(n)); - for(rec = gdl_first(&tree->rec[n]); rec != NULL; rec = gdl_next(&tree->rec[n], rec)) { - altium_field_t *field; - printf(" %s\n", rec->type_s); - for(field = gdl_first(&rec->fields); field != NULL; field = gdl_next(&rec->fields, field)) { - printf(" %s=%s\n", field->key, field->val); - } - } - } -} - -int main(int argc, char *argv[]) -{ - const char *fn = "A.PcbDoc"; - FILE *f; - altium_tree_t tree = {0}; - int res; - - if (argc > 1) - fn = argv[1]; - - f = fopen(fn, "r"); - if (f == NULL) { - fprintf(stderr, "can't open %s for read\n", fn); - return -1; - } - res = pcbdoc_ascii_test_parse(NULL, 0, fn, f); - fclose(f); - - if (!res) { - fprintf(stderr, "test parse says '%s' is not a PcbDoc\n", fn); - return -1; - } - - if (pcbdoc_ascii_parse_file(NULL, &tree, fn) != 0) { - altium_tree_free(&tree); - fprintf(stderr, "failed to parse '%s'\n", fn); - return -1; - } - - - dump_tree(&tree); - - altium_tree_free(&tree); - return 0; -} Index: work/alien_formats/altium_parser/pcbdoc_ascii.h =================================================================== --- work/alien_formats/altium_parser/pcbdoc_ascii.h (revision 35283) +++ work/alien_formats/altium_parser/pcbdoc_ascii.h (nonexistent) @@ -1,34 +0,0 @@ -#include "plug_io.h" -#include -#include "altium_kw.h" - -typedef struct altium_field_s { - altium_kw_field_keys_t type; /* derived from ->key */ - const char *key; - const char *val; - gdl_elem_t link; /* in parent record */ -} altium_field_t; - -typedef struct altium_record_s { - altium_kw_record_keys_t type; /* derived from ->type_s */ - const char *type_s; - gdl_list_t fields; - gdl_elem_t link; /* in tree records */ -} altium_record_t; - -typedef struct altium_block_s { - gdl_elem_t link; /* in tree blocks */ - long size; /* allocated size of raw */ - char raw[1]; /* bytes read from the file */ -} altium_block_t; - -typedef struct altium_tree_s { - gdl_list_t rec[altium_kw_record_SPHASH_MAXVAL+1]; /* ordered list of records per type */ - gdl_list_t blocks; -} altium_tree_t; - -int pcbdoc_ascii_test_parse(pcb_plug_io_t *ctx, pcb_plug_iot_t typ, const char *file_name, FILE *f); -int pcbdoc_ascii_parse_file(rnd_hidlib_t *hidlib, altium_tree_t *tree, const char *fn); - -void altium_tree_free(altium_tree_t *tree); - Index: work/alien_formats/altium_parser/config.h =================================================================== --- work/alien_formats/altium_parser/config.h (revision 35283) +++ work/alien_formats/altium_parser/config.h (nonexistent) @@ -1,2 +0,0 @@ -#define TODO(s) - Index: work/alien_formats/altium_parser/Makefile =================================================================== --- work/alien_formats/altium_parser/Makefile (revision 35283) +++ work/alien_formats/altium_parser/Makefile (nonexistent) @@ -1,13 +0,0 @@ -SPHASH=src_3rd/sphash/sphash -CFLAGS = -Wall -g -Isrc_3rd - -main: main.o pcbdoc_ascii.o altium_kw.o - -main.o: main.c pcbdoc_ascii.h - -pcbdoc_ascii.o: pcbdoc_ascii.c pcbdoc_ascii.h - -altium_kw.c altium_kw.h: altium_kw.sphash - $(SPHASH) $(VERBOSE) -i --multi --prefix altium_kw --out altium_kw < altium_kw.sphash - -altium_kw.o: altium_kw.c altium_kw.h \ No newline at end of file