r5421 - trunk/eda/fped

werner at docs.openmoko.org werner at docs.openmoko.org
Wed Aug 12 01:26:38 CEST 2009


Author: werner
Date: 2009-08-12 01:26:38 +0200 (Wed, 12 Aug 2009)
New Revision: 5421

Added:
   trunk/eda/fped/fbga.fpd
Modified:
   trunk/eda/fped/TODO
   trunk/eda/fped/expr.c
   trunk/eda/fped/expr.h
   trunk/eda/fped/file.c
   trunk/eda/fped/file.h
   trunk/eda/fped/fped.c
   trunk/eda/fped/gui_frame.c
   trunk/eda/fped/unparse.c
Log:
- added support for string constants to unparse()
- implemented eval_str
- expand() now tries to obtain a string
- added example fbga.fpd to demonstrate use of strings
- when invoked with an inexisting file, fped now starts with an empty model,
  instead of getting confused 
- we now religiously call edit_nothing before adding fields to edit, so that
  we won't create a loop through edit-next



Modified: trunk/eda/fped/TODO
===================================================================
--- trunk/eda/fped/TODO	2009-08-11 21:54:18 UTC (rev 5420)
+++ trunk/eda/fped/TODO	2009-08-11 23:26:38 UTC (rev 5421)
@@ -39,6 +39,9 @@
 - code organization is very poor. E.g., functions belonging to the different
   items (pads, silk objects, vectors, etc.) should be grouped by item, not by
   type of function, similar to how some things are now with gui_meas.c
+- eval_string_var should be merged into eval_var and the result should be a
+  struct num (?) that can contain both types. This also means changing all the
+  ops to handle/reject strings.
 
 Open decisions:
 - Q: should loop be (start, last) or (start, iterations) ? or start ... last ?

Modified: trunk/eda/fped/expr.c
===================================================================
--- trunk/eda/fped/expr.c	2009-08-11 21:54:18 UTC (rev 5420)
+++ trunk/eda/fped/expr.c	2009-08-11 23:26:38 UTC (rev 5421)
@@ -154,6 +154,38 @@
 }
 
 
+static const char *eval_string_var(const struct frame *frame, const char *name)
+{
+	const struct table *table;
+	const struct loop *loop;
+	const struct value *value;
+	struct var *var;
+	const char *res;
+
+	for (table = frame->tables; table; table = table->next) {
+		value = table->curr_row->values;
+		for (var = table->vars; var; var = var->next) {
+			if (var->name == name) {
+				if (var->visited)
+					return NULL;
+				var->visited = 1;
+				res = eval_str(value->expr, frame);
+				var->visited = 0;
+				return res;
+				
+			}
+			value = value->next;
+		}
+	}
+	for (loop = frame->loops; loop; loop = loop->next)
+		if (loop->var.name == name)
+			return NULL;
+	if (frame->curr_parent)
+		return eval_string_var(frame->curr_parent, name);
+	return NULL;
+}
+
+
 struct num op_var(const struct expr *self, const struct frame *frame)
 {
 	struct num res;
@@ -307,9 +339,13 @@
 }
 
 
-char *eval_str(const struct frame *frame, const struct expr *expr)
+const char *eval_str(const struct expr *expr, const struct frame *frame)
 {
-	abort();
+	if (expr->op == op_string)
+		return expr->u.str;
+	if (expr->op == op_var)
+		return eval_string_var(frame, expr->u.var);
+	return NULL;
 }
 
 
@@ -329,7 +365,7 @@
 	char num_buf[100]; /* enough :-) */
 	const char *s, *s0;
 	char *var;
-	const char *var_unique;
+	const char *var_unique, *value_string;
 	struct num value;
 	int i, value_len;
 
@@ -366,18 +402,24 @@
 			continue;
 		var_unique = unique(var);
 		free(var);
-		value = eval_var(frame, var_unique);
-		if (is_undef(value)) {
-			fail("undefined variable \"%s\"", var_unique);
-			goto fail;
+		value_string = eval_string_var(frame, var_unique);
+		if (value_string)
+			value_len = strlen(value_string);
+		else {
+			value = eval_var(frame, var_unique);
+			if (is_undef(value)) {
+				fail("undefined variable \"%s\"", var_unique);
+				goto fail;
+			}
+			value_len = snprintf(num_buf, sizeof(num_buf), "%lg%s",
+			    value.n, str_unit(value));
+			value_string = num_buf;
 		}
-		value_len = snprintf(num_buf, sizeof(num_buf), "%lg%s",
-		    value.n, str_unit(value));
 		len += value_len;
 		buf = realloc(buf, len+1);
 		if (!buf)
 			abort();
-		strcpy(buf+i, num_buf);
+		strcpy(buf+i, value_string);
 		i += value_len;
 	}
 	buf[i] = 0;
@@ -410,6 +452,7 @@
 void scan_expr(const char *s);
 int yyparse(void);
 
+
 struct expr *expr_result;
 
 
