Date: | 2012-05-01 01:03:10 (11 years 10 months ago) |
---|---|
Author: | Werner Almesberger |
Commit: | e99a9f470563ea39adc56b7d7ee2f08317002628 |
Message: | b2/: add parsing of part inventories (WIP) Also simplify representation of packaging variants. |
Files: |
b2/INV (1 diff) b2/db.c (1 diff) b2/db.h (2 diffs) b2/lang.h (1 diff) b2/lang.l (1 diff) b2/lang.y (5 diffs) |
Change Details
b2/INV | ||
---|---|---|
1 | FOO R101X CT 1234 1 USD 0 1 0.1 10 0.8 100 6 | |
2 | FOO R101X-T TR 1234 3000 USD 0 3000 13 |
b2/db.c | ||
---|---|---|
158 | 158 | } |
159 | 159 | |
160 | 160 | |
161 | void part_add_stock(struct part *part, struct stock *stock) | |
162 | { | |
163 | if (!part->stock) { | |
164 | part->stock = stock; | |
165 | return; | |
166 | } | |
167 | yyerrorf("part %s %s already has stock", part->domain, part->name); | |
168 | } | |
169 | ||
170 | ||
161 | 171 | void part_dump(FILE *file, const struct part *part) |
162 | 172 | { |
163 | 173 | const struct param *p; |
b2/db.h | ||
---|---|---|
28 | 28 | struct currency *next; |
29 | 29 | }; |
30 | 30 | |
31 | /* | |
32 | * If quantity increases, next entry is next higher discount. | |
33 | * If quantity decreases, next entries are prices after reaching the large | |
34 | * quantity. | |
35 | * | |
36 | * Examples: | |
37 | * | |
38 | * An order of 12 units with the prices below | |
39 | * | |
40 | * a) 1 0.5 10 4.0 100 30.0 | |
41 | * b) 1 0.5 10 4.0 1 0.4 100 30.0 | |
42 | * | |
43 | * would cost | |
44 | * | |
45 | * a) 1*4.0+2*0.5 = 5.0 | |
46 | * b) 1*4.0+2*0.4 = 4.8 | |
47 | */ | |
48 | ||
31 | 49 | struct price { |
32 | 50 | int qty; /* order quantity */ |
33 | 51 | double value; /* per quantity cost */ |
34 | const struct currency *curr; | |
35 | int fract; /* 0 if > qty at same price; 1 if multiples of qty */ | |
36 | struct price *next; /* next lower qty */ | |
52 | struct price *next; /* next qty */ | |
37 | 53 | }; |
38 | 54 | |
39 | 55 | struct provider { |
40 | 56 | const char *name; |
41 | 57 | double shipping; /* S&H cost */ |
42 | double minimum; /* minimum order */ | |
58 | double minimum; /* value of minimum order, before S&H */ | |
43 | 59 | const struct currency *curr; |
44 | 60 | struct provider *next; |
45 | 61 | }; |
46 | 62 | |
63 | /* | |
64 | * Handling of multiple forms of packaging: | |
65 | * | |
66 | * - category is a keyword that identifies the packaging type, e.g., | |
67 | * T for tape/tray, MAN for manual feeding, etc. | |
68 | * - a query can be constrained to a set of categories | |
69 | * - conversion options (e.g., "Digi-Reel") can be expressed as additional | |
70 | * entries | |
71 | * | |
72 | * @@@ To do: shared availability | |
73 | */ | |
74 | ||
47 | 75 | struct stock { |
76 | const char *cat; /* category */ | |
48 | 77 | int avail; /* items in stock */ |
49 | 78 | int package; /* "natural" quantity (reel, tray, bag, etc.) */ |
50 | struct price *manual; /* single parts, for manual assembly only */ | |
51 | double reeling; /* cost of converting "manual" to "fab"; <0 if n/a */ | |
52 | struct price *fab; /* for automated assembly */ | |
79 | const struct currency *curr; | |
80 | double add; /* additive element of cost */ | |
81 | struct price *price; | |
53 | 82 | } stock; |
54 | 83 | |
55 | 84 | struct part { |
... | ... | |
66 | 95 | struct part *part_add(const char *domain, const char *name); |
67 | 96 | void part_alias(struct part *a, struct part *b); |
68 | 97 | void part_finalize(struct part *part, const struct action *act); |
98 | void part_add_stock(struct part *part, struct stock *stock); | |
69 | 99 | void part_dump(FILE *file, const struct part *part); |
70 | 100 | |
71 | 101 | #endif /* !DB_H */ |
b2/lang.h | ||
---|---|---|
15 | 15 | |
16 | 16 | void parse_hierarchy(void); |
17 | 17 | void parse_characteristics(void); |
18 | void parse_inventory(void); | |
18 | 19 | |
19 | 20 | void yywarnf(const char *fmt, ...); |
20 | 21 | void yyerrorf(const char *fmt, ...); |
b2/lang.l | ||
---|---|---|
44 | 44 | yyparse(); |
45 | 45 | } |
46 | 46 | |
47 | ||
48 | void parse_inventory(void) | |
49 | { | |
50 | start_token = START_INVENTORY; | |
51 | expose_nl = 1; | |
52 | lineno = 1; | |
53 | yyparse(); | |
54 | } | |
55 | ||
47 | 56 | %} |
48 | 57 | |
49 | 58 |
b2/lang.y | ||
---|---|---|
64 | 64 | |
65 | 65 | %union { |
66 | 66 | const char *s; |
67 | int num; | |
68 | double fnum; | |
67 | 69 | struct equiv *equiv; |
68 | 70 | struct names *names; |
69 | 71 | struct format *format; |
... | ... | |
74 | 76 | struct action act; |
75 | 77 | struct part *part; |
76 | 78 | struct param *param; |
79 | struct price *price; | |
80 | struct stock *stock; | |
77 | 81 | }; |
78 | 82 | |
79 | 83 | |
80 | %token START_HIERARCHY START_CHAR | |
84 | %token START_HIERARCHY START_CHAR START_INVENTORY | |
81 | 85 | %token TOK_LE TOK_GE TOK_NL |
82 | 86 | %token <s> WORD |
83 | 87 | |
88 | %type <num> int | |
89 | %type <fnum> float | |
84 | 90 | %type <equiv> nameqs |
85 | 91 | %type <names> names nameq |
86 | 92 | %type <format> format |
... | ... | |
89 | 95 | %type <sel> selectors |
90 | 96 | %type <cond> conditions condition |
91 | 97 | %type <act> opt_wildcard action |
92 | %type <part> part | |
98 | %type <part> part inventory_item | |
93 | 99 | %type <param> param params |
100 | %type <price> prices price | |
101 | %type <stock> stock | |
94 | 102 | |
95 | 103 | %% |
96 | 104 | |
97 | 105 | all: |
98 | 106 | START_HIERARCHY hierarchy |
99 | 107 | | START_CHAR characteristics |
108 | | START_INVENTORY inventory | |
100 | 109 | ; |
101 | 110 | |
111 | ||
112 | /* ----- Characteristics hierarchy ----------------------------------------- */ | |
113 | ||
114 | ||
102 | 115 | hierarchy: |
103 | 116 | nameset hierarchy |
104 | 117 | | action |
... | ... | |
349 | 362 | } |
350 | 363 | ; |
351 | 364 | |
365 | ||
366 | /* ----- Part characteristics --------------------------------------------- */ | |
367 | ||
368 | ||
352 | 369 | characteristics: |
353 | 370 | | TOK_NL |
354 | 371 | | part characteristics |
... | ... | |
389 | 406 | $$->value.u.name = $3; |
390 | 407 | } |
391 | 408 | ; |
409 | ||
410 | ||
411 | /* ----- Part inventory ---------------------------------------------------- */ | |
412 | ||
413 | ||
414 | inventory: | |
415 | | TOK_NL | |
416 | | inventory_item inventory | |
417 | ; | |
418 | ||
419 | inventory_item: | |
420 | WORD WORD stock TOK_NL | |
421 | { | |
422 | $$ = part_lookup($1, $2); | |
423 | if (!$$) | |
424 | $$ = part_add($1, $2); | |
425 | part_add_stock($$, $3); | |
426 | } | |
427 | ; | |
428 | ||
429 | stock: | |
430 | WORD int int WORD float prices | |
431 | { | |
432 | $$ = alloc_type(struct stock); | |
433 | $$->cat = $1; | |
434 | $$->avail = $2; | |
435 | $$->package = $3; | |
436 | $$->curr = NULL; /* @@@ later -- currency($4); */ | |
437 | $$->add = $5; | |
438 | $$->price = $6; | |
439 | } | |
440 | ; | |
441 | ||
442 | prices: | |
443 | price | |
444 | { | |
445 | $$ = $1; | |
446 | } | |
447 | | price prices | |
448 | { | |
449 | $$ = $1; | |
450 | $$->next = $2; | |
451 | } | |
452 | ; | |
453 | ||
454 | price: | |
455 | int float | |
456 | { | |
457 | $$ = alloc_type(struct price); | |
458 | $$->qty = $1; | |
459 | $$->value = $2; | |
460 | $$->next = NULL; | |
461 | } | |
462 | ; | |
463 | ||
464 | int: | |
465 | WORD | |
466 | { | |
467 | char *end; | |
468 | ||
469 | $$ = strtol($1, &end, 10); | |
470 | if (*end) | |
471 | yyerrorf("\"%s\" is not an integer", $1); | |
472 | } | |
473 | ; | |
474 | ||
475 | float: | |
476 | WORD | |
477 | { | |
478 | char *end; | |
479 | ||
480 | $$ = strtod($1, &end); | |
481 | if (*end) | |
482 | yyerrorf("\"%s\" is not a number", $1); | |
483 | } | |
484 | ; |
Branches:
master