coord.c |
1 | 1 | /* |
2 | 2 | * coord.c - Coordinate representation and basic operations |
3 | 3 | * |
4 | | * Written 2009, 2010 by Werner Almesberger |
5 | | * Copyright 2009, 2010 by Werner Almesberger |
| 4 | * Written 2009, 2010, 2016 by Werner Almesberger |
| 5 | * Copyright 2009, 2010, 2016 by Werner Almesberger |
6 | 6 | * |
7 | 7 | * This program is free software; you can redistribute it and/or modify |
8 | 8 | * it under the terms of the GNU General Public License as published by |
... | ... | |
32 | 32 | } |
33 | 33 | |
34 | 34 | |
| 35 | double um_to_mm(double um, int exponent) |
| 36 | { |
| 37 | return um*pow(UM_IN_MM, exponent); |
| 38 | } |
| 39 | |
| 40 | |
35 | 41 | /* ----- convert internal units to best external unit ---------------------- */ |
36 | 42 | |
37 | 43 | |
coord.h |
1 | 1 | /* |
2 | 2 | * coord.h - Coordinate representation and basic operations |
3 | 3 | * |
4 | | * Written 2009, 2010 by Werner Almesberger |
5 | | * Copyright 2009, 2010 by Werner Almesberger |
| 4 | * Written 2009, 2010, 2016 by Werner Almesberger |
| 5 | * Copyright 2009, 2010, 2016 by Werner Almesberger |
6 | 6 | * |
7 | 7 | * This program is free software; you can redistribute it and/or modify |
8 | 8 | * it under the terms of the GNU General Public License as published by |
... | ... | |
20 | 20 | #define MICRON_UNITS 10 |
21 | 21 | #define MIL_UNITS (25.4*MICRON_UNITS) |
22 | 22 | #define MM_UNITS (1000.0*MICRON_UNITS) |
| 23 | #define UM_UNITS MICRON_UNITS |
23 | 24 | #define KICAD_UNIT (MIL_UNITS/10.0) |
24 | 25 | |
25 | 26 | #define MIL_IN_MM 0.0254 |
| 27 | #define UM_IN_MM 0.001 |
26 | 28 | |
27 | 29 | |
28 | 30 | typedef int32_t unit_type; |
... | ... | |
48 | 50 | } |
49 | 51 | |
50 | 52 | |
| 53 | static inline unit_type um_to_units(double mm) |
| 54 | { |
| 55 | return mm*UM_UNITS; |
| 56 | } |
| 57 | |
| 58 | |
51 | 59 | static inline double units_to_mm(unit_type u) |
52 | 60 | { |
53 | 61 | return (double) u/MM_UNITS; |
54 | 62 | } |
55 | 63 | |
56 | 64 | |
| 65 | static inline double units_to_um(unit_type u) |
| 66 | { |
| 67 | return (double) u/UM_UNITS; |
| 68 | } |
| 69 | |
| 70 | |
57 | 71 | static inline double units_to_mil(unit_type u) |
58 | 72 | { |
59 | 73 | return (double) u/MIL_UNITS; |
... | ... | |
74 | 88 | |
75 | 89 | double mm_to_mil(double mm, int exponent); |
76 | 90 | double mil_to_mm(double mil, int exponent); |
| 91 | double um_to_mm(double um, int exponent); |
77 | 92 | |
78 | 93 | double units_to_best(unit_type u, int *mm); |
79 | 94 | |
expr.c |
1 | 1 | /* |
2 | 2 | * expr.c - Expressions and values |
3 | 3 | * |
4 | | * Written 2009, 2010, 2012 by Werner Almesberger |
5 | | * Copyright 2009, 2010, 2012 by Werner Almesberger |
| 4 | * Written 2009, 2010, 2012, 2016 by Werner Almesberger |
| 5 | * Copyright 2009, 2010, 2012, 2016 by Werner Almesberger |
6 | 6 | * |
7 | 7 | * This program is free software; you can redistribute it and/or modify |
8 | 8 | * it under the terms of the GNU General Public License as published by |
... | ... | |
61 | 61 | case nt_mm: |
62 | 62 | unit = "mm"; |
63 | 63 | break; |
| 64 | case nt_um: |
| 65 | unit = "um"; |
| 66 | break; |
64 | 67 | case nt_mil: |
65 | 68 | unit = "mil"; |
66 | 69 | break; |
... | ... | |
78 | 81 | { |
79 | 82 | if (!is_distance(*n)) { |
80 | 83 | fail("%s^%d is not a distance", |
81 | | n->type == nt_mm ? "mm" : n->type == nt_mil ? "mil" : "?", |
82 | | n->exponent); |
| 84 | n->type == nt_mm ? "mm" : n->type == nt_um ? "um" : |
| 85 | n->type == nt_mil ? "mil" : "?", n->exponent); |
83 | 86 | return 0; |
84 | 87 | } |
85 | 88 | switch (n->type) { |
... | ... | |
89 | 92 | case nt_mm: |
90 | 93 | n->n = mm_to_units(n->n); |
91 | 94 | break; |
| 95 | case nt_um: |
| 96 | n->n = um_to_units(n->n); |
| 97 | break; |
92 | 98 | default: |
93 | 99 | abort(); |
94 | 100 | } |
... | ... | |
273 | 279 | /* ----- arithmetic -------------------------------------------------------- */ |
274 | 280 | |
275 | 281 | |
| 282 | static void converge_to_mm(struct num *a) |
| 283 | { |
| 284 | switch (a->type) { |
| 285 | case nt_mil: |
| 286 | a->type = nt_mm; |
| 287 | a->n = mil_to_mm(a->n, a->exponent); |
| 288 | break; |
| 289 | case nt_um: |
| 290 | a->type = nt_mm; |
| 291 | a->n = um_to_mm(a->n, a->exponent); |
| 292 | break; |
| 293 | case nt_mm: |
| 294 | break; |
| 295 | default: |
| 296 | abort(); |
| 297 | } |
| 298 | } |
| 299 | |
| 300 | |
276 | 301 | static struct num compatible_sum(struct num *a, struct num *b) |
277 | 302 | { |
278 | 303 | struct num res; |
279 | 304 | |
280 | 305 | if (a->type != b->type) { |
281 | | if (a->type == nt_mil) { |
282 | | a->type = nt_mm; |
283 | | a->n = mil_to_mm(a->n, a->exponent); |
284 | | } |
285 | | if (b->type == nt_mil) { |
286 | | b->type = nt_mm; |
287 | | b->n = mil_to_mm(b->n, a->exponent); |
288 | | } |
| 306 | converge_to_mm(a); |
| 307 | converge_to_mm(b); |
289 | 308 | } |
290 | 309 | if (a->exponent != b->exponent) { |
291 | 310 | fail("incompatible exponents (%d, %d)", |
... | ... | |
305 | 324 | struct num res; |
306 | 325 | |
307 | 326 | if (a->type != b->type) { |
308 | | if (a->type == nt_mil) { |
309 | | a->type = nt_mm; |
310 | | a->n = mil_to_mm(a->n, a->exponent); |
311 | | } |
312 | | if (b->type == nt_mil) { |
313 | | b->type = nt_mm; |
314 | | b->n = mil_to_mm(b->n, b->exponent); |
315 | | } |
| 327 | converge_to_mm(a); |
| 328 | converge_to_mm(b); |
316 | 329 | } |
317 | 330 | res.type = a->type; |
318 | 331 | res.exponent = exponent; |
expr.h |
1 | 1 | /* |
2 | 2 | * expr.h - Expressions and values |
3 | 3 | * |
4 | | * Written 2009, 2012 by Werner Almesberger |
5 | | * Copyright 2009, 2012 by Werner Almesberger |
| 4 | * Written 2009, 2012, 2016 by Werner Almesberger |
| 5 | * Copyright 2009, 2012, 2016 by Werner Almesberger |
6 | 6 | * |
7 | 7 | * This program is free software; you can redistribute it and/or modify |
8 | 8 | * it under the terms of the GNU General Public License as published by |
... | ... | |
27 | 27 | enum num_type { |
28 | 28 | nt_none, |
29 | 29 | nt_mm, |
| 30 | nt_um, |
30 | 31 | nt_mil, |
31 | 32 | }; |
32 | 33 | |
... | ... | |
63 | 64 | |
64 | 65 | static inline int is_distance(struct num num) |
65 | 66 | { |
66 | | return (num.type == nt_mm || num.type == nt_mil) && num.exponent == 1; |
| 67 | return (num.type == nt_mm || num.type == nt_um || num.type == nt_mil) |
| 68 | && num.exponent == 1; |
67 | 69 | } |
68 | 70 | |
69 | 71 | |
... | ... | |
94 | 96 | } |
95 | 97 | |
96 | 98 | |
| 99 | static inline struct num make_um(double um) |
| 100 | { |
| 101 | struct num res; |
| 102 | |
| 103 | res.type = nt_um; |
| 104 | res.exponent = 1; |
| 105 | res.n = um; |
| 106 | return res; |
| 107 | } |
| 108 | |
| 109 | |
97 | 110 | static inline struct num make_mil(double mil) |
98 | 111 | { |
99 | 112 | struct num res; |
fpd.l |
2 | 2 | /* |
3 | 3 | * fpd.l - FootPrint Definition language |
4 | 4 | * |
5 | | * Written 2009, 2010, 2012 by Werner Almesberger |
6 | | * Copyright 2009, 2010, 2012 by Werner Almesberger |
| 5 | * Written 2009, 2010, 2012, 2016 by Werner Almesberger |
| 6 | * Copyright 2009, 2010, 2016 by Werner Almesberger |
7 | 7 | * |
8 | 8 | * This program is free software; you can redistribute it and/or modify |
9 | 9 | * it under the terms of the GNU General Public License as published by |
... | ... | |
164 | 164 | yylval.num.exponent = 1; |
165 | 165 | sscanf(yytext, "%lf", &yylval.num.n); |
166 | 166 | return NUMBER; } |
| 167 | {NUM}{SP}um { yylval.num.type = nt_um; |
| 168 | yylval.num.exponent = 1; |
| 169 | sscanf(yytext, "%lf", &yylval.num.n); |
| 170 | return NUMBER; } |
167 | 171 | {NUM}{SP}mil { yylval.num.type = nt_mil; |
168 | 172 | yylval.num.exponent = 1; |
169 | 173 | sscanf(yytext, "%lf", &yylval.num.n); |
test/um |
| 1 | #!/bin/sh |
| 2 | . ./Common |
| 3 | |
| 4 | ############################################################################### |
| 5 | |
| 6 | fped "um: iprint micrometers" <<EOF |
| 7 | %iprint 100um |
| 8 | EOF |
| 9 | expect <<EOF |
| 10 | 100um |
| 11 | EOF |
| 12 | |
| 13 | #------------------------------------------------------------------------------ |
| 14 | |
| 15 | fped "um: add mm + um" <<EOF |
| 16 | %iprint 1mm + 100 um |
| 17 | EOF |
| 18 | expect <<EOF |
| 19 | 1.1mm |
| 20 | EOF |
| 21 | |
| 22 | #------------------------------------------------------------------------------ |
| 23 | |
| 24 | fped "um: subtract mil - um" <<EOF |
| 25 | %iprint 100mil - 100 um |
| 26 | EOF |
| 27 | expect <<EOF |
| 28 | 2.44mm |
| 29 | EOF |
| 30 | |
| 31 | #------------------------------------------------------------------------------ |
| 32 | |
| 33 | fped "um: multiply um with um" <<EOF |
| 34 | %iprint 100um * 50um |
| 35 | EOF |
| 36 | expect <<EOF |
| 37 | 5000um^2 |
| 38 | EOF |
| 39 | |
| 40 | #------------------------------------------------------------------------------ |
| 41 | |
| 42 | fped "um: multiply um with mm" <<EOF |
| 43 | %iprint 100um * 2mm |
| 44 | EOF |
| 45 | expect <<EOF |
| 46 | 0.2mm^2 |
| 47 | EOF |
| 48 | |
| 49 | #------------------------------------------------------------------------------ |
| 50 | |
| 51 | fped "um: divide mil by um" <<EOF |
| 52 | %iprint 20mil / 10um |
| 53 | EOF |
| 54 | expect <<EOF |
| 55 | 50.8 |
| 56 | EOF |
| 57 | |
| 58 | #------------------------------------------------------------------------------ |
| 59 | |
| 60 | fped_dump "um: use um in vector" <<EOF |
| 61 | vec @(100um, 50um) |
| 62 | EOF |
| 63 | expect <<EOF |
| 64 | /* MACHINE-GENERATED ! */ |
| 65 | |
| 66 | package "_" |
| 67 | unit mm |
| 68 | |
| 69 | __0: vec @(100um, 50um) |
| 70 | EOF |
| 71 | |
| 72 | #------------------------------------------------------------------------------ |
| 73 | |
| 74 | fped "um: measure distance in um" <<EOF |
| 75 | a: vec @(0mm, 0mm) |
| 76 | b: vec .(300um, 0mm) |
| 77 | c: vec .(0mm, 400um) |
| 78 | meas a >> c /* dummy */ |
| 79 | m: meas a >> c |
| 80 | |
| 81 | %meas m |
| 82 | EOF |
| 83 | expect <<EOF |
| 84 | 0.5 |
| 85 | EOF |