Index: trunk/scconfig/Rev.h =================================================================== --- trunk/scconfig/Rev.h (revision 31007) +++ trunk/scconfig/Rev.h (revision 31008) @@ -1 +1 @@ -static const int myrev = 31003; +static const int myrev = 31008; Index: trunk/scconfig/Rev.tab =================================================================== --- trunk/scconfig/Rev.tab (revision 31007) +++ trunk/scconfig/Rev.tab (revision 31008) @@ -1,4 +1,4 @@ -31003 configure pcb_ -> rnd_ renames in librnd +31008 configure pcb_ -> rnd_ renames in librnd 30779 configure remove distaligntext - all cases handled by distalign properly 30754 configure remove the old import_sch plugin (in favor of import_sch2) 30753 configure disable the old drc, enable the new drc Index: trunk/src/Makefile.in =================================================================== --- trunk/src/Makefile.in (revision 31007) +++ trunk/src/Makefile.in (revision 31008) @@ -96,7 +96,7 @@ $(LIBRND)/core/misc_util.o $(LIBRND)/core/paths.o $(LIBRND)/core/pcb_bool.o - $(LIBRND)/core/pcb-printf.o + $(LIBRND)/core/rnd_printf.o $(LIBRND)/core/plugins.o $(LIBRND)/core/pixmap.o $(LIBRND)/core/safe_fs.o Index: trunk/src/actions_pcb.c =================================================================== --- trunk/src/actions_pcb.c (revision 31007) +++ trunk/src/actions_pcb.c (revision 31008) @@ -40,7 +40,7 @@ #include "layer_addr.h" #include "undo.h" #include "change.h" -#include +#include #include "conf_core.h" const char *PCB_PTR_DOMAIN_LAYER = "pcb_fgw_ptr_domain_layer"; Index: trunk/src/idpath.c =================================================================== --- trunk/src/idpath.c (revision 31007) +++ trunk/src/idpath.c (revision 31008) @@ -39,7 +39,7 @@ #include "board.h" #include "data.h" #include "layer.h" -#include +#include static int idpath_map(pcb_idpath_t *idp, pcb_any_obj_t *obj, int level, int *numlevels) { Index: trunk/src/layer_grp.c =================================================================== --- trunk/src/layer_grp.c (revision 31007) +++ trunk/src/layer_grp.c (revision 31008) @@ -32,7 +32,7 @@ #include "data.h" #include "layer_grp.h" #include -#include +#include #include "event.h" #include #include "funchash_core.h" Index: trunk/src/librnd/core/pcb-printf.c =================================================================== --- trunk/src/librnd/core/pcb-printf.c (revision 31007) +++ trunk/src/librnd/core/pcb-printf.c (nonexistent) @@ -1,918 +0,0 @@ -/* - * COPYRIGHT - * - * pcb-rnd, interactive printed circuit board design - * (this file is based on PCB, interactive printed circuit board design) - * Copyright (C) 2011 Andrew Poelstra - * Copyright (C) 2016,2019 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") - * - * - * Old contact info: - * Andrew Poelstra, 16966 60A Ave, V3S 8X5 Surrey, BC, Canada - * asp11@sfu.ca - * - */ - -/* Implementation of printf wrapper to output pcb coords and angles - * For details of all supported specifiers, see the comment at the - * top of pcb-printf.h */ - -#include -#include -#include -#include -#include - -const char *rnd_printf_slot[RND_PRINTF_SLOT_max] = -{ - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 8 user formats */ - "%mr", /* original unitless cmil file format coord */ - "%.07$$mS" /* safe file format coord */ -}; - -static int min_sig_figs(double d) -{ - char buf[50]; - int rv; - - if (d == 0) - return 0; - - /* Normalize to x.xxxx... form */ - if (d < 0) - d *= -1; - while (d >= 10) - d /= 10; - while (d < 1) - d *= 10; - - rv = sprintf(buf, "%g", d); - return rv; -} - -/* Truncate trailing 0's from str */ -static int do_trunc0(char *str) -{ - char *end = str + strlen(str) - 1; - while((end > str) && (*end == '0') && (end[-1] != '.')) { - *end = '\0'; - end--; - } - return end-str+1; -} - - -/* Create sprintf specifier, using default_prec no precision is given */ -static inline void make_printf_spec(char *printf_spec_new, const char *printf_spec, int precision, int *trunc0) -{ - int i = 0; - - *trunc0 = 0; - - while (printf_spec[i] == '%' || isdigit(printf_spec[i]) || - printf_spec[i] == '-' || printf_spec[i] == '+' || printf_spec[i] == '#' || printf_spec[i] == '0') - ++i; - - if (printf_spec[i] == '.') { - if ((printf_spec[i+1] == '0') && (isdigit(printf_spec[i+2]))) - *trunc0 = 1; - sprintf(printf_spec_new, ", %sf", printf_spec); - } - else - sprintf(printf_spec_new, ", %s.%df", printf_spec, precision); -} - -/* sprintf a value (used to change locale on is_file_mode) */ -#define sprintf_lc_safe(is_file_mode, out, fmt, val) \ -do { \ - sprintf(out, fmt, val); \ - if (trunc0) \ - do_trunc0(filemode_buff); \ -} while(0) - -/* append a suffix, with or without space */ -static int inline append_suffix(gds_t *dest, enum pcb_suffix_e suffix_type, const char *suffix) -{ - switch (suffix_type) { - case PCB_UNIT_NO_SUFFIX: - break; - case PCB_UNIT_SUFFIX: - if (gds_append(dest, ' ') != 0) return -1; - /* deliberate fall-thru */ - case PCB_UNIT_FILE_MODE: - if (gds_append_str(dest, suffix) != 0) return -1; - break; - } - return 0; -} - - -/* Internal coord-to-string converter for pcb-printf - * Converts a (group of) measurement(s) to a comma-delimited - * string, with appropriate units. If more than one coord is - * given, the list is enclosed in parens to make the scope of - * the unit suffix clear. - * - * dest Append the output to this dynamic string - * coord Array of coords to convert - * n_coords Number of coords in array - * printf_spec printf sub-specifier to use with %f - * e_allow Bitmap of units the function may use - * suffix_type Whether to add a suffix - * - * return 0 on success, -1 on error - */ -static int CoordsToString(gds_t *dest, rnd_coord_t coord[], int n_coords, const gds_t *printf_spec_, enum pcb_allow_e allow, - enum pcb_suffix_e suffix_type) -{ - char filemode_buff[128]; /* G_ASCII_DTOSTR_BUF_SIZE */ - char printf_spec_new_local[256]; - double *value, value_local[32]; - enum pcb_family_e family; - const char *suffix; - int i, n, retval = -1, trunc0 = 0; - const char *printf_spec = printf_spec_->array; - char *printf_spec_new; - - if (n_coords > (sizeof(value_local) / sizeof(value_local[0]))) { - value = malloc(n_coords * sizeof *value); - if (value == NULL) - return -1; - } - else - value = value_local; - - if (allow == 0) - allow = PCB_UNIT_ALLOW_ALL_SANE; - - i = printf_spec_->used + 64; - if (i > sizeof(printf_spec_new_local)) - printf_spec_new = malloc(i); - else - printf_spec_new = printf_spec_new_local; - - /* Check our freedom in choosing units */ - if ((allow & PCB_UNIT_ALLOW_IMPERIAL) == 0) - family = PCB_UNIT_METRIC; - else if ((allow & PCB_UNIT_ALLOW_METRIC) == 0) - family = PCB_UNIT_IMPERIAL; - else { - int met_votes = 0, imp_votes = 0; - - for (i = 0; i < n_coords; ++i) - if (min_sig_figs(PCB_COORD_TO_MIL(coord[i])) < min_sig_figs(PCB_COORD_TO_MM(coord[i]))) - ++imp_votes; - else - ++met_votes; - - if (imp_votes > met_votes) - family = PCB_UNIT_IMPERIAL; - else - family = PCB_UNIT_METRIC; - } - - /* Set base unit */ - for (i = 0; i < n_coords; ++i) { - switch (family) { - case PCB_UNIT_METRIC: - value[i] = PCB_COORD_TO_MM(coord[i]); - break; - case PCB_UNIT_IMPERIAL: - value[i] = PCB_COORD_TO_MIL(coord[i]); - break; - default: - value[i] = 0; - } - } - - /* Determine scale factor -- find smallest unit that brings - * the whole group above unity */ - for (n = 0; n < pcb_get_n_units(0); ++n) { - if ((pcb_units[n].allow & allow) != 0 && (pcb_units[n].family == family)) { - int n_above_one = 0; - - for (i = 0; i < n_coords; ++i) - if (fabs(value[i] * pcb_units[n].scale_factor) > 1) - ++n_above_one; - if (n_above_one == n_coords) - break; - } - } - /* If nothing worked, wind back to the smallest allowable unit */ - if (n == pcb_get_n_units(0)) { - do { - --n; - } while ((n>=0) && ((pcb_units[n].allow & allow) == 0 || pcb_units[n].family != family)); - } - - /* Apply scale factor */ - suffix = pcb_units[n].suffix; - for (i = 0; i < n_coords; ++i) - value[i] = value[i] * pcb_units[n].scale_factor; - - make_printf_spec(printf_spec_new, printf_spec, pcb_units[n].default_prec, &trunc0); - - /* Actually sprintf the values in place - * (+ 2 skips the ", " for first value) */ - if (n_coords > 1) - if (gds_append(dest, '(') != 0) - goto err; - - sprintf_lc_safe((suffix_type == PCB_UNIT_FILE_MODE), filemode_buff, printf_spec_new + 2, value[0]); - if (gds_append_str(dest, filemode_buff) != 0) - goto err; - - for (i = 1; i < n_coords; ++i) { - sprintf_lc_safe((suffix_type == PCB_UNIT_FILE_MODE), filemode_buff, printf_spec_new, value[i]); - if (gds_append_str(dest, filemode_buff) != 0) - goto err; - } - if (n_coords > 1) - if (gds_append(dest, ')') != 0) goto err; - - - /* Append suffix */ - if (value[0] != 0 || n_coords > 1) - if (append_suffix(dest, suffix_type, suffix) != 0) - goto err; - - retval = 0; -err:; - if (printf_spec_new != printf_spec_new_local) - free(printf_spec_new); - - if (value != value_local) - free(value); - return retval; -} - -typedef struct { - int score_factor; - - enum pcb_allow_e base; - double down_limit; - enum pcb_allow_e down; - double up_limit; - enum pcb_allow_e up; - - /* persistent, calculated once */ - const rnd_unit_t *base_unit, *down_unit, *up_unit; -} human_coord_t; - -/* Conversion preference table */ -static human_coord_t human_coord[] = { - {2, PCB_UNIT_ALLOW_MM, 0.001, PCB_UNIT_ALLOW_UM, 1000.0, PCB_UNIT_ALLOW_M ,NULL,NULL,NULL}, - {1, PCB_UNIT_ALLOW_MIL, 0, 0, 1000.0, PCB_UNIT_ALLOW_IN ,NULL,NULL,NULL} -}; -#define NUM_HUMAN_COORD (sizeof(human_coord) / sizeof(human_coord[0])) - -static inline int try_human_coord(rnd_coord_t coord, const rnd_unit_t *unit, double down_limit, double up_limit, int score_factor, double *value, unsigned int *best, const char **suffix) -{ - double v, frac, save; - long int digs, zeros; - unsigned int score; - - /* convert the value to the proposed unit */ - if (unit->family == PCB_UNIT_METRIC) - v = PCB_COORD_TO_MM(coord); - else - v = PCB_COORD_TO_MIL(coord); - save = v = v * unit->scale_factor; - if (v < 0) v = -v; - - /* Check if neighbour units are better */ - if ((down_limit > 0) && (v < down_limit)) - return -1; - if ((up_limit > 0) && (v > up_limit)) - return +1; - - /* count trailing zeros after the decimal point up to 8 digits */ - frac = v - floor(v); - digs = frac * 100000000.0; - if (digs != 0) - for(zeros = 0; (digs % 10) == 0; zeros++, digs /= 10); - else - zeros = 8; - - /* score is higher for more zeroes */ - score = score_factor + 8 * zeros; - -/* printf("try: %s '%.8f' -> %.8f %d score=%d\n", unit->suffix, v, frac, zeros, score);*/ - - /* update the best score */ - if (score > *best) { - *value = save; - *best = score; - *suffix = unit->suffix; - } - - return 0; -} - -/* Same as CoordsToString but take only one coord and print it in human readable format */ -static int CoordsToHumanString(gds_t *dest, rnd_coord_t coord, const gds_t *printf_spec_, enum pcb_suffix_e suffix_type) -{ - char filemode_buff[128]; /* G_ASCII_DTOSTR_BUF_SIZE */ - char printf_spec_new_local[256]; - char *printf_spec_new; - int i, retval = -1, trunc0; - const char *printf_spec = printf_spec_->array; - const char *suffix; - double value; - unsigned int best_score = 0; - - i = printf_spec_->used + 64; - if (i > sizeof(printf_spec_new_local)) - printf_spec_new = malloc(i); - else - printf_spec_new = printf_spec_new_local; - - /* cache unit lookup */ - if (human_coord[0].base_unit == NULL) { - for(i = 0; i < NUM_HUMAN_COORD; i++) { - human_coord[i].base_unit = get_unit_struct_by_allow(human_coord[i].base); - human_coord[i].down_unit = get_unit_struct_by_allow(human_coord[i].down); - human_coord[i].up_unit = get_unit_struct_by_allow(human_coord[i].up); - } - } - - for(i = 0; i < NUM_HUMAN_COORD; i++) { - int res; - /* try the base units first */ - res = try_human_coord(coord, human_coord[i].base_unit, human_coord[i].down_limit, human_coord[i].up_limit, human_coord[i].score_factor,&value, &best_score, &suffix); - if (res < 0) - try_human_coord(coord, human_coord[i].down_unit, 0, 0, human_coord[i].score_factor, &value, &best_score, &suffix); - else if (res > 0) - try_human_coord(coord, human_coord[i].up_unit, 0, 0, human_coord[i].score_factor,&value, &best_score, &suffix); - } - - make_printf_spec(printf_spec_new, printf_spec, 8, &trunc0); - sprintf_lc_safe((suffix_type == PCB_UNIT_FILE_MODE), filemode_buff, printf_spec_new + 2, value); - if (gds_append_str(dest, filemode_buff) != 0) - goto err; - - if (value != 0) { - if (suffix_type == PCB_UNIT_NO_SUFFIX) - suffix_type = PCB_UNIT_SUFFIX; - if (append_suffix(dest, suffix_type, suffix) != 0) - goto err; - } - - err:; - if (printf_spec_new != printf_spec_new_local) - free(printf_spec_new); - return retval; -} - -int QstringToString(gds_t *dest, const char *qstr, char q, char esc, const char *needq) -{ - const char *s; - - if ((qstr == NULL) || (*qstr == '\0')) { - gds_append(dest, q); - gds_append(dest, q); - return 0; - } - - /* check if quoting is needed */ - if (strpbrk(qstr, needq) == NULL) { - gds_append_str(dest, qstr); - return 0; - } - - /* wrap in quotes and protect escape and quote chars */ - gds_append(dest, q); - for(s = qstr; *s != '\0'; s++) { - if ((*s == esc) || (*s == q)) - gds_append(dest, esc); - gds_append(dest, *s); - } - gds_append(dest, q); - return 0; -} - -/* Main low level pcb-printf function - * This is a printf wrapper that accepts new format specifiers to - * output pcb coords as various units. See the comment at the top - * of pcb-printf.h for full details. - * - * [in] string Append anything new at the end of this dynamic string (must be initialized before the call) - * [in] fmt Format specifier - * [in] args Arguments to specifier - * - * return 0 on success */ -int rnd_safe_append_vprintf(gds_t *string, rnd_safe_printf_t safe, const char *fmt, va_list args) -{ - gds_t spec; - const char *qstr, *needsq; - char tmp[128]; /* large enough for rendering a long long int */ - int tmplen, retval = -1, slot_recursion = 0, mq_has_spec; - char *dot, *free_fmt = NULL; - enum pcb_allow_e mask = PCB_UNIT_ALLOW_ALL_SANE; - unsigned long maxfmts; - - if ((safe & PCB_SAFEPRINT_arg_max) > 0) - maxfmts = (safe & PCB_SAFEPRINT_arg_max); - else - maxfmts = 1UL<<31; - - gds_init(&spec); - - new_fmt:; - while (*fmt) { - enum pcb_suffix_e suffix = PCB_UNIT_NO_SUFFIX; - - if (*fmt == '%') { - const char *ext_unit = ""; - rnd_coord_t value[10]; - int count, i; - - gds_truncate(&spec, 0); - mq_has_spec = 0; - - /* Get printf sub-specifiers */ - if (gds_append(&spec, *fmt++) != 0) goto err; - while (isdigit(*fmt) || *fmt == '.' || *fmt == ' ' || *fmt == '*' - || *fmt == '#' || *fmt == 'l' || *fmt == 'L' || *fmt == 'h' - || *fmt == '+' || *fmt == '-' || *fmt == '[' || *fmt == '{') { - if (*fmt == '*') { - char itmp[32]; - int ilen; - ilen = sprintf(itmp, "%d", va_arg(args, int)); - if (gds_append_len(&spec, itmp, ilen) != 0) goto err; - fmt++; - } - else - if (gds_append(&spec, *fmt++) != 0) goto err; - } - - /* check if specifier is %[] */ - if ((gds_len(&spec) > 2) && (spec.array[1] == '[')) { - int slot = atoi(spec.array+2); - gds_t new_spec; - if ((slot < 0) || (slot > RND_PRINTF_SLOT_max)) { - fprintf(stderr, "Internal error: invalid printf slot addressed: '%s'\n", spec.array); - abort(); - } - slot_recursion++; - if (slot_recursion > 16) { - fprintf(stderr, "Internal error: printf slot recursion too deep on addressed: '%s'\n", spec.array); - abort(); - } - if (rnd_printf_slot[slot] == NULL) { - fprintf(stderr, "Internal error: printf empty slot reference: '%s'\n", spec.array); - abort(); - } - gds_init(&new_spec); - gds_append_str(&new_spec, rnd_printf_slot[slot]); - if (*fmt == ']') - fmt++; - gds_append_str(&new_spec, fmt); - if (free_fmt != NULL) - free(free_fmt); - fmt = free_fmt = new_spec.array; - memset(&new_spec, 0, sizeof(new_spec)); - gds_truncate(&spec, 0); - goto new_fmt; - } - if ((spec.array[0] == '%') && (spec.array[1] == '{')) { - /* {} specifier for %mq */ - const char *end; - gds_truncate(&spec, 0); - for(end = fmt; *end != '\0'; end++) { - if ((end[0] != '\\') && (end[1] == '}')) { - end++; - break; - } - } - if (*end == '\0') - goto err; - gds_append_len(&spec, fmt, end-fmt); - fmt = end+1; - mq_has_spec = 1; - } - else - slot_recursion = 0; - - /* Get our sub-specifiers */ - if (*fmt == '#') { - mask = PCB_UNIT_ALLOW_CMIL; /* This must be pcb's base unit */ - fmt++; - } - if (*fmt == '$') { - suffix = PCB_UNIT_SUFFIX; - fmt++; - if (*fmt == '$') { - fmt++; - suffix = PCB_UNIT_FILE_MODE; - } - } - - if (maxfmts == 0) - return -1; - maxfmts--; - - /* Tack full specifier onto specifier */ - if (*fmt != 'm') - if (gds_append(&spec, *fmt) != 0) goto err; - switch (*fmt) { - /* Printf specs */ - case 'o': - case 'i': - case 'd': - case 'u': - case 'x': - case 'X': - if (safe & PCB_SAFEPRINT_COORD_ONLY) - return -1; - if (spec.array[1] == 'l') - tmplen = sprintf(tmp, spec.array, va_arg(args, long)); - else - tmplen = sprintf(tmp, spec.array, va_arg(args, int)); - if (gds_append_len(string, tmp, tmplen) != 0) goto err; - break; - case 'e': - case 'E': - case 'f': - case 'g': - case 'G': - if (safe & PCB_SAFEPRINT_COORD_ONLY) - return -1; - if (strchr(spec.array, '*')) { - int prec = va_arg(args, int); - tmplen = sprintf(tmp, spec.array, va_arg(args, double), prec); - } - else - tmplen = sprintf(tmp, spec.array, va_arg(args, double)); - if (gds_append_len(string, tmp, tmplen) != 0) goto err; - break; - case 'c': - if (safe & PCB_SAFEPRINT_COORD_ONLY) - return -1; - if (spec.array[1] == 'l' && sizeof(int) <= sizeof(wchar_t)) - tmplen = sprintf(tmp, spec.array, va_arg(args, wchar_t)); - else - tmplen = sprintf(tmp, spec.array, va_arg(args, int)); - if (gds_append_len(string, tmp, tmplen) != 0) goto err; - break; - case 's': - if (safe & PCB_SAFEPRINT_COORD_ONLY) - return -1; - if (spec.array[0] == 'l') { - /* TODO: convert wchar to char and append it */ - fprintf(stderr, "Internal error: appending %%ls is not supported\n"); - abort(); - } - else { - const char *s = va_arg(args, const char *); - if (s == NULL) s = "(null)"; - if (gds_append_str(string, s) != 0) goto err; - } - break; - case 'n': - if (safe & PCB_SAFEPRINT_COORD_ONLY) - return -1; - /* Depending on gcc settings, this will probably break with - * some silly "can't put %n in writable data space" message */ - tmplen = sprintf(tmp, spec.array, va_arg(args, int *)); - if (gds_append_len(string, tmp, tmplen) != 0) goto err; - break; - case 'p': - if (safe & PCB_SAFEPRINT_COORD_ONLY) - return -1; - tmplen = sprintf(tmp, spec.array, va_arg(args, void *)); - if (gds_append_len(string, tmp, tmplen) != 0) goto err; - break; - case '%': - if (gds_append(string, '%') != 0) goto err; - break; - /* Our specs */ - case 'm': - ++fmt; - if (*fmt == '*') - ext_unit = va_arg(args, const char *); - if (*fmt != '+' && *fmt != 'a' && *fmt != 'A' && *fmt != 'f' && *fmt != 'q') - value[0] = va_arg(args, rnd_coord_t); - count = 1; - switch (*fmt) { - case 'q': - qstr = va_arg(args, const char *); - if (mq_has_spec) - needsq = spec.array; - else - needsq = " \"\\"; - if (QstringToString(string, qstr, '"', '\\', needsq) != 0) goto err; - break; - case 'I': - if (CoordsToString(string, value, 1, &spec, PCB_UNIT_ALLOW_NM, PCB_UNIT_NO_SUFFIX) != 0) goto err; - break; - case 's': - if (CoordsToString(string, value, 1, &spec, PCB_UNIT_ALLOW_MM | PCB_UNIT_ALLOW_MIL, suffix) != 0) goto err; - break; - case 'S': - if (CoordsToString(string, value, 1, &spec, mask & PCB_UNIT_ALLOW_NATURAL, suffix) != 0) goto err; - break; - case 'N': - if (CoordsToString(string, value, 1, &spec, mask, suffix) != 0) goto err; - break; - case 'H': - if ((safe & PCB_SAFEPRINT_COORD_ONLY) && (value[0] > 1)) - return -1; - if (CoordsToHumanString(string, value[0], &spec, suffix) != 0) goto err; - break; - case 'M': - if (CoordsToString(string, value, 1, &spec, mask & PCB_UNIT_ALLOW_METRIC, suffix) != 0) goto err; - break; - case 'L': - if (CoordsToString(string, value, 1, &spec, mask & PCB_UNIT_ALLOW_IMPERIAL, suffix) != 0) goto err; - break; - case 'k': - if (CoordsToString(string, value, 1, &spec, PCB_UNIT_ALLOW_DMIL, suffix) != 0) goto err; - break; - case 'r': - if (CoordsToString(string, value, 1, &spec, PCB_UNIT_ALLOW_READABLE, PCB_UNIT_NO_SUFFIX) != 0) goto err; - break; - /* All these fallthroughs are deliberate */ - case '9': - value[count++] = va_arg(args, rnd_coord_t); - case '8': - value[count++] = va_arg(args, rnd_coord_t); - case '7': - value[count++] = va_arg(args, rnd_coord_t); - case '6': - value[count++] = va_arg(args, rnd_coord_t); - case '5': - value[count++] = va_arg(args, rnd_coord_t); - case '4': - value[count++] = va_arg(args, rnd_coord_t); - case '3': - value[count++] = va_arg(args, rnd_coord_t); - case '2': - case 'D': - if (safe & PCB_SAFEPRINT_COORD_ONLY) - return -1; - value[count++] = va_arg(args, rnd_coord_t); - if (CoordsToString(string, value, count, &spec, mask & PCB_UNIT_ALLOW_ALL_SANE, suffix) != 0) goto err; - break; - case 'd': - if (safe & PCB_SAFEPRINT_COORD_ONLY) - return -1; - value[1] = va_arg(args, rnd_coord_t); - if (CoordsToString(string, value, 2, &spec, PCB_UNIT_ALLOW_MM | PCB_UNIT_ALLOW_MIL, suffix) != 0) goto err; - break; - case '*': - { - int found = 0; - for (i = 0; i < pcb_get_n_units(1); ++i) { - if (strcmp(ext_unit, pcb_units[i].suffix) == 0) { - if (CoordsToString(string, value, 1, &spec, pcb_units[i].allow, suffix) != 0) goto err; - found = 1; - break; - } - } - if (!found) - if (CoordsToString(string, value, 1, &spec, mask & PCB_UNIT_ALLOW_ALL_SANE, suffix) != 0) goto err; - } - break; - case 'a': - if (safe & PCB_SAFEPRINT_COORD_ONLY) - return -1; - if (gds_append_len(&spec, ".06f", 4) != 0) goto err; - if (suffix == PCB_UNIT_SUFFIX) - if (gds_append_len(&spec, " deg", 4) != 0) goto err; - tmplen = sprintf(tmp, spec.array, (double) va_arg(args, rnd_angle_t)); - if (gds_append_len(string, tmp, tmplen) != 0) goto err; - break; - case 'A': - if (safe & PCB_SAFEPRINT_COORD_ONLY) - return -1; - if (gds_append_len(&spec, ".0f", 3) != 0) goto err; - /* if (suffix == PCB_UNIT_SUFFIX) - if (gds_append_len(&spec, " deg", 4) != 0) goto err;*/ - tmplen = sprintf(tmp, spec.array, 10*((double) va_arg(args, rnd_angle_t))); /* kicad legacy needs decidegrees */ - if (gds_append_len(string, tmp, tmplen) != 0) goto err; - break; - case 'f': - if (safe & PCB_SAFEPRINT_COORD_ONLY) - return -1; - gds_append_len(&spec, "f", 1); - tmplen = sprintf(tmp, spec.array, va_arg(args, double)); - dot = strchr(spec.array, '.'); - if ((dot != NULL) && (dot[1] == '0')) - tmplen = do_trunc0(tmp); - if (gds_append_len(string, tmp, tmplen) != 0) goto err; - break; - case '+': - mask = va_arg(args, enum pcb_allow_e); - break; - default: - { - int found = 0; - for (i = 0; i < pcb_get_n_units(1); ++i) { - if (*fmt == pcb_units[i].printf_code) { - if (CoordsToString(string, value, 1, &spec, pcb_units[i].allow, suffix) != 0) goto err; - found = 1; - break; - } - } - if (!found) - if (CoordsToString(string, value, 1, &spec, PCB_UNIT_ALLOW_ALL_SANE, suffix) != 0) goto err; - } - break; - } - break; - } - } - else - if (gds_append(string, *fmt) != 0) goto err; - ++fmt; - } - - retval = 0; -err:; - gds_uninit(&spec); - if (free_fmt != NULL) - free(free_fmt); - - return retval; -} - -int rnd_sprintf(char *string, const char *fmt, ...) -{ - gds_t str; - va_list args; - - memset(&str, 0, sizeof(str)); /* can't use gds_init, it'd allocate str.array */ - va_start(args, fmt); - - /* pretend the string is already allocated to something huge; this doesn't - make the code less safe but saves a copy */ - str.array = string; - str.alloced = 1<<31; - str.no_realloc = 1; - - rnd_safe_append_vprintf(&str, 0, fmt, args); - - va_end(args); - return str.used; -} - -int rnd_snprintf(char *string, size_t len, const char *fmt, ...) -{ - gds_t str; - va_list args; - - memset(&str, 0, sizeof(str)); /* can't use gds_init, it'd allocate str.array */ - va_start(args, fmt); - - str.array = string; - str.alloced = len; - str.no_realloc = 1; - - rnd_safe_append_vprintf(&str, 0, fmt, args); - - va_end(args); - return str.used; -} - -int rnd_safe_snprintf(char *string, size_t len, rnd_safe_printf_t safe, const char *fmt, ...) -{ - gds_t str; - va_list args; - int res; - - memset(&str, 0, sizeof(str)); /* can't use gds_init, it'd allocate str.array */ - va_start(args, fmt); - - str.array = string; - str.alloced = len; - str.no_realloc = 1; - if (len > 0) - *string = '\0'; /* make sure the string is empty on error of the low level call didn't print anything */ - - res = rnd_safe_append_vprintf(&str, safe, fmt, args); - - va_end(args); - if (res < 0) - return res; - return str.used; -} - - -int rnd_vsnprintf(char *string, size_t len, const char *fmt, va_list args) -{ - gds_t str; - - memset(&str, 0, sizeof(str)); /* can't use gds_init, it'd allocate str.array */ - - str.array = string; - str.alloced = len; - str.no_realloc = 1; - - rnd_safe_append_vprintf(&str, 0, fmt, args); - - return str.used; -} - -int rnd_fprintf(FILE * fh, const char *fmt, ...) -{ - int rv; - va_list args; - - va_start(args, fmt); - rv = rnd_vfprintf(fh, fmt, args); - va_end(args); - - return rv; -} - -int rnd_vfprintf(FILE * fh, const char *fmt, va_list args) -{ - int rv; - gds_t str; - gds_init(&str); - - if (fh == NULL) - rv = -1; - else { - rnd_safe_append_vprintf(&str, 0, fmt, args); - rv = fprintf(fh, "%s", str.array); - } - - gds_uninit(&str); - return rv; -} - -int rnd_printf(const char *fmt, ...) -{ - int rv; - gds_t str; - va_list args; - - gds_init(&str); - va_start(args, fmt); - - rnd_safe_append_vprintf(&str, 0, fmt, args); - rv = printf("%s", str.array); - - va_end(args); - gds_uninit(&str); - return rv; -} - -char *rnd_strdup_printf(const char *fmt, ...) -{ - gds_t str; - va_list args; - - gds_init(&str); - - va_start(args, fmt); - rnd_safe_append_vprintf(&str, 0, fmt, args); - va_end(args); - - return str.array; /* no other allocation has been made */ -} - -char *rnd_strdup_vprintf(const char *fmt, va_list args) -{ - gds_t str; - gds_init(&str); - - rnd_safe_append_vprintf(&str, 0, fmt, args); - - return str.array; /* no other allocation has been made */ -} - - -/* Wrapper for pcb_safe_append_vprintf that appends to a string using vararg API */ -int rnd_append_printf(gds_t *str, const char *fmt, ...) -{ - int retval; - - va_list args; - va_start(args, fmt); - retval = rnd_safe_append_vprintf(str, 0, fmt, args); - va_end(args); - - return retval; -} Index: trunk/src/librnd/core/conf.h =================================================================== --- trunk/src/librnd/core/conf.h (revision 31007) +++ trunk/src/librnd/core/conf.h (revision 31008) @@ -28,7 +28,7 @@ #define RND_CONF_H #include #include -#include +#include #include #include #include Index: trunk/src/librnd/core/grid.c =================================================================== --- trunk/src/librnd/core/grid.c (revision 31007) +++ trunk/src/librnd/core/grid.c (revision 31008) @@ -43,7 +43,7 @@ #include #include #include -#include +#include rnd_coord_t rnd_grid_fit(rnd_coord_t x, rnd_coord_t grid_spacing, rnd_coord_t grid_offset) { Index: trunk/src/librnd/core/hid_dad.h =================================================================== --- trunk/src/librnd/core/hid_dad.h (revision 31007) +++ trunk/src/librnd/core/hid_dad.h (revision 31008) @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include Index: trunk/src/librnd/core/hid_dad_spin.c =================================================================== --- trunk/src/librnd/core/hid_dad_spin.c (revision 31007) +++ trunk/src/librnd/core/hid_dad_spin.c (revision 31008) @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include #include Index: trunk/src/librnd/core/pcb-printf.h =================================================================== --- trunk/src/librnd/core/pcb-printf.h (revision 31007) +++ trunk/src/librnd/core/pcb-printf.h (revision 31008) @@ -1,178 +1,2 @@ -/* - * COPYRIGHT - * - * pcb-rnd, interactive printed circuit board design - * (this file is based on PCB, interactive printed circuit board design) - * Copyright (C) 2011 Andrew Poelstra - * Copyright (C) 2016,2019 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") - * - * - * Old contact info: - * Andrew Poelstra, 16966 60A Ave, V3S 8X5 Surrey, BC, Canada - * asp11@sfu.ca - * - */ - -/* This file defines a wrapper around sprintf, that - * defines new specifiers that take rnd_coord_t objects - * as input. - * - * There is a fair bit of nasty (repetitious) code in - * here, but I feel the gain in clarity for output - * code elsewhere in the project will make it worth - * it. - * - * The new coord/angle specifiers are: - * %mI output a raw internal coordinate without any suffix - * %mm output a measure in mm - * %mu output a measure in um - * %mM output a measure in scaled (mm/um) metric - * %ml output a measure in mil - * %mL output a measure in scaled (mil/in) imperial - * %ms output a measure in most natural mm/mil units - * %mS output a measure in most natural scaled units - * %mN output a measure in requested natural units (enforces the choice of %m+ without further modifications) - * %mH output a measure in most human readable scaled units - * %md output a pair of measures in most natural mm/mil units - * %mD output a pair of measures in most natural scaled units - * %m3 output 3 measures in most natural scaled units - * ... - * %m9 output 9 measures in most natural scaled units - * %m* output a measure with unit given as an additional - * const char* parameter - * %m+ accepts an e_allow parameter that masks all subsequent - * "natural" (N/S/D/3/.../9) specifiers to only use certain - * units - * %ma output an angle in degrees (expects degrees) - * %mf output an a double (same as %f, expect it understands the .0n modifier) - * - * Exotic formats, DO NOT USE: - * %mr output a measure in a unit readable by io_pcb parse_l.l - * (outputs in centimil without units - compatibility with mainline) - * %mk output a measure in decimil (kicad legacy format) - * %mA output an angle in decidegrees (degrees x 10) for kicad legacy - * - * These accept the usual printf modifiers for %f, as well as - * $ output a unit suffix after the measure (with space between measure and unit) - * $$ output a unit suffix after the measure (without space) - * .n number of digits after the decimal point (the usual %f modifier) - * .0n where n is a digit; same as %.n, but truncates trailing zeros - * [n] use stored format n - * # prevents all scaling for %mS/D/1/.../9 (this should - * ONLY be used for debug code since its output exposes - * pcb's base units). - * - * The usual printf(3) precision and length modifiers should work with - * any format specifier that outputs coords, e.g. %.3mm will output in - * mm up to 3 decimal digits after the decimal point. - * - * The new string specifiers are: - * %mq output a quoted string (""); quote if contains quote. Use - * backslash to protect quotes within the quoted string. Modifiers: - * {chars} start quoting if any of these appear; "\}" in {chars} is a plain '}' - * - * - * KNOWN ISSUES: - * No support for %zu size_t printf spec - */ - -#ifndef RND_PCB_PRINTF_H -#define RND_PCB_PRINTF_H - -#include -#include -#include -#include - -typedef enum { /* bitmask for printf hardening */ - PCB_SAFEPRINT_arg_max = 1023, /* for internal use */ - PCB_SAFEPRINT_COORD_ONLY = 1024 /* print only coords (%m); anything else will result in error, returning -1 */ -} rnd_safe_printf_t; - -int rnd_fprintf(FILE * f, const char *fmt, ...); -int rnd_vfprintf(FILE * f, const char *fmt, va_list args); -int rnd_sprintf(char *string, const char *fmt, ...); -int rnd_snprintf(char *string, size_t len, const char *fmt, ...); -int rnd_safe_snprintf(char *string, size_t len, rnd_safe_printf_t safe, const char *fmt, ...); -int rnd_vsnprintf(char *string, size_t len, const char *fmt, va_list args); -int rnd_printf(const char *fmt, ...); -char *rnd_strdup_printf(const char *fmt, ...); -char *rnd_strdup_vprintf(const char *fmt, va_list args); - -int rnd_append_printf(gds_t *str, const char *fmt, ...); - -/* Low level call that does the job */ -int rnd_safe_append_vprintf(gds_t *string, rnd_safe_printf_t safe, const char *fmt, va_list args); - -/* Predefined slots (macros): %[n] will use the nth string from this list. - The first 8 are user-definable. */ -typedef enum { - RND_PRINTF_SLOT_USER0, - RND_PRINTF_SLOT_USER1, - RND_PRINTF_SLOT_USER2, - RND_PRINTF_SLOT_USER3, - RND_PRINTF_SLOT_USER4, - RND_PRINTF_SLOT_USER5, - RND_PRINTF_SLOT_USER6, - RND_PRINTF_SLOT_USER7, - RND_PRINTF_SLOT_FF_ORIG_COORD, /* %[8] original .pcb file format coord prints */ - RND_PRINTF_SLOT_FF_SAFE_COORD, /* %[9] safe .pcb file format coord print that doesn't lose precision */ - RND_PRINTF_SLOT_max -} rnd_printf_slot_idx_t; -extern const char *rnd_printf_slot[RND_PRINTF_SLOT_max]; - -/* strdup and return a string built from a template, controlled by flags: - - RND_SUBST_HOME: replace leading ~ with the user's home directory - - RND_SUBST_PERCENT: attempt to replace printf-like formatting - directives (e.g. %P) using an user provided callback function. The callback - function needs to recognize the directive at **input (pointing to the byte - after the %) and append the substitution to s and increase *input to point - beyond the format directive. The callback returns 0 on success or -1 - on unknown directive (which will be copied verbatim). %% will always - be translated into a single %, without calling cb. - - RND_SUBST_CONF: replace $(conf) automatically (no callback) - - Implemented in paths.c because it depends on conf_core.h and error.h . -*/ -typedef enum { - RND_SUBST_HOME = 1, - RND_SUBST_PERCENT = 2, - RND_SUBST_CONF = 4, - RND_SUBST_BACKSLASH = 8, /* substitute \ sequences as printf(3) does */ - - RND_SUBST_ALL = 0x7f, /* substitute all, but do not enable quiet */ - - RND_SUBST_QUIET = 0x80 -} rnd_strdup_subst_t; - -/* Substitute template using cb, leaving extra room at the end and append the - result to s. Returns 0 on success. */ -int rnd_subst_append(gds_t *s, const char *template, int (*cb)(void *ctx, gds_t *s, const char **input), void *ctx, rnd_strdup_subst_t flags, size_t extra_room); - -/* Same as rnd_subst_append(), but returns a dynamic allocated string - (the caller needs to free() after use) or NULL on error. */ -char *rnd_strdup_subst(const char *template, int (*cb)(void *ctx, gds_t *s, const char **input), void *ctx, rnd_strdup_subst_t flags); - -#endif +/* Provided temporarily, for compatibility */ +#include Index: trunk/src/librnd/core/rnd_printf.c =================================================================== --- trunk/src/librnd/core/rnd_printf.c (nonexistent) +++ trunk/src/librnd/core/rnd_printf.c (revision 31008) @@ -0,0 +1,918 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 2011 Andrew Poelstra + * Copyright (C) 2016,2019 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") + * + * + * Old contact info: + * Andrew Poelstra, 16966 60A Ave, V3S 8X5 Surrey, BC, Canada + * asp11@sfu.ca + * + */ + +/* Implementation of printf wrapper to output pcb coords and angles + * For details of all supported specifiers, see the comment at the + * top of rnd_printf.h */ + +#include +#include +#include +#include +#include + +const char *rnd_printf_slot[RND_PRINTF_SLOT_max] = +{ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 8 user formats */ + "%mr", /* original unitless cmil file format coord */ + "%.07$$mS" /* safe file format coord */ +}; + +static int min_sig_figs(double d) +{ + char buf[50]; + int rv; + + if (d == 0) + return 0; + + /* Normalize to x.xxxx... form */ + if (d < 0) + d *= -1; + while (d >= 10) + d /= 10; + while (d < 1) + d *= 10; + + rv = sprintf(buf, "%g", d); + return rv; +} + +/* Truncate trailing 0's from str */ +static int do_trunc0(char *str) +{ + char *end = str + strlen(str) - 1; + while((end > str) && (*end == '0') && (end[-1] != '.')) { + *end = '\0'; + end--; + } + return end-str+1; +} + + +/* Create sprintf specifier, using default_prec no precision is given */ +static inline void make_printf_spec(char *printf_spec_new, const char *printf_spec, int precision, int *trunc0) +{ + int i = 0; + + *trunc0 = 0; + + while (printf_spec[i] == '%' || isdigit(printf_spec[i]) || + printf_spec[i] == '-' || printf_spec[i] == '+' || printf_spec[i] == '#' || printf_spec[i] == '0') + ++i; + + if (printf_spec[i] == '.') { + if ((printf_spec[i+1] == '0') && (isdigit(printf_spec[i+2]))) + *trunc0 = 1; + sprintf(printf_spec_new, ", %sf", printf_spec); + } + else + sprintf(printf_spec_new, ", %s.%df", printf_spec, precision); +} + +/* sprintf a value (used to change locale on is_file_mode) */ +#define sprintf_lc_safe(is_file_mode, out, fmt, val) \ +do { \ + sprintf(out, fmt, val); \ + if (trunc0) \ + do_trunc0(filemode_buff); \ +} while(0) + +/* append a suffix, with or without space */ +static int inline append_suffix(gds_t *dest, enum pcb_suffix_e suffix_type, const char *suffix) +{ + switch (suffix_type) { + case PCB_UNIT_NO_SUFFIX: + break; + case PCB_UNIT_SUFFIX: + if (gds_append(dest, ' ') != 0) return -1; + /* deliberate fall-thru */ + case PCB_UNIT_FILE_MODE: + if (gds_append_str(dest, suffix) != 0) return -1; + break; + } + return 0; +} + + +/* Internal coord-to-string converter for pcb-printf + * Converts a (group of) measurement(s) to a comma-delimited + * string, with appropriate units. If more than one coord is + * given, the list is enclosed in parens to make the scope of + * the unit suffix clear. + * + * dest Append the output to this dynamic string + * coord Array of coords to convert + * n_coords Number of coords in array + * printf_spec printf sub-specifier to use with %f + * e_allow Bitmap of units the function may use + * suffix_type Whether to add a suffix + * + * return 0 on success, -1 on error + */ +static int CoordsToString(gds_t *dest, rnd_coord_t coord[], int n_coords, const gds_t *printf_spec_, enum pcb_allow_e allow, + enum pcb_suffix_e suffix_type) +{ + char filemode_buff[128]; /* G_ASCII_DTOSTR_BUF_SIZE */ + char printf_spec_new_local[256]; + double *value, value_local[32]; + enum pcb_family_e family; + const char *suffix; + int i, n, retval = -1, trunc0 = 0; + const char *printf_spec = printf_spec_->array; + char *printf_spec_new; + + if (n_coords > (sizeof(value_local) / sizeof(value_local[0]))) { + value = malloc(n_coords * sizeof *value); + if (value == NULL) + return -1; + } + else + value = value_local; + + if (allow == 0) + allow = PCB_UNIT_ALLOW_ALL_SANE; + + i = printf_spec_->used + 64; + if (i > sizeof(printf_spec_new_local)) + printf_spec_new = malloc(i); + else + printf_spec_new = printf_spec_new_local; + + /* Check our freedom in choosing units */ + if ((allow & PCB_UNIT_ALLOW_IMPERIAL) == 0) + family = PCB_UNIT_METRIC; + else if ((allow & PCB_UNIT_ALLOW_METRIC) == 0) + family = PCB_UNIT_IMPERIAL; + else { + int met_votes = 0, imp_votes = 0; + + for (i = 0; i < n_coords; ++i) + if (min_sig_figs(PCB_COORD_TO_MIL(coord[i])) < min_sig_figs(PCB_COORD_TO_MM(coord[i]))) + ++imp_votes; + else + ++met_votes; + + if (imp_votes > met_votes) + family = PCB_UNIT_IMPERIAL; + else + family = PCB_UNIT_METRIC; + } + + /* Set base unit */ + for (i = 0; i < n_coords; ++i) { + switch (family) { + case PCB_UNIT_METRIC: + value[i] = PCB_COORD_TO_MM(coord[i]); + break; + case PCB_UNIT_IMPERIAL: + value[i] = PCB_COORD_TO_MIL(coord[i]); + break; + default: + value[i] = 0; + } + } + + /* Determine scale factor -- find smallest unit that brings + * the whole group above unity */ + for (n = 0; n < pcb_get_n_units(0); ++n) { + if ((pcb_units[n].allow & allow) != 0 && (pcb_units[n].family == family)) { + int n_above_one = 0; + + for (i = 0; i < n_coords; ++i) + if (fabs(value[i] * pcb_units[n].scale_factor) > 1) + ++n_above_one; + if (n_above_one == n_coords) + break; + } + } + /* If nothing worked, wind back to the smallest allowable unit */ + if (n == pcb_get_n_units(0)) { + do { + --n; + } while ((n>=0) && ((pcb_units[n].allow & allow) == 0 || pcb_units[n].family != family)); + } + + /* Apply scale factor */ + suffix = pcb_units[n].suffix; + for (i = 0; i < n_coords; ++i) + value[i] = value[i] * pcb_units[n].scale_factor; + + make_printf_spec(printf_spec_new, printf_spec, pcb_units[n].default_prec, &trunc0); + + /* Actually sprintf the values in place + * (+ 2 skips the ", " for first value) */ + if (n_coords > 1) + if (gds_append(dest, '(') != 0) + goto err; + + sprintf_lc_safe((suffix_type == PCB_UNIT_FILE_MODE), filemode_buff, printf_spec_new + 2, value[0]); + if (gds_append_str(dest, filemode_buff) != 0) + goto err; + + for (i = 1; i < n_coords; ++i) { + sprintf_lc_safe((suffix_type == PCB_UNIT_FILE_MODE), filemode_buff, printf_spec_new, value[i]); + if (gds_append_str(dest, filemode_buff) != 0) + goto err; + } + if (n_coords > 1) + if (gds_append(dest, ')') != 0) goto err; + + + /* Append suffix */ + if (value[0] != 0 || n_coords > 1) + if (append_suffix(dest, suffix_type, suffix) != 0) + goto err; + + retval = 0; +err:; + if (printf_spec_new != printf_spec_new_local) + free(printf_spec_new); + + if (value != value_local) + free(value); + return retval; +} + +typedef struct { + int score_factor; + + enum pcb_allow_e base; + double down_limit; + enum pcb_allow_e down; + double up_limit; + enum pcb_allow_e up; + + /* persistent, calculated once */ + const rnd_unit_t *base_unit, *down_unit, *up_unit; +} human_coord_t; + +/* Conversion preference table */ +static human_coord_t human_coord[] = { + {2, PCB_UNIT_ALLOW_MM, 0.001, PCB_UNIT_ALLOW_UM, 1000.0, PCB_UNIT_ALLOW_M ,NULL,NULL,NULL}, + {1, PCB_UNIT_ALLOW_MIL, 0, 0, 1000.0, PCB_UNIT_ALLOW_IN ,NULL,NULL,NULL} +}; +#define NUM_HUMAN_COORD (sizeof(human_coord) / sizeof(human_coord[0])) + +static inline int try_human_coord(rnd_coord_t coord, const rnd_unit_t *unit, double down_limit, double up_limit, int score_factor, double *value, unsigned int *best, const char **suffix) +{ + double v, frac, save; + long int digs, zeros; + unsigned int score; + + /* convert the value to the proposed unit */ + if (unit->family == PCB_UNIT_METRIC) + v = PCB_COORD_TO_MM(coord); + else + v = PCB_COORD_TO_MIL(coord); + save = v = v * unit->scale_factor; + if (v < 0) v = -v; + + /* Check if neighbour units are better */ + if ((down_limit > 0) && (v < down_limit)) + return -1; + if ((up_limit > 0) && (v > up_limit)) + return +1; + + /* count trailing zeros after the decimal point up to 8 digits */ + frac = v - floor(v); + digs = frac * 100000000.0; + if (digs != 0) + for(zeros = 0; (digs % 10) == 0; zeros++, digs /= 10); + else + zeros = 8; + + /* score is higher for more zeroes */ + score = score_factor + 8 * zeros; + +/* printf("try: %s '%.8f' -> %.8f %d score=%d\n", unit->suffix, v, frac, zeros, score);*/ + + /* update the best score */ + if (score > *best) { + *value = save; + *best = score; + *suffix = unit->suffix; + } + + return 0; +} + +/* Same as CoordsToString but take only one coord and print it in human readable format */ +static int CoordsToHumanString(gds_t *dest, rnd_coord_t coord, const gds_t *printf_spec_, enum pcb_suffix_e suffix_type) +{ + char filemode_buff[128]; /* G_ASCII_DTOSTR_BUF_SIZE */ + char printf_spec_new_local[256]; + char *printf_spec_new; + int i, retval = -1, trunc0; + const char *printf_spec = printf_spec_->array; + const char *suffix; + double value; + unsigned int best_score = 0; + + i = printf_spec_->used + 64; + if (i > sizeof(printf_spec_new_local)) + printf_spec_new = malloc(i); + else + printf_spec_new = printf_spec_new_local; + + /* cache unit lookup */ + if (human_coord[0].base_unit == NULL) { + for(i = 0; i < NUM_HUMAN_COORD; i++) { + human_coord[i].base_unit = get_unit_struct_by_allow(human_coord[i].base); + human_coord[i].down_unit = get_unit_struct_by_allow(human_coord[i].down); + human_coord[i].up_unit = get_unit_struct_by_allow(human_coord[i].up); + } + } + + for(i = 0; i < NUM_HUMAN_COORD; i++) { + int res; + /* try the base units first */ + res = try_human_coord(coord, human_coord[i].base_unit, human_coord[i].down_limit, human_coord[i].up_limit, human_coord[i].score_factor,&value, &best_score, &suffix); + if (res < 0) + try_human_coord(coord, human_coord[i].down_unit, 0, 0, human_coord[i].score_factor, &value, &best_score, &suffix); + else if (res > 0) + try_human_coord(coord, human_coord[i].up_unit, 0, 0, human_coord[i].score_factor,&value, &best_score, &suffix); + } + + make_printf_spec(printf_spec_new, printf_spec, 8, &trunc0); + sprintf_lc_safe((suffix_type == PCB_UNIT_FILE_MODE), filemode_buff, printf_spec_new + 2, value); + if (gds_append_str(dest, filemode_buff) != 0) + goto err; + + if (value != 0) { + if (suffix_type == PCB_UNIT_NO_SUFFIX) + suffix_type = PCB_UNIT_SUFFIX; + if (append_suffix(dest, suffix_type, suffix) != 0) + goto err; + } + + err:; + if (printf_spec_new != printf_spec_new_local) + free(printf_spec_new); + return retval; +} + +int QstringToString(gds_t *dest, const char *qstr, char q, char esc, const char *needq) +{ + const char *s; + + if ((qstr == NULL) || (*qstr == '\0')) { + gds_append(dest, q); + gds_append(dest, q); + return 0; + } + + /* check if quoting is needed */ + if (strpbrk(qstr, needq) == NULL) { + gds_append_str(dest, qstr); + return 0; + } + + /* wrap in quotes and protect escape and quote chars */ + gds_append(dest, q); + for(s = qstr; *s != '\0'; s++) { + if ((*s == esc) || (*s == q)) + gds_append(dest, esc); + gds_append(dest, *s); + } + gds_append(dest, q); + return 0; +} + +/* Main low level pcb-printf function + * This is a printf wrapper that accepts new format specifiers to + * output pcb coords as various units. See the comment at the top + * of rnd_printf.h for full details. + * + * [in] string Append anything new at the end of this dynamic string (must be initialized before the call) + * [in] fmt Format specifier + * [in] args Arguments to specifier + * + * return 0 on success */ +int rnd_safe_append_vprintf(gds_t *string, rnd_safe_printf_t safe, const char *fmt, va_list args) +{ + gds_t spec; + const char *qstr, *needsq; + char tmp[128]; /* large enough for rendering a long long int */ + int tmplen, retval = -1, slot_recursion = 0, mq_has_spec; + char *dot, *free_fmt = NULL; + enum pcb_allow_e mask = PCB_UNIT_ALLOW_ALL_SANE; + unsigned long maxfmts; + + if ((safe & PCB_SAFEPRINT_arg_max) > 0) + maxfmts = (safe & PCB_SAFEPRINT_arg_max); + else + maxfmts = 1UL<<31; + + gds_init(&spec); + + new_fmt:; + while (*fmt) { + enum pcb_suffix_e suffix = PCB_UNIT_NO_SUFFIX; + + if (*fmt == '%') { + const char *ext_unit = ""; + rnd_coord_t value[10]; + int count, i; + + gds_truncate(&spec, 0); + mq_has_spec = 0; + + /* Get printf sub-specifiers */ + if (gds_append(&spec, *fmt++) != 0) goto err; + while (isdigit(*fmt) || *fmt == '.' || *fmt == ' ' || *fmt == '*' + || *fmt == '#' || *fmt == 'l' || *fmt == 'L' || *fmt == 'h' + || *fmt == '+' || *fmt == '-' || *fmt == '[' || *fmt == '{') { + if (*fmt == '*') { + char itmp[32]; + int ilen; + ilen = sprintf(itmp, "%d", va_arg(args, int)); + if (gds_append_len(&spec, itmp, ilen) != 0) goto err; + fmt++; + } + else + if (gds_append(&spec, *fmt++) != 0) goto err; + } + + /* check if specifier is %[] */ + if ((gds_len(&spec) > 2) && (spec.array[1] == '[')) { + int slot = atoi(spec.array+2); + gds_t new_spec; + if ((slot < 0) || (slot > RND_PRINTF_SLOT_max)) { + fprintf(stderr, "Internal error: invalid printf slot addressed: '%s'\n", spec.array); + abort(); + } + slot_recursion++; + if (slot_recursion > 16) { + fprintf(stderr, "Internal error: printf slot recursion too deep on addressed: '%s'\n", spec.array); + abort(); + } + if (rnd_printf_slot[slot] == NULL) { + fprintf(stderr, "Internal error: printf empty slot reference: '%s'\n", spec.array); + abort(); + } + gds_init(&new_spec); + gds_append_str(&new_spec, rnd_printf_slot[slot]); + if (*fmt == ']') + fmt++; + gds_append_str(&new_spec, fmt); + if (free_fmt != NULL) + free(free_fmt); + fmt = free_fmt = new_spec.array; + memset(&new_spec, 0, sizeof(new_spec)); + gds_truncate(&spec, 0); + goto new_fmt; + } + if ((spec.array[0] == '%') && (spec.array[1] == '{')) { + /* {} specifier for %mq */ + const char *end; + gds_truncate(&spec, 0); + for(end = fmt; *end != '\0'; end++) { + if ((end[0] != '\\') && (end[1] == '}')) { + end++; + break; + } + } + if (*end == '\0') + goto err; + gds_append_len(&spec, fmt, end-fmt); + fmt = end+1; + mq_has_spec = 1; + } + else + slot_recursion = 0; + + /* Get our sub-specifiers */ + if (*fmt == '#') { + mask = PCB_UNIT_ALLOW_CMIL; /* This must be pcb's base unit */ + fmt++; + } + if (*fmt == '$') { + suffix = PCB_UNIT_SUFFIX; + fmt++; + if (*fmt == '$') { + fmt++; + suffix = PCB_UNIT_FILE_MODE; + } + } + + if (maxfmts == 0) + return -1; + maxfmts--; + + /* Tack full specifier onto specifier */ + if (*fmt != 'm') + if (gds_append(&spec, *fmt) != 0) goto err; + switch (*fmt) { + /* Printf specs */ + case 'o': + case 'i': + case 'd': + case 'u': + case 'x': + case 'X': + if (safe & PCB_SAFEPRINT_COORD_ONLY) + return -1; + if (spec.array[1] == 'l') + tmplen = sprintf(tmp, spec.array, va_arg(args, long)); + else + tmplen = sprintf(tmp, spec.array, va_arg(args, int)); + if (gds_append_len(string, tmp, tmplen) != 0) goto err; + break; + case 'e': + case 'E': + case 'f': + case 'g': + case 'G': + if (safe & PCB_SAFEPRINT_COORD_ONLY) + return -1; + if (strchr(spec.array, '*')) { + int prec = va_arg(args, int); + tmplen = sprintf(tmp, spec.array, va_arg(args, double), prec); + } + else + tmplen = sprintf(tmp, spec.array, va_arg(args, double)); + if (gds_append_len(string, tmp, tmplen) != 0) goto err; + break; + case 'c': + if (safe & PCB_SAFEPRINT_COORD_ONLY) + return -1; + if (spec.array[1] == 'l' && sizeof(int) <= sizeof(wchar_t)) + tmplen = sprintf(tmp, spec.array, va_arg(args, wchar_t)); + else + tmplen = sprintf(tmp, spec.array, va_arg(args, int)); + if (gds_append_len(string, tmp, tmplen) != 0) goto err; + break; + case 's': + if (safe & PCB_SAFEPRINT_COORD_ONLY) + return -1; + if (spec.array[0] == 'l') { + /* TODO: convert wchar to char and append it */ + fprintf(stderr, "Internal error: appending %%ls is not supported\n"); + abort(); + } + else { + const char *s = va_arg(args, const char *); + if (s == NULL) s = "(null)"; + if (gds_append_str(string, s) != 0) goto err; + } + break; + case 'n': + if (safe & PCB_SAFEPRINT_COORD_ONLY) + return -1; + /* Depending on gcc settings, this will probably break with + * some silly "can't put %n in writable data space" message */ + tmplen = sprintf(tmp, spec.array, va_arg(args, int *)); + if (gds_append_len(string, tmp, tmplen) != 0) goto err; + break; + case 'p': + if (safe & PCB_SAFEPRINT_COORD_ONLY) + return -1; + tmplen = sprintf(tmp, spec.array, va_arg(args, void *)); + if (gds_append_len(string, tmp, tmplen) != 0) goto err; + break; + case '%': + if (gds_append(string, '%') != 0) goto err; + break; + /* Our specs */ + case 'm': + ++fmt; + if (*fmt == '*') + ext_unit = va_arg(args, const char *); + if (*fmt != '+' && *fmt != 'a' && *fmt != 'A' && *fmt != 'f' && *fmt != 'q') + value[0] = va_arg(args, rnd_coord_t); + count = 1; + switch (*fmt) { + case 'q': + qstr = va_arg(args, const char *); + if (mq_has_spec) + needsq = spec.array; + else + needsq = " \"\\"; + if (QstringToString(string, qstr, '"', '\\', needsq) != 0) goto err; + break; + case 'I': + if (CoordsToString(string, value, 1, &spec, PCB_UNIT_ALLOW_NM, PCB_UNIT_NO_SUFFIX) != 0) goto err; + break; + case 's': + if (CoordsToString(string, value, 1, &spec, PCB_UNIT_ALLOW_MM | PCB_UNIT_ALLOW_MIL, suffix) != 0) goto err; + break; + case 'S': + if (CoordsToString(string, value, 1, &spec, mask & PCB_UNIT_ALLOW_NATURAL, suffix) != 0) goto err; + break; + case 'N': + if (CoordsToString(string, value, 1, &spec, mask, suffix) != 0) goto err; + break; + case 'H': + if ((safe & PCB_SAFEPRINT_COORD_ONLY) && (value[0] > 1)) + return -1; + if (CoordsToHumanString(string, value[0], &spec, suffix) != 0) goto err; + break; + case 'M': + if (CoordsToString(string, value, 1, &spec, mask & PCB_UNIT_ALLOW_METRIC, suffix) != 0) goto err; + break; + case 'L': + if (CoordsToString(string, value, 1, &spec, mask & PCB_UNIT_ALLOW_IMPERIAL, suffix) != 0) goto err; + break; + case 'k': + if (CoordsToString(string, value, 1, &spec, PCB_UNIT_ALLOW_DMIL, suffix) != 0) goto err; + break; + case 'r': + if (CoordsToString(string, value, 1, &spec, PCB_UNIT_ALLOW_READABLE, PCB_UNIT_NO_SUFFIX) != 0) goto err; + break; + /* All these fallthroughs are deliberate */ + case '9': + value[count++] = va_arg(args, rnd_coord_t); + case '8': + value[count++] = va_arg(args, rnd_coord_t); + case '7': + value[count++] = va_arg(args, rnd_coord_t); + case '6': + value[count++] = va_arg(args, rnd_coord_t); + case '5': + value[count++] = va_arg(args, rnd_coord_t); + case '4': + value[count++] = va_arg(args, rnd_coord_t); + case '3': + value[count++] = va_arg(args, rnd_coord_t); + case '2': + case 'D': + if (safe & PCB_SAFEPRINT_COORD_ONLY) + return -1; + value[count++] = va_arg(args, rnd_coord_t); + if (CoordsToString(string, value, count, &spec, mask & PCB_UNIT_ALLOW_ALL_SANE, suffix) != 0) goto err; + break; + case 'd': + if (safe & PCB_SAFEPRINT_COORD_ONLY) + return -1; + value[1] = va_arg(args, rnd_coord_t); + if (CoordsToString(string, value, 2, &spec, PCB_UNIT_ALLOW_MM | PCB_UNIT_ALLOW_MIL, suffix) != 0) goto err; + break; + case '*': + { + int found = 0; + for (i = 0; i < pcb_get_n_units(1); ++i) { + if (strcmp(ext_unit, pcb_units[i].suffix) == 0) { + if (CoordsToString(string, value, 1, &spec, pcb_units[i].allow, suffix) != 0) goto err; + found = 1; + break; + } + } + if (!found) + if (CoordsToString(string, value, 1, &spec, mask & PCB_UNIT_ALLOW_ALL_SANE, suffix) != 0) goto err; + } + break; + case 'a': + if (safe & PCB_SAFEPRINT_COORD_ONLY) + return -1; + if (gds_append_len(&spec, ".06f", 4) != 0) goto err; + if (suffix == PCB_UNIT_SUFFIX) + if (gds_append_len(&spec, " deg", 4) != 0) goto err; + tmplen = sprintf(tmp, spec.array, (double) va_arg(args, rnd_angle_t)); + if (gds_append_len(string, tmp, tmplen) != 0) goto err; + break; + case 'A': + if (safe & PCB_SAFEPRINT_COORD_ONLY) + return -1; + if (gds_append_len(&spec, ".0f", 3) != 0) goto err; + /* if (suffix == PCB_UNIT_SUFFIX) + if (gds_append_len(&spec, " deg", 4) != 0) goto err;*/ + tmplen = sprintf(tmp, spec.array, 10*((double) va_arg(args, rnd_angle_t))); /* kicad legacy needs decidegrees */ + if (gds_append_len(string, tmp, tmplen) != 0) goto err; + break; + case 'f': + if (safe & PCB_SAFEPRINT_COORD_ONLY) + return -1; + gds_append_len(&spec, "f", 1); + tmplen = sprintf(tmp, spec.array, va_arg(args, double)); + dot = strchr(spec.array, '.'); + if ((dot != NULL) && (dot[1] == '0')) + tmplen = do_trunc0(tmp); + if (gds_append_len(string, tmp, tmplen) != 0) goto err; + break; + case '+': + mask = va_arg(args, enum pcb_allow_e); + break; + default: + { + int found = 0; + for (i = 0; i < pcb_get_n_units(1); ++i) { + if (*fmt == pcb_units[i].printf_code) { + if (CoordsToString(string, value, 1, &spec, pcb_units[i].allow, suffix) != 0) goto err; + found = 1; + break; + } + } + if (!found) + if (CoordsToString(string, value, 1, &spec, PCB_UNIT_ALLOW_ALL_SANE, suffix) != 0) goto err; + } + break; + } + break; + } + } + else + if (gds_append(string, *fmt) != 0) goto err; + ++fmt; + } + + retval = 0; +err:; + gds_uninit(&spec); + if (free_fmt != NULL) + free(free_fmt); + + return retval; +} + +int rnd_sprintf(char *string, const char *fmt, ...) +{ + gds_t str; + va_list args; + + memset(&str, 0, sizeof(str)); /* can't use gds_init, it'd allocate str.array */ + va_start(args, fmt); + + /* pretend the string is already allocated to something huge; this doesn't + make the code less safe but saves a copy */ + str.array = string; + str.alloced = 1<<31; + str.no_realloc = 1; + + rnd_safe_append_vprintf(&str, 0, fmt, args); + + va_end(args); + return str.used; +} + +int rnd_snprintf(char *string, size_t len, const char *fmt, ...) +{ + gds_t str; + va_list args; + + memset(&str, 0, sizeof(str)); /* can't use gds_init, it'd allocate str.array */ + va_start(args, fmt); + + str.array = string; + str.alloced = len; + str.no_realloc = 1; + + rnd_safe_append_vprintf(&str, 0, fmt, args); + + va_end(args); + return str.used; +} + +int rnd_safe_snprintf(char *string, size_t len, rnd_safe_printf_t safe, const char *fmt, ...) +{ + gds_t str; + va_list args; + int res; + + memset(&str, 0, sizeof(str)); /* can't use gds_init, it'd allocate str.array */ + va_start(args, fmt); + + str.array = string; + str.alloced = len; + str.no_realloc = 1; + if (len > 0) + *string = '\0'; /* make sure the string is empty on error of the low level call didn't print anything */ + + res = rnd_safe_append_vprintf(&str, safe, fmt, args); + + va_end(args); + if (res < 0) + return res; + return str.used; +} + + +int rnd_vsnprintf(char *string, size_t len, const char *fmt, va_list args) +{ + gds_t str; + + memset(&str, 0, sizeof(str)); /* can't use gds_init, it'd allocate str.array */ + + str.array = string; + str.alloced = len; + str.no_realloc = 1; + + rnd_safe_append_vprintf(&str, 0, fmt, args); + + return str.used; +} + +int rnd_fprintf(FILE * fh, const char *fmt, ...) +{ + int rv; + va_list args; + + va_start(args, fmt); + rv = rnd_vfprintf(fh, fmt, args); + va_end(args); + + return rv; +} + +int rnd_vfprintf(FILE * fh, const char *fmt, va_list args) +{ + int rv; + gds_t str; + gds_init(&str); + + if (fh == NULL) + rv = -1; + else { + rnd_safe_append_vprintf(&str, 0, fmt, args); + rv = fprintf(fh, "%s", str.array); + } + + gds_uninit(&str); + return rv; +} + +int rnd_printf(const char *fmt, ...) +{ + int rv; + gds_t str; + va_list args; + + gds_init(&str); + va_start(args, fmt); + + rnd_safe_append_vprintf(&str, 0, fmt, args); + rv = printf("%s", str.array); + + va_end(args); + gds_uninit(&str); + return rv; +} + +char *rnd_strdup_printf(const char *fmt, ...) +{ + gds_t str; + va_list args; + + gds_init(&str); + + va_start(args, fmt); + rnd_safe_append_vprintf(&str, 0, fmt, args); + va_end(args); + + return str.array; /* no other allocation has been made */ +} + +char *rnd_strdup_vprintf(const char *fmt, va_list args) +{ + gds_t str; + gds_init(&str); + + rnd_safe_append_vprintf(&str, 0, fmt, args); + + return str.array; /* no other allocation has been made */ +} + + +/* Wrapper for pcb_safe_append_vprintf that appends to a string using vararg API */ +int rnd_append_printf(gds_t *str, const char *fmt, ...) +{ + int retval; + + va_list args; + va_start(args, fmt); + retval = rnd_safe_append_vprintf(str, 0, fmt, args); + va_end(args); + + return retval; +} Index: trunk/src/librnd/core/rnd_printf.h =================================================================== --- trunk/src/librnd/core/rnd_printf.h (nonexistent) +++ trunk/src/librnd/core/rnd_printf.h (revision 31008) @@ -0,0 +1,178 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 2011 Andrew Poelstra + * Copyright (C) 2016,2019 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") + * + * + * Old contact info: + * Andrew Poelstra, 16966 60A Ave, V3S 8X5 Surrey, BC, Canada + * asp11@sfu.ca + * + */ + +/* This file defines a wrapper around sprintf, that + * defines new specifiers that take rnd_coord_t objects + * as input. + * + * There is a fair bit of nasty (repetitious) code in + * here, but I feel the gain in clarity for output + * code elsewhere in the project will make it worth + * it. + * + * The new coord/angle specifiers are: + * %mI output a raw internal coordinate without any suffix + * %mm output a measure in mm + * %mu output a measure in um + * %mM output a measure in scaled (mm/um) metric + * %ml output a measure in mil + * %mL output a measure in scaled (mil/in) imperial + * %ms output a measure in most natural mm/mil units + * %mS output a measure in most natural scaled units + * %mN output a measure in requested natural units (enforces the choice of %m+ without further modifications) + * %mH output a measure in most human readable scaled units + * %md output a pair of measures in most natural mm/mil units + * %mD output a pair of measures in most natural scaled units + * %m3 output 3 measures in most natural scaled units + * ... + * %m9 output 9 measures in most natural scaled units + * %m* output a measure with unit given as an additional + * const char* parameter + * %m+ accepts an e_allow parameter that masks all subsequent + * "natural" (N/S/D/3/.../9) specifiers to only use certain + * units + * %ma output an angle in degrees (expects degrees) + * %mf output an a double (same as %f, expect it understands the .0n modifier) + * + * Exotic formats, DO NOT USE: + * %mr output a measure in a unit readable by io_pcb parse_l.l + * (outputs in centimil without units - compatibility with mainline) + * %mk output a measure in decimil (kicad legacy format) + * %mA output an angle in decidegrees (degrees x 10) for kicad legacy + * + * These accept the usual printf modifiers for %f, as well as + * $ output a unit suffix after the measure (with space between measure and unit) + * $$ output a unit suffix after the measure (without space) + * .n number of digits after the decimal point (the usual %f modifier) + * .0n where n is a digit; same as %.n, but truncates trailing zeros + * [n] use stored format n + * # prevents all scaling for %mS/D/1/.../9 (this should + * ONLY be used for debug code since its output exposes + * pcb's base units). + * + * The usual printf(3) precision and length modifiers should work with + * any format specifier that outputs coords, e.g. %.3mm will output in + * mm up to 3 decimal digits after the decimal point. + * + * The new string specifiers are: + * %mq output a quoted string (""); quote if contains quote. Use + * backslash to protect quotes within the quoted string. Modifiers: + * {chars} start quoting if any of these appear; "\}" in {chars} is a plain '}' + * + * + * KNOWN ISSUES: + * No support for %zu size_t printf spec + */ + +#ifndef RND_PCB_PRINTF_H +#define RND_PCB_PRINTF_H + +#include +#include +#include +#include + +typedef enum { /* bitmask for printf hardening */ + PCB_SAFEPRINT_arg_max = 1023, /* for internal use */ + PCB_SAFEPRINT_COORD_ONLY = 1024 /* print only coords (%m); anything else will result in error, returning -1 */ +} rnd_safe_printf_t; + +int rnd_fprintf(FILE * f, const char *fmt, ...); +int rnd_vfprintf(FILE * f, const char *fmt, va_list args); +int rnd_sprintf(char *string, const char *fmt, ...); +int rnd_snprintf(char *string, size_t len, const char *fmt, ...); +int rnd_safe_snprintf(char *string, size_t len, rnd_safe_printf_t safe, const char *fmt, ...); +int rnd_vsnprintf(char *string, size_t len, const char *fmt, va_list args); +int rnd_printf(const char *fmt, ...); +char *rnd_strdup_printf(const char *fmt, ...); +char *rnd_strdup_vprintf(const char *fmt, va_list args); + +int rnd_append_printf(gds_t *str, const char *fmt, ...); + +/* Low level call that does the job */ +int rnd_safe_append_vprintf(gds_t *string, rnd_safe_printf_t safe, const char *fmt, va_list args); + +/* Predefined slots (macros): %[n] will use the nth string from this list. + The first 8 are user-definable. */ +typedef enum { + RND_PRINTF_SLOT_USER0, + RND_PRINTF_SLOT_USER1, + RND_PRINTF_SLOT_USER2, + RND_PRINTF_SLOT_USER3, + RND_PRINTF_SLOT_USER4, + RND_PRINTF_SLOT_USER5, + RND_PRINTF_SLOT_USER6, + RND_PRINTF_SLOT_USER7, + RND_PRINTF_SLOT_FF_ORIG_COORD, /* %[8] original .pcb file format coord prints */ + RND_PRINTF_SLOT_FF_SAFE_COORD, /* %[9] safe .pcb file format coord print that doesn't lose precision */ + RND_PRINTF_SLOT_max +} rnd_printf_slot_idx_t; +extern const char *rnd_printf_slot[RND_PRINTF_SLOT_max]; + +/* strdup and return a string built from a template, controlled by flags: + + RND_SUBST_HOME: replace leading ~ with the user's home directory + + RND_SUBST_PERCENT: attempt to replace printf-like formatting + directives (e.g. %P) using an user provided callback function. The callback + function needs to recognize the directive at **input (pointing to the byte + after the %) and append the substitution to s and increase *input to point + beyond the format directive. The callback returns 0 on success or -1 + on unknown directive (which will be copied verbatim). %% will always + be translated into a single %, without calling cb. + + RND_SUBST_CONF: replace $(conf) automatically (no callback) + + Implemented in paths.c because it depends on conf_core.h and error.h . +*/ +typedef enum { + RND_SUBST_HOME = 1, + RND_SUBST_PERCENT = 2, + RND_SUBST_CONF = 4, + RND_SUBST_BACKSLASH = 8, /* substitute \ sequences as printf(3) does */ + + RND_SUBST_ALL = 0x7f, /* substitute all, but do not enable quiet */ + + RND_SUBST_QUIET = 0x80 +} rnd_strdup_subst_t; + +/* Substitute template using cb, leaving extra room at the end and append the + result to s. Returns 0 on success. */ +int rnd_subst_append(gds_t *s, const char *template, int (*cb)(void *ctx, gds_t *s, const char **input), void *ctx, rnd_strdup_subst_t flags, size_t extra_room); + +/* Same as rnd_subst_append(), but returns a dynamic allocated string + (the caller needs to free() after use) or NULL on error. */ +char *rnd_strdup_subst(const char *template, int (*cb)(void *ctx, gds_t *s, const char **input), void *ctx, rnd_strdup_subst_t flags); + +#endif Index: trunk/src/librnd/poly/polyarea.c =================================================================== --- trunk/src/librnd/poly/polyarea.c (revision 31007) +++ trunk/src/librnd/poly/polyarea.c (revision 31008) @@ -50,7 +50,7 @@ #include #include #include -#include +#include #include #include #include Index: trunk/src/obj_term.c =================================================================== --- trunk/src/obj_term.c (revision 31007) +++ trunk/src/obj_term.c (revision 31008) @@ -36,7 +36,7 @@ #include "obj_common.h" #include "obj_term.h" #include "obj_subc_parent.h" -#include +#include #include "undo.h" #include "polygon.h" Index: trunk/src/plug_io.c =================================================================== --- trunk/src/plug_io.c (revision 31007) +++ trunk/src/plug_io.c (revision 31008) @@ -58,7 +58,7 @@ #include #include "rats_patch.h" #include -#include +#include #include #include "event.h" #include Index: trunk/src/route_style.c =================================================================== --- trunk/src/route_style.c (revision 31007) +++ trunk/src/route_style.c (revision 31008) @@ -28,7 +28,7 @@ */ #include #include "config.h" -#include +#include #include "genvector/gds_char.h" #include "route_style.h" #include Index: trunk/src/view.c =================================================================== --- trunk/src/view.c (revision 31007) +++ trunk/src/view.c (revision 31008) @@ -43,7 +43,7 @@ #include #include #include -#include +#include static unsigned long int pcb_view_next_uid = 0; Index: trunk/src_plugins/asm/asm.c =================================================================== --- trunk/src_plugins/asm/asm.c (revision 31007) +++ trunk/src_plugins/asm/asm.c (revision 31008) @@ -38,7 +38,7 @@ #include #include #include "obj_subc.h" -#include +#include #include #include #include "search.h" Index: trunk/src_plugins/autoroute/autoroute.c =================================================================== --- trunk/src_plugins/autoroute/autoroute.c (revision 31007) +++ trunk/src_plugins/autoroute/autoroute.c (revision 31008) @@ -80,7 +80,7 @@ #include "obj_pinvia_therm.h" #include "undo.h" #include "vector.h" -#include +#include #include "layer.h" #include #include "layer.h" Index: trunk/src_plugins/dialogs/dlg_about.c =================================================================== --- trunk/src_plugins/dialogs/dlg_about.c (revision 31007) +++ trunk/src_plugins/dialogs/dlg_about.c (revision 31008) @@ -31,7 +31,7 @@ #include "build_run.h" #include #include -#include +#include #include "dlg_about.h" typedef struct{ Index: trunk/src_plugins/dialogs/dlg_pinout.c =================================================================== --- trunk/src_plugins/dialogs/dlg_pinout.c (revision 31007) +++ trunk/src_plugins/dialogs/dlg_pinout.c (revision 31008) @@ -26,7 +26,7 @@ #include #include "build_run.h" -#include +#include #include "obj_subc_parent.h" #include "draw.h" #include "obj_term.h" Index: trunk/src_plugins/dialogs/dlg_pref.c =================================================================== --- trunk/src_plugins/dialogs/dlg_pref.c (revision 31007) +++ trunk/src_plugins/dialogs/dlg_pref.c (revision 31008) @@ -32,7 +32,7 @@ #include #include #include "build_run.h" -#include +#include #include #include "event.h" #include Index: trunk/src_plugins/djopt/djopt.c =================================================================== --- trunk/src_plugins/djopt/djopt.c (revision 31007) +++ trunk/src_plugins/djopt/djopt.c (revision 31008) @@ -48,7 +48,7 @@ #include "flag_str.h" #include "find.h" #include "layer.h" -#include +#include #include #include #include Index: trunk/src_plugins/draw_fontsel/draw_fontsel.c =================================================================== --- trunk/src_plugins/draw_fontsel/draw_fontsel.c (revision 31007) +++ trunk/src_plugins/draw_fontsel/draw_fontsel.c (revision 31008) @@ -38,7 +38,7 @@ #include #include #include "stub_draw.h" -#include +#include #include #include "conf_core.h" Index: trunk/src_plugins/export_bom/bom.c =================================================================== --- trunk/src_plugins/export_bom/bom.c (revision 31007) +++ trunk/src_plugins/export_bom/bom.c (revision 31008) @@ -16,7 +16,7 @@ #include "board.h" #include "data.h" #include -#include +#include #include #include #include Index: trunk/src_plugins/export_dsn/dsn.c =================================================================== --- trunk/src_plugins/export_dsn/dsn.c (revision 31007) +++ trunk/src_plugins/export_dsn/dsn.c (revision 31008) @@ -50,7 +50,7 @@ #include "change.h" #include "draw.h" #include "undo.h" -#include +#include #include "polygon.h" #include #include "layer.h" Index: trunk/src_plugins/export_dxf/dxf.c =================================================================== --- trunk/src_plugins/export_dxf/dxf.c (revision 31007) +++ trunk/src_plugins/export_dxf/dxf.c (revision 31008) @@ -42,7 +42,7 @@ #include "layer.h" #include "layer_vis.h" #include -#include +#include #include #include "lht_template.h" #include Index: trunk/src_plugins/export_excellon/excellon.c =================================================================== --- trunk/src_plugins/export_excellon/excellon.c (revision 31007) +++ trunk/src_plugins/export_excellon/excellon.c (revision 31008) @@ -2,7 +2,7 @@ #include "board.h" #include -#include +#include #include #include #include "draw.h" Index: trunk/src_plugins/export_fidocadj/fidocadj.c =================================================================== --- trunk/src_plugins/export_fidocadj/fidocadj.c (revision 31007) +++ trunk/src_plugins/export_fidocadj/fidocadj.c (revision 31008) @@ -47,7 +47,7 @@ #include "data.h" #include "layer_vis.h" #include -#include +#include #include #include "plug_io.h" #include Index: trunk/src_plugins/export_gerber/gerber.c =================================================================== --- trunk/src_plugins/export_gerber/gerber.c (revision 31007) +++ trunk/src_plugins/export_gerber/gerber.c (revision 31008) @@ -18,7 +18,7 @@ #include "draw.h" #include "layer.h" #include "layer_vis.h" -#include +#include #include #include "hid_cam.h" #include Index: trunk/src_plugins/export_openems/mesh.c =================================================================== --- trunk/src_plugins/export_openems/mesh.c (revision 31007) +++ trunk/src_plugins/export_openems/mesh.c (revision 31008) @@ -35,7 +35,7 @@ #include #include "event.h" #include -#include +#include static pcb_mesh_t mesh; static const char *mesh_ui_cookie = "mesh ui layer cookie"; Index: trunk/src_plugins/export_ps/eps.c =================================================================== --- trunk/src_plugins/export_ps/eps.c (revision 31007) +++ trunk/src_plugins/export_ps/eps.c (revision 31008) @@ -13,7 +13,7 @@ #include "draw.h" #include "layer.h" #include "layer_vis.h" -#include +#include #include #include Index: trunk/src_plugins/export_ps/ps.c =================================================================== --- trunk/src_plugins/export_ps/ps.c (revision 31007) +++ trunk/src_plugins/export_ps/ps.c (revision 31008) @@ -12,7 +12,7 @@ #include "layer.h" #include #include "draw.h" -#include +#include #include #include "hid_cam.h" #include Index: trunk/src_plugins/export_stat/stat.c =================================================================== --- trunk/src_plugins/export_stat/stat.c (revision 31007) +++ trunk/src_plugins/export_stat/stat.c (revision 31008) @@ -50,7 +50,7 @@ #include "data_it.h" #include "netlist.h" #include -#include +#include #include #include "plug_io.h" #include Index: trunk/src_plugins/export_test/export_test.c =================================================================== --- trunk/src_plugins/export_test/export_test.c (revision 31007) +++ trunk/src_plugins/export_test/export_test.c (revision 31008) @@ -11,7 +11,7 @@ #include "board.h" #include "data.h" #include -#include +#include #include #include Index: trunk/src_plugins/export_vfs_fuse/export_vfs_fuse.c =================================================================== --- trunk/src_plugins/export_vfs_fuse/export_vfs_fuse.c (revision 31007) +++ trunk/src_plugins/export_vfs_fuse/export_vfs_fuse.c (revision 31008) @@ -21,7 +21,7 @@ #include "board.h" #include "data.h" #include -#include +#include #include #include "plug_io.h" #include Index: trunk/src_plugins/export_vfs_mc/export_vfs_mc.c =================================================================== --- trunk/src_plugins/export_vfs_mc/export_vfs_mc.c (revision 31007) +++ trunk/src_plugins/export_vfs_mc/export_vfs_mc.c (revision 31008) @@ -11,7 +11,7 @@ #include "board.h" #include "data.h" #include -#include +#include #include #include "plug_io.h" Index: trunk/src_plugins/export_xy/xy.c =================================================================== --- trunk/src_plugins/export_xy/xy.c (revision 31007) +++ trunk/src_plugins/export_xy/xy.c (revision 31008) @@ -15,7 +15,7 @@ #include "data.h" #include "data_it.h" #include -#include +#include #include #include #include "obj_pstk_inlines.h" Index: trunk/src_plugins/exto_std/exto_std.c =================================================================== --- trunk/src_plugins/exto_std/exto_std.c (revision 31007) +++ trunk/src_plugins/exto_std/exto_std.c (revision 31008) @@ -35,7 +35,7 @@ #include #include #include "obj_subc.h" -#include +#include #include "extobj.h" #include "extobj_helper.h" #include "conf_core.h" Index: trunk/src_plugins/fontmode/fontmode.c =================================================================== --- trunk/src_plugins/fontmode/fontmode.c (revision 31007) +++ trunk/src_plugins/fontmode/fontmode.c (revision 31008) @@ -50,7 +50,7 @@ #include #include "flag_str.h" #include "undo.h" -#include +#include #include #include #include Index: trunk/src_plugins/fp_board/fp_board.c =================================================================== --- trunk/src_plugins/fp_board/fp_board.c (revision 31007) +++ trunk/src_plugins/fp_board/fp_board.c (revision 31008) @@ -11,7 +11,7 @@ #include "obj_subc_list.h" #include "obj_subc_op.h" #include -#include +#include #include "operation.h" #include "plug_io.h" #include Index: trunk/src_plugins/hid_batch/batch.c =================================================================== --- trunk/src_plugins/hid_batch/batch.c (revision 31007) +++ trunk/src_plugins/hid_batch/batch.c (revision 31008) @@ -9,7 +9,7 @@ #include #include "data.h" #include "layer.h" -#include +#include #include #include #include Index: trunk/src_plugins/hid_lesstif/dialogs.c =================================================================== --- trunk/src_plugins/hid_lesstif/dialogs.c (revision 31007) +++ trunk/src_plugins/hid_lesstif/dialogs.c (revision 31008) @@ -16,7 +16,7 @@ #include "build_run.h" #include "crosshair.h" #include "layer.h" -#include +#include #include #include "lesstif.h" Index: trunk/src_plugins/hid_lesstif/main.c =================================================================== --- trunk/src_plugins/hid_lesstif/main.c (revision 31007) +++ trunk/src_plugins/hid_lesstif/main.c (revision 31008) @@ -24,7 +24,7 @@ #include "crosshair.h" #include #include "layer.h" -#include +#include #include "event.h" #include #include Index: trunk/src_plugins/hid_lesstif/menu.c =================================================================== --- trunk/src_plugins/hid_lesstif/menu.c (revision 31007) +++ trunk/src_plugins/hid_lesstif/menu.c (revision 31008) @@ -11,7 +11,7 @@ #include "data.h" #include -#include +#include #include "layer.h" #include Index: trunk/src_plugins/hid_remote/proto.c =================================================================== --- trunk/src_plugins/hid_remote/proto.c (revision 31007) +++ trunk/src_plugins/hid_remote/proto.c (revision 31008) @@ -26,7 +26,7 @@ #include #include -#include +#include #define proto_vsnprintf rnd_vsnprintf #include "proto_lowcommon.h" #include "proto_lowsend.h" Index: trunk/src_plugins/hid_remote/remote.c =================================================================== --- trunk/src_plugins/hid_remote/remote.c (revision 31007) +++ trunk/src_plugins/hid_remote/remote.c (revision 31008) @@ -10,7 +10,7 @@ #include "data.h" #include "draw.h" #include "layer.h" -#include +#include #include #include #include "funchash_core.h" Index: trunk/src_plugins/import_calay/calay.c =================================================================== --- trunk/src_plugins/import_calay/calay.c (revision 31007) +++ trunk/src_plugins/import_calay/calay.c (revision 31008) @@ -36,7 +36,7 @@ #include "data.h" #include "plug_import.h" #include -#include +#include #include #include Index: trunk/src_plugins/import_fpcb_nl/fpcb_nl.c =================================================================== --- trunk/src_plugins/import_fpcb_nl/fpcb_nl.c (revision 31007) +++ trunk/src_plugins/import_fpcb_nl/fpcb_nl.c (revision 31008) @@ -37,7 +37,7 @@ #include "data.h" #include "plug_import.h" #include -#include +#include #include #include Index: trunk/src_plugins/import_hpgl/hpgl.c =================================================================== --- trunk/src_plugins/import_hpgl/hpgl.c (revision 31007) +++ trunk/src_plugins/import_hpgl/hpgl.c (revision 31008) @@ -39,7 +39,7 @@ #include "data.h" #include "buffer.h" #include -#include +#include #include #include Index: trunk/src_plugins/import_ltspice/ltspice.c =================================================================== --- trunk/src_plugins/import_ltspice/ltspice.c (revision 31007) +++ trunk/src_plugins/import_ltspice/ltspice.c (revision 31008) @@ -38,7 +38,7 @@ #include "data.h" #include "plug_import.h" #include -#include +#include #include #include #include Index: trunk/src_plugins/import_mentor_sch/mentor_sch.c =================================================================== --- trunk/src_plugins/import_mentor_sch/mentor_sch.c (revision 31007) +++ trunk/src_plugins/import_mentor_sch/mentor_sch.c (revision 31008) @@ -36,7 +36,7 @@ #include "data.h" #include "plug_import.h" #include -#include +#include #include #include Index: trunk/src_plugins/import_mentor_sch/netlist_helper.c =================================================================== --- trunk/src_plugins/import_mentor_sch/netlist_helper.c (revision 31007) +++ trunk/src_plugins/import_mentor_sch/netlist_helper.c (revision 31008) @@ -35,7 +35,7 @@ #include "netlist_helper.h" #include -#include +#include #include #include #include Index: trunk/src_plugins/import_mucs/mucs.c =================================================================== --- trunk/src_plugins/import_mucs/mucs.c (revision 31007) +++ trunk/src_plugins/import_mucs/mucs.c (revision 31008) @@ -41,7 +41,7 @@ #include "board.h" #include "data.h" #include -#include +#include #include #include Index: trunk/src_plugins/import_net_action/import_net_action.c =================================================================== --- trunk/src_plugins/import_net_action/import_net_action.c (revision 31007) +++ trunk/src_plugins/import_net_action/import_net_action.c (revision 31008) @@ -37,7 +37,7 @@ #include "plug_import.h" #include -#include +#include #include #include Index: trunk/src_plugins/import_tinycad/tinycad.c =================================================================== --- trunk/src_plugins/import_tinycad/tinycad.c (revision 31007) +++ trunk/src_plugins/import_tinycad/tinycad.c (revision 31008) @@ -38,7 +38,7 @@ #include "plug_import.h" #include -#include +#include #include #include Index: trunk/src_plugins/io_hyp/parser.c =================================================================== --- trunk/src_plugins/io_hyp/parser.c (revision 31007) +++ trunk/src_plugins/io_hyp/parser.c (revision 31008) @@ -25,7 +25,7 @@ #include "hyp_l.h" #include "hyp_y.h" #include -#include +#include #include "flag_str.h" #include "polygon.h" #include "board.h" Index: trunk/src_plugins/io_kicad/read_net.c =================================================================== --- trunk/src_plugins/io_kicad/read_net.c (revision 31007) +++ trunk/src_plugins/io_kicad/read_net.c (revision 31008) @@ -38,7 +38,7 @@ #include "data.h" #include "plug_import.h" #include -#include +#include #include #include Index: trunk/src_plugins/io_pcb/file.c =================================================================== --- trunk/src_plugins/io_pcb/file.c (revision 31007) +++ trunk/src_plugins/io_pcb/file.c (revision 31008) @@ -51,7 +51,7 @@ #include "layer_grp.h" #include "move.h" #include "parse_common.h" -#include +#include #include "polygon.h" #include #include "remove.h" Index: trunk/src_plugins/io_tedax/footprint.c =================================================================== --- trunk/src_plugins/io_tedax/footprint.c (revision 31007) +++ trunk/src_plugins/io_tedax/footprint.c (revision 31008) @@ -41,7 +41,7 @@ #include #include "data.h" #include "board.h" -#include +#include #include #include #include "obj_line.h" Index: trunk/src_plugins/io_tedax/tnetlist.c =================================================================== --- trunk/src_plugins/io_tedax/tnetlist.c (revision 31007) +++ trunk/src_plugins/io_tedax/tnetlist.c (revision 31008) @@ -37,7 +37,7 @@ #include "plug_io.h" #include #include -#include +#include #include #include #include Index: trunk/src_plugins/jostle/jostle.c =================================================================== --- trunk/src_plugins/jostle/jostle.c (revision 31007) +++ trunk/src_plugins/jostle/jostle.c (revision 31008) @@ -27,7 +27,7 @@ #include #include "remove.h" #include -#include +#include #include #include #include "layer.h" Index: trunk/src_plugins/lib_gtk_common/bu_menu.c =================================================================== --- trunk/src_plugins/lib_gtk_common/bu_menu.c (revision 31007) +++ trunk/src_plugins/lib_gtk_common/bu_menu.c (revision 31008) @@ -6,7 +6,7 @@ #include #include "board.h" -#include +#include #include #include #include Index: trunk/src_plugins/lib_gtk_common/dlg_attribute.c =================================================================== --- trunk/src_plugins/lib_gtk_common/dlg_attribute.c (revision 31007) +++ trunk/src_plugins/lib_gtk_common/dlg_attribute.c (revision 31008) @@ -35,7 +35,7 @@ #include "dlg_attribute.h" #include -#include +#include #include #include #include Index: trunk/src_plugins/lib_gtk_common/dlg_attributes.c =================================================================== --- trunk/src_plugins/lib_gtk_common/dlg_attributes.c (revision 31007) +++ trunk/src_plugins/lib_gtk_common/dlg_attributes.c (revision 31008) @@ -32,7 +32,7 @@ #include "dlg_attributes.h" #include -#include +#include #include #include #include Index: trunk/src_plugins/lib_gtk_common/dlg_topwin.c =================================================================== --- trunk/src_plugins/lib_gtk_common/dlg_topwin.c (revision 31007) +++ trunk/src_plugins/lib_gtk_common/dlg_topwin.c (revision 31008) @@ -48,7 +48,7 @@ #include "board.h" #include "crosshair.h" -#include +#include #include #include Index: trunk/src_plugins/lib_hid_pcbui/layer_menu.c =================================================================== --- trunk/src_plugins/lib_hid_pcbui/layer_menu.c (revision 31007) +++ trunk/src_plugins/lib_hid_pcbui/layer_menu.c (revision 31008) @@ -34,7 +34,7 @@ #include "layer.h" #include "layer_ui.h" #include "layer_grp.h" -#include +#include #include #include Index: trunk/src_plugins/lib_netmap/netmap.c =================================================================== --- trunk/src_plugins/lib_netmap/netmap.c (revision 31007) +++ trunk/src_plugins/lib_netmap/netmap.c (revision 31008) @@ -33,7 +33,7 @@ #include "data.h" #include "find.h" #include "netlist.h" -#include +#include #include static pcb_net_t *alloc_net(pcb_netmap_t *map) Index: trunk/src_plugins/lib_polyhelp/polyhelp.c =================================================================== --- trunk/src_plugins/lib_polyhelp/polyhelp.c (revision 31007) +++ trunk/src_plugins/lib_polyhelp/polyhelp.c (revision 31008) @@ -32,7 +32,7 @@ #include "polyhelp.h" #include "polygon.h" #include -#include +#include #include "obj_line.h" #include #include Index: trunk/src_plugins/lib_vfs/lib_vfs.c =================================================================== --- trunk/src_plugins/lib_vfs/lib_vfs.c (revision 31007) +++ trunk/src_plugins/lib_vfs/lib_vfs.c (revision 31008) @@ -29,7 +29,7 @@ #include "board.h" #include "data.h" #include -#include +#include #include #include Index: trunk/src_plugins/lib_wget/lib_wget.c =================================================================== --- trunk/src_plugins/lib_wget/lib_wget.c (revision 31007) +++ trunk/src_plugins/lib_wget/lib_wget.c (revision 31008) @@ -28,7 +28,7 @@ #include -#include +#include #include #include #include "lib_wget.h" Index: trunk/src_plugins/loghid/hid-logger.c =================================================================== --- trunk/src_plugins/loghid/hid-logger.c (revision 31007) +++ trunk/src_plugins/loghid/hid-logger.c (revision 31008) @@ -3,7 +3,7 @@ */ #include "config.h" #include "hid-logger.h" -#include +#include #include #define ENUM_LOG_TEXT(e) case e: txt = #e; break Index: trunk/src_plugins/order/order.c =================================================================== --- trunk/src_plugins/order/order.c (revision 31007) +++ trunk/src_plugins/order/order.c (revision 31008) @@ -31,7 +31,7 @@ #include #include "board.h" #include "data.h" -#include +#include #include #include #include Index: trunk/src_plugins/order_pcbway/pcbway.c =================================================================== --- trunk/src_plugins/order_pcbway/pcbway.c (revision 31007) +++ trunk/src_plugins/order_pcbway/pcbway.c (revision 31008) @@ -33,7 +33,7 @@ #include #include "board.h" -#include +#include #include #include #include Index: trunk/src_plugins/propedit/propedit.c =================================================================== --- trunk/src_plugins/propedit/propedit.c (revision 31007) +++ trunk/src_plugins/propedit/propedit.c (revision 31008) @@ -33,7 +33,7 @@ #include "propsel.h" #include "propdlg.h" #include -#include +#include #include #include "layer.h" #include "layer_addr.h" Index: trunk/src_plugins/propedit/props.c =================================================================== --- trunk/src_plugins/propedit/props.c (revision 31007) +++ trunk/src_plugins/propedit/props.c (revision 31008) @@ -28,7 +28,7 @@ #include "propsel.h" #include #include "board.h" -#include +#include #include #include /*#define HT_INVALID_VALUE ((pcb_propval_t){PCB_PROPT_invalid, {0}})*/ Index: trunk/src_plugins/propedit/propsel.c =================================================================== --- trunk/src_plugins/propedit/propsel.c (revision 31007) +++ trunk/src_plugins/propedit/propsel.c (revision 31008) @@ -37,7 +37,7 @@ #include "undo.h" #include "rotate.h" #include "obj_pstk_inlines.h" -#include +#include #include "conf_core.h" #include #include "netlist.h" Index: trunk/src_plugins/puller/puller.c =================================================================== --- trunk/src_plugins/puller/puller.c (revision 31007) +++ trunk/src_plugins/puller/puller.c (revision 31008) @@ -64,7 +64,7 @@ #include "data.h" #include "draw.h" #include "move.h" -#include +#include #include "remove.h" #include #include "flag_str.h" Index: trunk/src_plugins/query/query_exec.c =================================================================== --- trunk/src_plugins/query/query_exec.c (revision 31007) +++ trunk/src_plugins/query/query_exec.c (revision 31008) @@ -32,7 +32,7 @@ #include "query.h" #include "query_exec.h" #include "query_access.h" -#include +#include #define PCB dontuse Index: trunk/src_plugins/renumber/renumber.c =================================================================== --- trunk/src_plugins/renumber/renumber.c (revision 31007) +++ trunk/src_plugins/renumber/renumber.c (revision 31008) @@ -45,7 +45,7 @@ #include "netlist.h" #include -#include +#include static const char pcb_acts_Renumber[] = "Renumber()\n" "Renumber(filename)"; static const char pcb_acth_Renumber[] = Index: trunk/src_plugins/report/report.c =================================================================== --- trunk/src_plugins/report/report.c (revision 31007) +++ trunk/src_plugins/report/report.c (revision 31008) @@ -51,7 +51,7 @@ #include "undo.h" #include "find.h" #include "draw.h" -#include +#include #include #include #include Index: trunk/src_plugins/script/script.c =================================================================== --- trunk/src_plugins/script/script.c (revision 31007) +++ trunk/src_plugins/script/script.c (revision 31008) @@ -41,7 +41,7 @@ #include #include #include -#include +#include #include "globalconst.h" #include "script.h" Index: trunk/src_plugins/serpentine/serpentine.c =================================================================== --- trunk/src_plugins/serpentine/serpentine.c (revision 31007) +++ trunk/src_plugins/serpentine/serpentine.c (revision 31008) @@ -42,7 +42,7 @@ #include "find.h" #include "draw.h" #include "draw_wireframe.h" -#include +#include #include #include #include "serpentine_conf.h" Index: trunk/src_plugins/sketch_route/sketch_route.c =================================================================== --- trunk/src_plugins/sketch_route/sketch_route.c (revision 31007) +++ trunk/src_plugins/sketch_route/sketch_route.c (revision 31008) @@ -43,7 +43,7 @@ #include "obj_pstk.h" #include "obj_pstk_inlines.h" #include "obj_subc_parent.h" -#include +#include #include "search.h" #include #include "layer_ui.h" Index: trunk/tests/pcb-printf/prcli.c =================================================================== --- trunk/tests/pcb-printf/prcli.c (revision 31007) +++ trunk/tests/pcb-printf/prcli.c (revision 31008) @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include int main(int argc, char *argv[]) Index: trunk/tests/pcb-printf/prclimq.c =================================================================== --- trunk/tests/pcb-printf/prclimq.c (revision 31007) +++ trunk/tests/pcb-printf/prclimq.c (revision 31008) @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include int main(int argc, char *argv[]) Index: trunk/tests/pcb-printf/tester.c =================================================================== --- trunk/tests/pcb-printf/tester.c (revision 31007) +++ trunk/tests/pcb-printf/tester.c (revision 31008) @@ -1,7 +1,7 @@ #include #include #include "config.h" -#include +#include #ifdef SPEED char buff[8192]; Index: trunk/util/gsch2pcb-rnd/Makefile.in =================================================================== --- trunk/util/gsch2pcb-rnd/Makefile.in (revision 31007) +++ trunk/util/gsch2pcb-rnd/Makefile.in (revision 31008) @@ -41,7 +41,7 @@ FP_OBJS = @/local/pcb/OBJS@ ../../src/plug_footprint.o -CONF_OBJS = ../../src/vtlibrary.o $(LIBRND)/core/compat_fs.o $(LIBRND)/core/paths.o $(LIBRND)/core/conf.o ../../src/conf_core.o $(LIBRND)/core/hid_cfg.o $(LIBRND)/core/hidlib_conf.o $(LIBRND)/core/misc_util.o $(LIBRND)/core/unit.o ../../src/conf_internal.o $(LIBRND)/core/list_conf.o $(LIBRND)/core/conf_hid.o $(LIBRND)/core/pcb-printf.o $(LIBRND)/core/compat_misc.o $(LIBRND)/core/safe_fs.o +CONF_OBJS = ../../src/vtlibrary.o $(LIBRND)/core/compat_fs.o $(LIBRND)/core/paths.o $(LIBRND)/core/conf.o ../../src/conf_core.o $(LIBRND)/core/hid_cfg.o $(LIBRND)/core/hidlib_conf.o $(LIBRND)/core/misc_util.o $(LIBRND)/core/unit.o ../../src/conf_internal.o $(LIBRND)/core/list_conf.o $(LIBRND)/core/conf_hid.o $(LIBRND)/core/rnd_printf.o $(LIBRND)/core/compat_misc.o $(LIBRND)/core/safe_fs.o FP_LDFLAGS = @/local/pcb/LDFLAGS@ FP_CFLAGS = @/local/pcb/CFLAGS@ OBJS = \