Index: trunk/src/paths.c =================================================================== --- trunk/src/paths.c (revision 4609) +++ trunk/src/paths.c (revision 4610) @@ -1,3 +1,30 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016 Tibor 'Igor2' Palinkas + * + * This module, rats.c, was written and is Copyright (C) 1997 by harry eaton + * this module is also subject to the GNU GPL as described below + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +/* Resolve paths, build paths using template */ +#include #include #include #include "config.h" @@ -5,6 +32,10 @@ #include "error.h" #include "conf_core.h" + +#include "board.h" +#include "compat_misc.h" + void resolve_paths(const char **in, char **out, int numpaths, unsigned int extra_room) { const char *subst_to; @@ -83,3 +114,79 @@ free(in); return out; } + +int pcb_build_fn_cb(void *ctx, gds_t *s, const char **input) +{ + char buff[20]; + + switch(**input) { + case 'P': + sprintf(buff, "%.8i", pcb_getpid()); + gds_append_str(s, buff); + (*input)++; + return 0; + case 'F': + gds_append_str(s, (PCB->Filename != NULL) ? PCB->Filename : "no_file_name"); + (*input)++; + return 0; + case 'B': + if (PCB->Filename != NULL) { + char *bn = strrchr(PCB->Filename, '/'); + if (bn != NULL) + bn++; + else + bn = PCB->Filename; + gds_append_str(s, bn); + } + else + gds_append_str(s, "no_file_name"); + (*input)++; + return 0; + case 'D': + if (PCB->Filename != NULL) { + char *bn = strrchr(PCB->Filename, '/'); + if (bn != NULL) + gds_append_len(s, PCB->Filename, bn-PCB->Filename+1); + else + gds_append_str(s, "./"); + } + else + gds_append_str(s, "./"); + (*input)++; + return 0; + case 'N': + gds_append_str(s, (PCB->Name != NULL) ? PCB->Name : "no_name"); + (*input)++; + return 0; + case 'T': + sprintf(buff, "%lu", (unsigned long int)time(NULL)); + gds_append_str(s, buff); + (*input)++; + return 0; + } + return -1; +} + +int pcb_build_argfn_cb(void *ctx_, gds_t *s, const char **input) +{ + if ((**input >= 'a') && (**input <= 'z')) { + int idx = **input - 'a'; + pcb_build_argfn_t *ctx = ctx_; + if (ctx->params[idx] == NULL) + return -1; + gds_append_str(s, ctx->params[idx]); + (*input)++; + return 0; + } + return pcb_build_fn_cb(NULL, s, input); +} + +char *pcb_build_fn(const char *template) +{ + return pcb_strdup_subst(template, pcb_build_fn_cb, NULL); +} + +char *pcb_build_argfn(const char *template, pcb_build_argfn_t *arg) +{ + return pcb_strdup_subst(template, pcb_build_argfn_cb, arg); +} Index: trunk/src/paths.h =================================================================== --- trunk/src/paths.h (revision 4609) +++ trunk/src/paths.h (revision 4610) @@ -1,4 +1,32 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016 Tibor 'Igor2' Palinkas + * + * This module, rats.c, was written and is Copyright (C) 1997 by harry eaton + * this module is also subject to the GNU GPL as described below + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ +/* Resolve paths, build paths using template */ + +#include "genvector/gds_char.h" + /* Allocate *out and copy the path from in to out, replacing ~ with conf_core.rc.path.home If extra_room is non-zero, allocate this many bytes extra for each slot; this leaves some room to append a file name. */ @@ -21,3 +49,28 @@ resolve_paths(in, out, __numpath__, extra_room); \ } \ } while(0) + + +/* generic file name template substitution callbacks for pcb_strdup_subst: + %P pid + %F load-time file name of the current pcb + %B basename (load-time file name of the current pcb without path) + %D dirname (load-time file path of the current pcb, without file name, with trailing slash, might be ./) + %N name of the current pcb + %T wall time (Epoch) +*/ +int pcb_build_fn_cb(void *ctx, gds_t *s, const char **input); + +char *pcb_build_fn(const char *template); + + +/* Same as above, but also replaces lower case formatting to the members of + the array if they are not NULL; use with pcb_build_argfn() */ +typedef struct { + const char *params['z' - 'a' + 1]; /* [0] for 'a' */ +} pcb_build_argfn_t; + +char *pcb_build_argfn(const char *template, pcb_build_argfn_t *arg); + +int pcb_build_argfn_cb(void *ctx, gds_t *s, const char **input); + Index: trunk/src/plug_io.c =================================================================== --- trunk/src/plug_io.c (revision 4609) +++ trunk/src/plug_io.c (revision 4610) @@ -43,13 +43,10 @@ #include #include -#include #include #include #include -#include "math_helper.h" -#include "buffer.h" #include "change.h" #include "data.h" #include "error.h" @@ -689,82 +686,6 @@ backup_timer = gui->add_timer(backup_cb, 1000 * conf_core.rc.backup_interval, x); } -int pcb_build_fn_cb(void *ctx, gds_t *s, const char **input) -{ - char buff[20]; - - switch(**input) { - case 'P': - sprintf(buff, "%.8i", pcb_getpid()); - gds_append_str(s, buff); - (*input)++; - return 0; - case 'F': - gds_append_str(s, (PCB->Filename != NULL) ? PCB->Filename : "no_file_name"); - (*input)++; - return 0; - case 'B': - if (PCB->Filename != NULL) { - char *bn = strrchr(PCB->Filename, '/'); - if (bn != NULL) - bn++; - else - bn = PCB->Filename; - gds_append_str(s, bn); - } - else - gds_append_str(s, "no_file_name"); - (*input)++; - return 0; - case 'D': - if (PCB->Filename != NULL) { - char *bn = strrchr(PCB->Filename, '/'); - if (bn != NULL) - gds_append_len(s, PCB->Filename, bn-PCB->Filename+1); - else - gds_append_str(s, "./"); - } - else - gds_append_str(s, "./"); - (*input)++; - return 0; - case 'N': - gds_append_str(s, (PCB->Name != NULL) ? PCB->Name : "no_name"); - (*input)++; - return 0; - case 'T': - sprintf(buff, "%lu", (unsigned long int)time(NULL)); - gds_append_str(s, buff); - (*input)++; - return 0; - } - return -1; -} - -int pcb_build_argfn_cb(void *ctx_, gds_t *s, const char **input) -{ - if ((**input >= 'a') && (**input <= 'z')) { - int idx = **input - 'a'; - pcb_build_argfn_t *ctx = ctx_; - if (ctx->params[idx] == NULL) - return -1; - gds_append_str(s, ctx->params[idx]); - (*input)++; - return 0; - } - return pcb_build_fn_cb(NULL, s, input); -} - -static char *build_fn(const char *template) -{ - return pcb_strdup_subst(template, pcb_build_fn_cb, NULL); -} - -char *pcb_build_argfn(const char *template, pcb_build_argfn_t *arg) -{ - return pcb_strdup_subst(template, pcb_build_argfn_cb, arg); -} - /* --------------------------------------------------------------------------- * creates backup file. The default is to use the pcb file name with * a "-" appended (like "foo.pcb-") and if we don't have a pcb file name @@ -784,7 +705,7 @@ } else { /* conf_core.rc.backup_name has %.8i which will be replaced by the process ID */ - filename = build_fn(conf_core.rc.backup_name); + filename = pcb_build_fn(conf_core.rc.backup_name); if (filename == NULL) { fprintf(stderr, "Backup(): can't build file name for a backup\n"); exit(1); @@ -804,7 +725,7 @@ */ void SaveTMPData(void) { - char *fn = build_fn(conf_core.rc.emergency_name); + char *fn = pcb_build_fn(conf_core.rc.emergency_name); WritePCBFile(fn, pcb_true, DEFAULT_FMT, pcb_true); if (TMPFilename != NULL) free(TMPFilename); Index: trunk/src/plug_io.h =================================================================== --- trunk/src/plug_io.h (revision 4609) +++ trunk/src/plug_io.h (revision 4610) @@ -157,26 +157,4 @@ } pcb_find_io_t; int pcb_find_io(pcb_find_io_t *available, int avail_len, plug_iot_t typ, int is_wr, const char *fmt); - -/* generic file name template substitution callbacks for pcb_strdup_subst: - %P pid - %F load-time file name of the current pcb - %B basename (load-time file name of the current pcb without path) - %D dirname (load-time file path of the current pcb, without file name, with trailing slash, might be ./) - %N name of the current pcb - %T wall time (Epoch) -*/ -int pcb_build_fn_cb(void *ctx, gds_t *s, const char **input); - - -/* Same as above, but also replaces lower case formatting to the members of - the array if they are not NULL; use with pcb_build_argfn() */ -typedef struct { - const char *params['z' - 'a' + 1]; /* [0] for 'a' */ -} pcb_build_argfn_t; - -char *pcb_build_argfn(const char *template, pcb_build_argfn_t *arg); - -int pcb_build_argfn_cb(void *ctx, gds_t *s, const char **input); - #endif Index: trunk/src_plugins/import_netlist/import_netlist.c =================================================================== --- trunk/src_plugins/import_netlist/import_netlist.c (revision 4609) +++ trunk/src_plugins/import_netlist/import_netlist.c (revision 4610) @@ -36,6 +36,7 @@ #include "rats_patch.h" #include "compat_misc.h" #include "compat_nls.h" +#include "paths.h" static plug_import_t import_netlist; Index: trunk/src_plugins/io_lihata/write.c =================================================================== --- trunk/src_plugins/io_lihata/write.c (revision 4609) +++ trunk/src_plugins/io_lihata/write.c (revision 4610) @@ -41,6 +41,7 @@ #include "common.h" #include "write_style.h" #include "io_lihata.h" +#include "paths.h" /*#define CFMT "%[9]"*/ #define CFMT "%.08$$mH" Index: trunk/src_plugins/io_pcb/parse_l.c =================================================================== --- trunk/src_plugins/io_pcb/parse_l.c (revision 4609) +++ trunk/src_plugins/io_pcb/parse_l.c (revision 4610) @@ -694,6 +694,7 @@ #include "compat_misc.h" #include "compat_cc.h" #include "obj_common.h" +#include "paths.h" #define YY_NO_INPUT @@ -725,7 +726,7 @@ */ static int Parse(FILE *Pipe, const char *Executable, const char *Path, const char *Filename); -#line 729 "parse_l.c" +#line 730 "parse_l.c" #define INITIAL 0 @@ -943,10 +944,10 @@ } { -#line 106 "parse_l.l" +#line 107 "parse_l.l" -#line 950 "parse_l.c" +#line 951 "parse_l.c" while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ { @@ -1015,227 +1016,227 @@ case 1: YY_RULE_SETUP -#line 108 "parse_l.l" +#line 109 "parse_l.l" { return(T_FILEVERSION); } YY_BREAK case 2: YY_RULE_SETUP -#line 109 "parse_l.l" +#line 110 "parse_l.l" { return(T_PCB); } YY_BREAK case 3: YY_RULE_SETUP -#line 110 "parse_l.l" +#line 111 "parse_l.l" { return(T_GRID); } YY_BREAK case 4: YY_RULE_SETUP -#line 111 "parse_l.l" +#line 112 "parse_l.l" { return(T_CURSOR); } YY_BREAK case 5: YY_RULE_SETUP -#line 112 "parse_l.l" +#line 113 "parse_l.l" { return(T_THERMAL); } YY_BREAK case 6: YY_RULE_SETUP -#line 113 "parse_l.l" +#line 114 "parse_l.l" { return(T_AREA); } YY_BREAK case 7: YY_RULE_SETUP -#line 114 "parse_l.l" +#line 115 "parse_l.l" { return(T_DRC); } YY_BREAK case 8: YY_RULE_SETUP -#line 115 "parse_l.l" +#line 116 "parse_l.l" { return(T_FLAGS); } YY_BREAK case 9: YY_RULE_SETUP -#line 116 "parse_l.l" +#line 117 "parse_l.l" { return(T_LAYER); } YY_BREAK case 10: YY_RULE_SETUP -#line 117 "parse_l.l" +#line 118 "parse_l.l" { return(T_PIN); } YY_BREAK case 11: YY_RULE_SETUP -#line 118 "parse_l.l" +#line 119 "parse_l.l" { return(T_PAD); } YY_BREAK case 12: YY_RULE_SETUP -#line 119 "parse_l.l" +#line 120 "parse_l.l" { return(T_VIA); } YY_BREAK case 13: YY_RULE_SETUP -#line 120 "parse_l.l" +#line 121 "parse_l.l" { return(T_LINE); } YY_BREAK case 14: YY_RULE_SETUP -#line 121 "parse_l.l" +#line 122 "parse_l.l" { return(T_RAT); } YY_BREAK case 15: YY_RULE_SETUP -#line 122 "parse_l.l" +#line 123 "parse_l.l" { return(T_RECTANGLE); } YY_BREAK case 16: YY_RULE_SETUP -#line 123 "parse_l.l" +#line 124 "parse_l.l" { return(T_TEXT); } YY_BREAK case 17: YY_RULE_SETUP -#line 124 "parse_l.l" +#line 125 "parse_l.l" { return(T_ELEMENTLINE); } YY_BREAK case 18: YY_RULE_SETUP -#line 125 "parse_l.l" +#line 126 "parse_l.l" { return(T_ELEMENTARC); } YY_BREAK case 19: YY_RULE_SETUP -#line 126 "parse_l.l" +#line 127 "parse_l.l" { return(T_ELEMENT); } YY_BREAK case 20: YY_RULE_SETUP -#line 127 "parse_l.l" +#line 128 "parse_l.l" { return(T_SYMBOLLINE); } YY_BREAK case 21: YY_RULE_SETUP -#line 128 "parse_l.l" +#line 129 "parse_l.l" { return(T_SYMBOL); } YY_BREAK case 22: YY_RULE_SETUP -#line 129 "parse_l.l" +#line 130 "parse_l.l" { return(T_MARK); } YY_BREAK case 23: YY_RULE_SETUP -#line 130 "parse_l.l" +#line 131 "parse_l.l" { return(T_GROUPS); } YY_BREAK case 24: YY_RULE_SETUP -#line 131 "parse_l.l" +#line 132 "parse_l.l" { return(T_STYLES); } YY_BREAK case 25: YY_RULE_SETUP -#line 132 "parse_l.l" +#line 133 "parse_l.l" { return(T_POLYGON); } YY_BREAK case 26: YY_RULE_SETUP -#line 133 "parse_l.l" +#line 134 "parse_l.l" { return(T_POLYGON_HOLE); } YY_BREAK case 27: YY_RULE_SETUP -#line 134 "parse_l.l" +#line 135 "parse_l.l" { return(T_ARC); } YY_BREAK case 28: YY_RULE_SETUP -#line 135 "parse_l.l" +#line 136 "parse_l.l" { return(T_NETLIST); } YY_BREAK case 29: YY_RULE_SETUP -#line 136 "parse_l.l" +#line 137 "parse_l.l" { return(T_NET); } YY_BREAK case 30: YY_RULE_SETUP -#line 137 "parse_l.l" +#line 138 "parse_l.l" { return(T_CONN); } YY_BREAK case 31: YY_RULE_SETUP -#line 138 "parse_l.l" +#line 139 "parse_l.l" { return(T_NETLISTPATCH); } YY_BREAK case 32: YY_RULE_SETUP -#line 139 "parse_l.l" +#line 140 "parse_l.l" { return(T_ADD_CONN); } YY_BREAK case 33: YY_RULE_SETUP -#line 140 "parse_l.l" +#line 141 "parse_l.l" { return(T_DEL_CONN); } YY_BREAK case 34: YY_RULE_SETUP -#line 141 "parse_l.l" +#line 142 "parse_l.l" { return(T_CHANGE_ATTRIB); } YY_BREAK case 35: YY_RULE_SETUP -#line 142 "parse_l.l" +#line 143 "parse_l.l" { return(T_ATTRIBUTE); } YY_BREAK case 36: YY_RULE_SETUP -#line 144 "parse_l.l" +#line 145 "parse_l.l" { return T_NM; } YY_BREAK case 37: YY_RULE_SETUP -#line 145 "parse_l.l" +#line 146 "parse_l.l" { return T_UM; } YY_BREAK case 38: YY_RULE_SETUP -#line 146 "parse_l.l" +#line 147 "parse_l.l" { return T_MM; } YY_BREAK case 39: YY_RULE_SETUP -#line 147 "parse_l.l" +#line 148 "parse_l.l" { return T_M; } YY_BREAK case 40: YY_RULE_SETUP -#line 148 "parse_l.l" +#line 149 "parse_l.l" { return T_KM; } YY_BREAK case 41: YY_RULE_SETUP -#line 149 "parse_l.l" +#line 150 "parse_l.l" { return T_UMIL; } YY_BREAK case 42: YY_RULE_SETUP -#line 150 "parse_l.l" +#line 151 "parse_l.l" { return T_CMIL; } YY_BREAK case 43: YY_RULE_SETUP -#line 151 "parse_l.l" +#line 152 "parse_l.l" { return T_MIL; } YY_BREAK case 44: YY_RULE_SETUP -#line 152 "parse_l.l" +#line 153 "parse_l.l" { return T_IN; } YY_BREAK case 45: YY_RULE_SETUP -#line 154 "parse_l.l" +#line 155 "parse_l.l" { pcb_lval.integer = (unsigned) *(pcb_text+1); return(CHAR_CONST); @@ -1243,17 +1244,17 @@ YY_BREAK case 46: YY_RULE_SETUP -#line 158 "parse_l.l" +#line 159 "parse_l.l" { return parse_number(); } YY_BREAK case 47: YY_RULE_SETUP -#line 159 "parse_l.l" +#line 160 "parse_l.l" { pcb_lval.integer = pcb_round (strtod (pcb_text, NULL)); return INTEGER; } YY_BREAK case 48: YY_RULE_SETUP -#line 161 "parse_l.l" +#line 162 "parse_l.l" { unsigned n; sscanf((char *) pcb_text, "%x", &n); pcb_lval.integer = n; @@ -1262,7 +1263,7 @@ YY_BREAK case 49: YY_RULE_SETUP -#line 166 "parse_l.l" +#line 167 "parse_l.l" { char *p1, *p2; @@ -1298,18 +1299,18 @@ YY_BREAK case 50: YY_RULE_SETUP -#line 198 "parse_l.l" +#line 199 "parse_l.l" {} YY_BREAK case 51: YY_RULE_SETUP -#line 199 "parse_l.l" +#line 200 "parse_l.l" {} YY_BREAK case 52: /* rule 52 can match eol */ YY_RULE_SETUP -#line 200 "parse_l.l" +#line 201 "parse_l.l" { #ifndef FLEX_SCANNER pcb_lineno++; @@ -1318,20 +1319,20 @@ YY_BREAK case 53: YY_RULE_SETUP -#line 205 "parse_l.l" +#line 206 "parse_l.l" {} YY_BREAK case 54: YY_RULE_SETUP -#line 206 "parse_l.l" +#line 207 "parse_l.l" { return(*pcb_text); } YY_BREAK case 55: YY_RULE_SETUP -#line 208 "parse_l.l" +#line 209 "parse_l.l" ECHO; YY_BREAK -#line 1335 "parse_l.c" +#line 1336 "parse_l.c" case YY_STATE_EOF(INITIAL): yyterminate(); @@ -2344,7 +2345,7 @@ #define YYTABLES_NAME "yytables" -#line 208 "parse_l.l" +#line 209 "parse_l.l" Index: trunk/src_plugins/io_pcb/parse_l.h =================================================================== --- trunk/src_plugins/io_pcb/parse_l.h (revision 4609) +++ trunk/src_plugins/io_pcb/parse_l.h (revision 4610) @@ -315,7 +315,7 @@ #undef YY_DECL #endif -#line 208 "parse_l.l" +#line 209 "parse_l.l" #line 322 "parse_l.h" Index: trunk/src_plugins/io_pcb/parse_l.l =================================================================== --- trunk/src_plugins/io_pcb/parse_l.l (revision 4609) +++ trunk/src_plugins/io_pcb/parse_l.l (revision 4610) @@ -60,6 +60,7 @@ #include "compat_misc.h" #include "compat_cc.h" #include "obj_common.h" +#include "paths.h" #define YY_NO_INPUT