@@ -422,14 +465,15 @@
 
 static void vacate_op(struct expr *expr)
 {
-	if (expr->op == &op_num || expr->op == &op_var)
+	if (expr->op == op_num || expr->op == op_string ||
+	    expr->op == op_var)
 		return;
-	if (expr->op == &op_minus) {
+	if (expr->op == op_minus) {
 		free_expr(expr->u.op.a);
 		return;
 	}
-	if (expr->op == &op_add || expr->op == &op_sub ||
-	    expr->op == &op_mult || expr->op == &op_div) {
+	if (expr->op == op_add || expr->op == op_sub ||
+	    expr->op == op_mult || expr->op == op_div) {
 		free_expr(expr->u.op.a);
 		free_expr(expr->u.op.b);
 		return;

Modified: trunk/eda/fped/expr.h
===================================================================
--- trunk/eda/fped/expr.h	2009-08-11 21:54:18 UTC (rev 5420)
+++ trunk/eda/fped/expr.h	2009-08-11 23:26:38 UTC (rev 5421)
@@ -121,7 +121,13 @@
 struct expr *binary_op(op_type op, struct expr *a, struct expr *b);
 
 struct num eval_var(const struct frame *frame, const char *name);
-char *eval_str(const struct frame *frame, const struct expr *expr);
+
+/*
+ * eval_str returns NULL if the result isn't a string. Evaluation may then
+ * be attempted with eval_num, and the result can be converted accordingly.
+ */
+const char *eval_str(const struct expr *expr, const struct frame *frame);
+
 struct num eval_num(const struct expr *expr, const struct frame *frame);
 
 /* if frame == NULL, we only check the syntax without expanding */

Added: trunk/eda/fped/fbga.fpd
===================================================================
--- trunk/eda/fped/fbga.fpd	                        (rev 0)
+++ trunk/eda/fped/fbga.fpd	2009-08-11 23:26:38 UTC (rev 5421)
@@ -0,0 +1,52 @@
+/* MACHINE-GENERATED ! */
+
+frame pad {
+	set Px = 0.5mm
+
+	set Py = 0.5mm
+
+	set cname = col+1
+
+	__0: vec @(col*1mm-Px/2, row*-1mm-Py/2)
+	__1: vec .(0mm, Py)
+	__2: vec __0(Px, 0mm)
+	pad "$rname$cname" __1 __2
+}
+
+frame inner {
+	loop col = c0, c1
+
+	frame pad @
+}
+
+frame last {
+	loop col = 4, 5
+
+	frame pad @
+}
+
+frame first {
+	loop col = 0, 1
+
+	frame pad @
+}
+
+part "Fake_BGA"
+table
+    { row, rname, c0, c1 }
+    { 0, "A", 2, 3 }
+    { 1, "B", 2, 3 }
+    { 2, "C", 9, 0 }
+    { 3, "D", 9, 0 }
+    { 4, "E", 2, 3 }
+    { 5, "F", 2, 3 }
+
+frame last @
+frame first @
+frame inner @
+measy pad.__0 -> pad.__1 0.2mm
+measy pad.__0 -> pad.__0 0.5mm
+measx pad.__0 -> pad.__2 -0.3mm
+measx pad.__0 -> pad.__0 -0.6mm
+measy pad.__0 >> pad.__1 0.8mm
+measx pad.__0 >> pad.__2 -0.9mm

Modified: trunk/eda/fped/file.c
===================================================================
--- trunk/eda/fped/file.c	2009-08-11 21:54:18 UTC (rev 5420)
+++ trunk/eda/fped/file.c	2009-08-11 23:26:38 UTC (rev 5421)
@@ -47,6 +47,19 @@
 }
 
 
+int file_exists(const char *name)
+{
+	struct stat st;
+
+	if (stat(name, &st) >= 0)
+		return 1;
+	if (errno == ENOENT)
+		return 0;
+	perror(name);
+	return -1;
+}
+
+
 int save_to(const char *name, int (*fn)(FILE *file))
 {
 	FILE *file;
@@ -73,8 +86,7 @@
 	char *s = stralloc(name);
 	char *back, *tmp;
 	char *slash, *dot;
-	int n;
-	struct stat st;
+	int n, res;
 
 	/* save to temporary file */
 
@@ -99,14 +111,12 @@
 	while (1) {
 		back = stralloc_printf("%s~%d%s%s",
 		    s, n, dot ? "." : "", dot ? dot+1 : "");
-		if (stat(back, &st) < 0) {
-			if (errno == ENOENT)
-				break;
-			perror(back);
-			free(back);
+		res = file_exists(back);
+		if (!res)
+			break;
+		free(back);
+		if (res < 0)
 			return;
-		}
-		free(back);
 		n++;
 	}
 	if (rename(name, back) < 0) {

Modified: trunk/eda/fped/file.h
===================================================================
--- trunk/eda/fped/file.h	2009-08-11 21:54:18 UTC (rev 5420)
+++ trunk/eda/fped/file.h	2009-08-11 23:26:38 UTC (rev 5421)
@@ -17,6 +17,11 @@
 #include <stdio.h>
 
 
+/*
+ * Returns -1 on error.
+ */
+int file_exists(const char *name);
+
 char *set_extension(const char *name, const char *ext);
 int save_to(const char *name, int (*fn)(FILE *file));
 void save_with_backup(const char *name, int (*fn)(FILE *file));

Modified: trunk/eda/fped/fped.c
===================================================================
--- trunk/eda/fped/fped.c	2009-08-11 21:54:18 UTC (rev 5420)
+++ trunk/eda/fped/fped.c	2009-08-11 23:26:38 UTC (rev 5421)
@@ -32,8 +32,12 @@
 
 static void load_file(const char *name)
 {
-	reporter = report_parse_error;
-	run_cpp_on_file(name);
+	if (file_exists(name) == 1) {
+		reporter = report_parse_error;
+		run_cpp_on_file(name);
+	} else {
+		scan_empty();
+	}
 	(void) yyparse();
 }
 

Modified: trunk/eda/fped/gui_frame.c
===================================================================
--- trunk/eda/fped/gui_frame.c	2009-08-11 21:54:18 UTC (rev 5420)
+++ trunk/eda/fped/gui_frame.c	2009-08-11 23:26:38 UTC (rev 5421)
@@ -487,6 +487,7 @@
 	label_in_box_bg(var->widget, COLOR_VAR_EDITING);
 	status_set_type_entry("name =");
 	status_set_name("%s", var->name);
+	edit_nothing();
 	edit_unique(&var->name, validate_var_name, var);
 }
 
@@ -508,6 +509,7 @@
 {
 	inst_select_outside(value, unselect_value);
 	label_in_box_bg(value->widget, COLOR_EXPR_EDITING);
+	edit_nothing();
 	edit_expr(&value->expr);
 }
 
@@ -549,6 +551,7 @@
 
 	switch (event->button) {
 	case 1:
+		edit_nothing();
 		edit_var(var);
 		break;
 	case 3:
@@ -566,6 +569,7 @@
 
 	switch (event->button) {
 	case 1:
+		edit_nothing();
 		edit_value(value);
 		break;
 	}
@@ -633,6 +637,7 @@
 
 	switch (event->button) {
 	case 1:
+		edit_nothing();
 		edit_var(var);
 		break;
 	case 3:
@@ -650,9 +655,11 @@
 
 	switch (event->button) {
 	case 1:
-		if (!value->row || value->row->table->active_row == value->row)
+		if (!value->row ||
+		    value->row->table->active_row == value->row) {
+			edit_nothing();
 			edit_value(value);
-		else {
+		} else {
 			select_row(value->row);
 			change_world();
 		}
@@ -745,6 +752,7 @@
 
 	switch (event->button) {
 	case 1:
+		edit_nothing();
 		edit_var(&loop->var);
 		break;
 	case 3:
@@ -762,6 +770,7 @@
 
 	switch (event->button) {
 	case 1:
+		edit_nothing();
 		edit_value(&loop->from);
 		break;
 	}
@@ -776,6 +785,7 @@
 
 	switch (event->button) {
 	case 1:
+		edit_nothing();
 		edit_value(&loop->to);
 		break;
 	}
@@ -940,6 +950,7 @@
 		label_in_box_bg(widget, COLOR_PART_NAME_EDITING);
 		status_set_type_entry("part =");
 		status_set_name("%s", part_name);
+		edit_nothing();
 		edit_name(&part_name, validate_part_name, NULL);
 		break;
 	}
@@ -1001,6 +1012,7 @@
 	label_in_box_bg(frame->label, COLOR_FRAME_EDITING);
 	status_set_type_entry("name =");
 	status_set_name("%s", frame->name);
+	edit_nothing();
 	edit_unique(&frame->name, validate_frame_name, frame);
 }
 
@@ -1025,8 +1037,10 @@
 		if (active_frame != frame)
 			select_frame(frame);
 		else {
-			if (active_frame->name)
+			if (active_frame->name) {
+				edit_nothing();
 				edit_frame(frame);
+			}
 		}
 		break;
 	case 3:

Modified: trunk/eda/fped/unparse.c
===================================================================
--- trunk/eda/fped/unparse.c	2009-08-11 21:54:18 UTC (rev 5420)
+++ trunk/eda/fped/unparse.c	2009-08-11 23:26:38 UTC (rev 5421)
@@ -38,7 +38,7 @@
 		return prec_mult;
 	if (op == op_minus)
 		return prec_unary;
-	if (op == op_num || op == op_var)
+	if (op == op_num || op == op_string || op == op_var)
 		return prec_primary;
 	abort();
 }
@@ -85,6 +85,8 @@
 		    expr->u.num.n, str_unit(expr->u.num));
 		return stralloc(tmp);
 	}
+	if (expr->op == op_string)
+		return stralloc_printf("\"%s\"", expr->u.str);
 	if (expr->op == op_var)
 		return stralloc(expr->u.var);
 	if (expr->op == op_minus)




More information about the commitlog mailing list