obj.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606
  1. /*
  2. * obj.c - Object definition model
  3. *
  4. * Written 2009-2012 by Werner Almesberger
  5. * Copyright 2009-2012 by Werner Almesberger
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. */
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #include <assert.h>
  15. #include "util.h"
  16. #include "error.h"
  17. #include "expr.h"
  18. #include "bitset.h"
  19. #include "meas.h"
  20. #include "inst.h"
  21. #include "hole.h"
  22. #include "overlap.h"
  23. #include "layer.h"
  24. #include "delete.h"
  25. #include "fpd.h"
  26. #include "obj.h"
  27. #define DEFAULT_SILK_WIDTH make_mil(15) /* @@@ */
  28. #define DEFAULT_OFFSET make_mil(0) /* @@@ */
  29. #define MAX_ITERATIONS 1000 /* abort "loop"s at this limit */
  30. char *pkg_name = NULL;
  31. struct frame *frames = NULL;
  32. struct frame *active_frame = NULL;
  33. void *instantiation_error = NULL;
  34. enum allow_overlap allow_overlap = ao_none;
  35. int holes_linked = 1;
  36. static struct bitset *frame_set; /* frames visited in "call chain" */
  37. /* ----- Searching --------------------------------------------------------- */
  38. /*
  39. * @@@ Known bug: we should compare all parameters of an instance, not just the
  40. * object's base or the vectors end.
  41. */
  42. static int found = 0;
  43. static int search_suspended = 0;
  44. static const struct vec *find_vec = NULL;
  45. static const struct obj *find_obj = NULL;
  46. static struct coord find_pos;
  47. static void suspend_search(void)
  48. {
  49. search_suspended++;
  50. }
  51. static void resume_search(void)
  52. {
  53. assert(search_suspended > 0);
  54. search_suspended--;
  55. }
  56. static struct coord get_pos(const struct inst *inst)
  57. {
  58. return inst->obj ? inst->base : inst->u.vec.end;
  59. }
  60. void find_inst(const struct inst *inst)
  61. {
  62. struct coord pos;
  63. if (search_suspended)
  64. return;
  65. if (find_vec != inst->vec)
  66. return;
  67. if (find_obj != inst->obj)
  68. return;
  69. pos = get_pos(inst);
  70. if (pos.x != find_pos.x || pos.y != find_pos.y)
  71. return;
  72. found++;
  73. }
  74. void search_inst(const struct inst *inst)
  75. {
  76. find_vec = inst->vec;
  77. find_obj = inst->obj;
  78. find_pos = get_pos(inst);
  79. }
  80. /* ----- Get the list of anchors of an object ------------------------------ */
  81. int obj_anchors(struct obj *obj, struct vec ***anchors)
  82. {
  83. anchors[0] = &obj->base;
  84. switch (obj->type) {
  85. case ot_frame:
  86. return 1;
  87. case ot_rect:
  88. case ot_line:
  89. anchors[1] = &obj->u.rect.other;
  90. return 2;
  91. case ot_pad:
  92. anchors[1] = &obj->u.pad.other;
  93. return 2;
  94. case ot_hole:
  95. anchors[1] = &obj->u.hole.other;
  96. return 2;
  97. case ot_meas:
  98. anchors[1] = &obj->u.meas.high;
  99. return 2;
  100. case ot_arc:
  101. /*
  102. * Put end point first so that this is what we grab if dragging
  103. * a circle (thereby turning it into an arc).
  104. */
  105. anchors[1] = &obj->u.arc.end;
  106. anchors[2] = &obj->u.arc.start;
  107. return 3;
  108. default:
  109. abort();
  110. }
  111. }
  112. /* ----- Instantiation ----------------------------------------------------- */
  113. static int generate_frame(struct frame *frame, struct coord base,
  114. const struct frame *parent, struct obj *frame_ref, int active);
  115. struct num eval_unit(const struct expr *expr, const struct frame *frame);
  116. /*static*/ struct num eval_unit(const struct expr *expr, const struct frame *frame)
  117. {
  118. struct num d;
  119. d = eval_num(expr, frame);
  120. if (!is_undef(d) && to_unit(&d))
  121. return d;
  122. fail_expr(expr);
  123. return undef;
  124. }
  125. static struct num eval_unit_default(const struct expr *expr,
  126. const struct frame *frame, struct num def)
  127. {
  128. if (expr)
  129. return eval_unit(expr, frame);
  130. to_unit(&def);
  131. return def;
  132. }
  133. static int recurse_vec(const char *name, const struct frame *frame,
  134. struct coord *res)
  135. {
  136. const struct vec *v;
  137. if (!frame)
  138. return 0;
  139. for (v = frame->vecs; v; v = v->next)
  140. if (v->name == name) {
  141. *res = v->pos;
  142. return 1;
  143. }
  144. return recurse_vec(name, frame->curr_parent, res);
  145. }
  146. static int resolve_vec(const struct vec *vec, struct coord base_pos,
  147. const struct frame *frame, struct coord *res)
  148. {
  149. const char *name = (const char *) vec;
  150. if (!vec) {
  151. *res = base_pos;
  152. return 1;
  153. }
  154. if (!*name) {
  155. *res = vec->pos;
  156. return 1;
  157. }
  158. if (recurse_vec(name, frame->curr_parent, res))
  159. return 1;
  160. fail("unknown vector \"%s\"", name);
  161. return 0;
  162. }
  163. static int generate_vecs(struct frame *frame, struct coord base_pos)
  164. {
  165. struct coord vec_base;
  166. struct vec *vec;
  167. struct num x, y;
  168. for (vec = frame->vecs; vec; vec = vec->next) {
  169. x = eval_unit(vec->x, frame);
  170. if (is_undef(x))
  171. goto error;
  172. y = eval_unit(vec->y, frame);
  173. if (is_undef(y))
  174. goto error;
  175. if (!resolve_vec(vec->base, base_pos, frame, &vec_base))
  176. goto error;
  177. vec->pos = vec_base;
  178. vec->pos.x += x.n;
  179. vec->pos.y += y.n;
  180. if (!inst_vec(vec, vec_base))
  181. goto error;
  182. meas_post(vec, vec->pos, frame_set);
  183. }
  184. return 1;
  185. error:
  186. instantiation_error = vec;
  187. return 0;
  188. }
  189. static int generate_objs(struct frame *frame, struct coord base_pos,
  190. int active)
  191. {
  192. struct obj *obj;
  193. char *name;
  194. int ok;
  195. struct num width, offset;
  196. struct coord base, other, start, end;
  197. for (obj = frame->objs; obj; obj = obj->next) {
  198. if (obj->type != ot_meas)
  199. if (!resolve_vec(obj->base, base_pos, frame, &base))
  200. goto error;
  201. switch (obj->type) {
  202. case ot_frame:
  203. if (!generate_frame(obj->u.frame.ref, base, frame, obj,
  204. active && obj->u.frame.ref->active_ref == obj))
  205. return 0;
  206. break;
  207. case ot_line:
  208. if (!resolve_vec(obj->u.line.other, base_pos, frame,
  209. &other))
  210. goto error;
  211. width = eval_unit_default(obj->u.line.width, frame,
  212. DEFAULT_SILK_WIDTH);
  213. if (is_undef(width))
  214. goto error;
  215. if (!inst_line(obj, base, other, width.n))
  216. goto error;
  217. break;
  218. case ot_rect:
  219. if (!resolve_vec(obj->u.rect.other, base_pos, frame,
  220. &other))
  221. goto error;
  222. width = eval_unit_default(obj->u.rect.width, frame,
  223. DEFAULT_SILK_WIDTH);
  224. if (is_undef(width))
  225. goto error;
  226. if (!inst_rect(obj, base, other, width.n))
  227. goto error;
  228. break;
  229. case ot_pad:
  230. if (!resolve_vec(obj->u.pad.other, base_pos, frame,
  231. &other))
  232. goto error;
  233. name = expand(obj->u.pad.name, frame);
  234. if (!name)
  235. goto error;
  236. ok = inst_pad(obj, name, base, other);
  237. free(name);
  238. if (!ok)
  239. goto error;
  240. break;
  241. case ot_hole:
  242. if (!resolve_vec(obj->u.hole.other, base_pos, frame,
  243. &other))
  244. goto error;
  245. if (!inst_hole(obj, base, other))
  246. goto error;
  247. break;
  248. case ot_arc:
  249. if (!resolve_vec(obj->u.arc.start, base_pos, frame,
  250. &start))
  251. goto error;
  252. if (!resolve_vec(obj->u.arc.end, base_pos, frame,
  253. &end))
  254. goto error;
  255. width = eval_unit_default(obj->u.arc.width, frame,
  256. DEFAULT_SILK_WIDTH);
  257. if (is_undef(width))
  258. goto error;
  259. if (!inst_arc(obj, base, start, end, width.n))
  260. goto error;
  261. break;
  262. case ot_meas:
  263. assert(frame == frames);
  264. offset = eval_unit_default(obj->u.meas.offset, frame,
  265. DEFAULT_OFFSET);
  266. if (is_undef(offset))
  267. goto error;
  268. inst_meas_hint(obj, offset.n);
  269. break;
  270. case ot_iprint:
  271. dbg_print(obj->u.iprint.expr, frame);
  272. break;
  273. default:
  274. abort();
  275. }
  276. }
  277. return 1;
  278. error:
  279. instantiation_error = obj;
  280. return 0;
  281. }
  282. static int generate_items(struct frame *frame, struct coord base, int active)
  283. {
  284. char *s;
  285. int ok;
  286. if (frame == frames) {
  287. s = expand(pkg_name, frame);
  288. /* s is NULL if expansion failed */
  289. inst_select_pkg(s ? s : "_", active);
  290. free(s);
  291. }
  292. inst_begin_active(active && frame == active_frame);
  293. ok = generate_vecs(frame, base) && generate_objs(frame, base, active);
  294. inst_end_active();
  295. return ok;
  296. }
  297. static int match_keys(struct frame *frame, struct coord base, int active)
  298. {
  299. const struct table *table;
  300. const struct var *var;
  301. const struct value *value;
  302. int res;
  303. for (table = frame->tables; table; table = table->next) {
  304. value = table->curr_row->values;
  305. for (var = table->vars; var; var = var->next) {
  306. if (var->key) {
  307. res = var_eq(frame, var->name, value->expr);
  308. if (!res)
  309. return 1;
  310. if (res < 0)
  311. return 0;
  312. }
  313. value = value->next;
  314. }
  315. }
  316. return generate_items(frame, base, active);
  317. }
  318. static int run_loops(struct frame *frame, struct loop *loop,
  319. struct coord base, int active)
  320. {
  321. struct num from, to;
  322. int n;
  323. int found_before, ok;
  324. if (!loop)
  325. return match_keys(frame, base, active);
  326. from = eval_num(loop->from.expr, frame);
  327. if (is_undef(from)) {
  328. fail_expr(loop->from.expr);
  329. instantiation_error = loop;
  330. return 0;
  331. }
  332. if (!is_dimensionless(from)) {
  333. fail("incompatible type for start value");
  334. fail_expr(loop->from.expr);
  335. instantiation_error = loop;
  336. return 0;
  337. }
  338. to = eval_num(loop->to.expr, frame);
  339. if (is_undef(to)) {
  340. fail_expr(loop->to.expr);
  341. instantiation_error = loop;
  342. return 0;
  343. }
  344. if (!is_dimensionless(to)) {
  345. fail("incompatible type for end value");
  346. fail_expr(loop->to.expr);
  347. instantiation_error = loop;
  348. return 0;
  349. }
  350. assert(!loop->initialized);
  351. loop->curr_value = from.n;
  352. loop->initialized = 1;
  353. n = 0;
  354. for (; loop->curr_value <= to.n; loop->curr_value += 1) {
  355. if (n >= MAX_ITERATIONS) {
  356. fail("%s: too many iterations (%d)", loop->var.name,
  357. MAX_ITERATIONS);
  358. instantiation_error = loop;
  359. goto fail;
  360. }
  361. found_before = found;
  362. if (loop->found == loop->active)
  363. suspend_search();
  364. ok = run_loops(frame, loop->next, base,
  365. active && loop->active == n);
  366. if (loop->found == loop->active)
  367. resume_search();
  368. if (!ok)
  369. goto fail;
  370. if (found_before != found)
  371. loop->found = n;
  372. n++;
  373. }
  374. loop->initialized = 0;
  375. loop->curr_value = UNDEF;
  376. if (active) {
  377. loop->n = from.n;
  378. loop->iterations = n;
  379. }
  380. return 1;
  381. fail:
  382. loop->initialized = 0;
  383. return 0;
  384. }
  385. static int iterate_tables(struct frame *frame, struct table *table,
  386. struct coord base, int active)
  387. {
  388. int found_before, ok;
  389. if (!table)
  390. return run_loops(frame, frame->loops, base, active);
  391. for (table->curr_row = table->rows; table->curr_row;
  392. table->curr_row = table->curr_row->next) {
  393. found_before = found;
  394. if (table->found_row == table->active_row)
  395. suspend_search();
  396. ok = iterate_tables(frame, table->next, base,
  397. active && table->active_row == table->curr_row);
  398. if (table->found_row == table->active_row)
  399. resume_search();
  400. if (!ok)
  401. return 0;
  402. if (found_before != found)
  403. table->found_row = table->curr_row;
  404. }
  405. return 1;
  406. }
  407. static int generate_frame(struct frame *frame, struct coord base,
  408. const struct frame *parent, struct obj *frame_ref, int active)
  409. {
  410. int ok;
  411. /*
  412. * We ensure during construction that frames can never recurse.
  413. */
  414. inst_begin_frame(frame_ref, frame, base,
  415. active && parent == active_frame,
  416. active && frame == active_frame);
  417. bitset_set(frame_set, frame->n);
  418. frame->curr_parent = parent;
  419. ok = iterate_tables(frame, frame->tables, base, active);
  420. inst_end_frame(frame);
  421. bitset_clear(frame_set, frame->n);
  422. frame->curr_parent = NULL;
  423. return ok;
  424. }
  425. static void reset_all_loops(void)
  426. {
  427. const struct frame *frame;
  428. struct loop *loop;
  429. for (frame = frames; frame; frame = frame->next)
  430. for (loop = frame->loops; loop; loop = loop->next)
  431. loop->iterations = 0;
  432. }
  433. static void reset_found(void)
  434. {
  435. struct frame *frame;
  436. struct table *table;
  437. struct loop *loop;
  438. for (frame = frames; frame; frame = frame->next) {
  439. for (table = frame->tables; table; table = table->next)
  440. table->found_row = NULL;
  441. for (loop = frame->loops; loop; loop = loop->next)
  442. loop->found = -1;
  443. frame->found_ref = NULL;
  444. }
  445. }
  446. /*
  447. * Note: we don't use frame->found_ref yet. Instead, we adjust the frame
  448. * references with activate_item in inst.c
  449. */
  450. static void activate_found(void)
  451. {
  452. struct frame *frame;
  453. struct table *table;
  454. struct loop *loop;
  455. for (frame = frames; frame; frame = frame->next) {
  456. for (table = frame->tables; table; table = table->next)
  457. if (table->found_row)
  458. table->active_row = table->found_row;
  459. for (loop = frame->loops; loop; loop = loop->next)
  460. if (loop->found != -1)
  461. loop->active = loop->found;
  462. if (frame->found_ref)
  463. frame->active_ref = frame->found_ref;
  464. }
  465. }
  466. static int enumerate_frames(void)
  467. {
  468. struct frame *frame;
  469. int n = 0;
  470. for (frame = frames; frame; frame = frame->next)
  471. frame->n = n++;
  472. return n;
  473. }
  474. int instantiate(void)
  475. {
  476. struct coord zero = { 0, 0 };
  477. int n_frames;
  478. int ok;
  479. meas_start();
  480. inst_start();
  481. n_frames = enumerate_frames();
  482. frame_set = bitset_new(n_frames);
  483. instantiation_error = NULL;
  484. reset_all_loops();
  485. reset_found();
  486. found = 0;
  487. search_suspended = 0;
  488. ok = generate_frame(frames, zero, NULL, NULL, 1);
  489. if (ok && (find_vec || find_obj) && found)
  490. activate_found();
  491. find_vec = NULL;
  492. find_obj = NULL;
  493. if (ok)
  494. ok = link_holes(holes_linked);
  495. if (ok)
  496. ok = refine_layers(allow_overlap);
  497. if (ok)
  498. ok = instantiate_meas(n_frames);
  499. if (ok)
  500. inst_commit();
  501. else
  502. inst_revert();
  503. bitset_free(frame_set);
  504. return ok;
  505. }
  506. /* ----- deallocation ------------------------------------------------------ */
  507. void obj_cleanup(void)
  508. {
  509. free(pkg_name);
  510. while (frames) {
  511. delete_frame(frames);
  512. destroy();
  513. }
  514. }