r5459 - trunk/eda/fped

werner at docs.openmoko.org werner at docs.openmoko.org
Sun Aug 16 06:12:37 CEST 2009


Author: werner
Date: 2009-08-16 06:12:37 +0200 (Sun, 16 Aug 2009)
New Revision: 5459

Added:
   trunk/eda/fped/fpd.h
Modified:
   trunk/eda/fped/TODO
   trunk/eda/fped/expr.c
   trunk/eda/fped/expr.h
   trunk/eda/fped/fpd.l
   trunk/eda/fped/fpd.y
   trunk/eda/fped/fped.c
   trunk/eda/fped/gui_frame.c
   trunk/eda/fped/gui_status.c
   trunk/eda/fped/gui_status.h
Log:
Columns and loops can now be entered in one step as  var = val, val, ...

- moved definition of expr_result from expr.c to fpd.y
- new header file fpd.h with all the things fpd.l and fpd.y export
- edit_var already calls edit_nothing, so there's no need to call it before
- added rapid entry option for loops, variables, and columns: var = val, ...



Modified: trunk/eda/fped/TODO
===================================================================
--- trunk/eda/fped/TODO	2009-08-16 01:51:21 UTC (rev 5458)
+++ trunk/eda/fped/TODO	2009-08-16 04:12:37 UTC (rev 5459)
@@ -26,6 +26,7 @@
 - default silk width has no business being hard-coded in obj.c
 - undelete only works if not much has changed since the deletion
 - focus should return to canvas if nobody else wants it
+- whenever we call parse_* for input parsing, we may leak lots of expressions
 
 Code cleanup:
 - merge edit_unique with edit_name

Modified: trunk/eda/fped/expr.c
===================================================================
--- trunk/eda/fped/expr.c	2009-08-16 01:51:21 UTC (rev 5458)
+++ trunk/eda/fped/expr.c	2009-08-16 04:12:37 UTC (rev 5459)
@@ -18,6 +18,7 @@
 #include "error.h"
 #include "obj.h"
 #include "unparse.h"
+#include "fpd.h"
 #include "expr.h"
 
 
@@ -449,13 +450,6 @@
 /* ----- expression-only parser -------------------------------------------- */
 
 
-void scan_expr(const char *s);
-int yyparse(void);
-
-
-struct expr *expr_result;
-
-
 struct expr *parse_expr(const char *s)
 {
 	scan_expr(s);
@@ -487,3 +481,43 @@
 	vacate_op(expr);
 	free(expr);
 }
+
+
+/* ----- var = value, ... shortcut ----------------------------------------- */
+
+
+int parse_var(const char *s, const char **id, struct value **values,
+    int max_values)
+{
+	const struct value *value;
+	int n;
+
+	scan_var(s);
+	if (yyparse())
+		return -1;
+	if (id)
+		*id = var_id;
+	if (values)
+		*values = var_value_list;
+	n = 0;
+	for (value = var_value_list; value; value = value->next)
+		n++;
+	if (max_values == -1 || n <= max_values)
+		return n;
+	free_values(var_value_list, 0);
+	return -1;
+}
+
+
+void free_values(struct value *values, int keep_expr)
+{
+	struct value *next;
+
+	while (values) {
+		next = values->next;
+		if (!keep_expr)
+			free_expr(values->expr);
+		free(values);
+		values = next;
+	}
+}

Modified: trunk/eda/fped/expr.h
===================================================================
--- trunk/eda/fped/expr.h	2009-08-16 01:51:21 UTC (rev 5458)
+++ trunk/eda/fped/expr.h	2009-08-16 04:12:37 UTC (rev 5459)
@@ -22,6 +22,7 @@
 
 struct frame;
 struct expr;
+struct value;
 
 enum num_type {
 	nt_none,
@@ -137,4 +138,8 @@
 struct expr *parse_expr(const char *s);
 void free_expr(struct expr *expr);
 
+int parse_var(const char *s, const char **id, struct value **values,
+    int max_values);
+void free_values(struct value *values, int keep_expr);
+
 #endif /* !EXPR_H */

Added: trunk/eda/fped/fpd.h
===================================================================
--- trunk/eda/fped/fpd.h	                        (rev 0)
+++ trunk/eda/fped/fpd.h	2009-08-16 04:12:37 UTC (rev 5459)
@@ -0,0 +1,32 @@
+/*
+ * fpd.c - Things fpd.l and fpd.y export
+ *
+ * Written 2009 by Werner Almesberger
+ * Copyright 2009 by Werner Almesberger
+ *
+ * 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.
+ */
+
+
+#ifndef FPD_H
+#define FPD_H
+
+#include "expr.h"
+#include "obj.h"
+
+
+extern struct expr *expr_result;
+extern const char *var_id;
+extern struct value *var_value_list;
+
+
+void scan_empty(void);
+void scan_expr(const char *s);
+void scan_var(const char *s);
+
+int yyparse(void);
+
+#endif /* !FPD_H */

Modified: trunk/eda/fped/fpd.l
===================================================================
--- trunk/eda/fped/fpd.l	2009-08-16 01:51:21 UTC (rev 5458)
+++ trunk/eda/fped/fpd.l	2009-08-16 04:12:37 UTC (rev 5459)
@@ -19,6 +19,7 @@
 #include "expr.h"
 #include "error.h"
 #include "meas.h"
+#include "fpd.h"
 
 #include "y.tab.h"
 
@@ -41,6 +42,13 @@
 	yy_scan_string(s);
 }
 
+
+void scan_var(const char *s)
+{
+	start_token = START_VAR;
+	yy_scan_string(s);
+}
+
 %}
 
 

Modified: trunk/eda/fped/fpd.y
===================================================================
--- trunk/eda/fped/fpd.y	2009-08-16 01:51:21 UTC (rev 5458)
+++ trunk/eda/fped/fpd.y	2009-08-16 04:12:37 UTC (rev 5459)
@@ -19,10 +19,14 @@
 #include "expr.h"
 #include "obj.h"
 #include "meas.h"
+#include "fpd.h"
 
 
-extern struct expr *expr_result;
+struct expr *expr_result;
+const char *var_id;
+struct value *var_value_list;
 
+
 static struct frame *curr_frame;
 static struct table *curr_table;
 static struct row *curr_row;
@@ -149,7 +153,7 @@
 };
 
 
-%token		START_FPD START_EXPR
+%token		START_FPD START_EXPR START_VAR
 %token		TOK_SET TOK_LOOP TOK_PART TOK_FRAME TOK_TABLE TOK_VEC
 %token		TOK_PAD TOK_RPAD TOK_RECT TOK_LINE TOK_CIRC TOK_ARC
 %token		TOK_MEAS TOK_MEASX TOK_MEASY
@@ -162,7 +166,7 @@
 %type	<table>	table
 %type	<var>	vars var
 %type	<row>	rows
-%type	<value>	row value
+%type	<value>	row value opt_value_list
 %type	<vec>	vec base qbase
 %type	<obj>	obj meas
 %type	<expr>	expr opt_expr add_expr mult_expr unary_expr primary_expr
@@ -178,7 +182,6 @@
 			root_frame = zalloc_type(struct frame);
 			set_frame(root_frame);
 		}
-
 	    fpd
 		{
 			root_frame->prev = last_frame;
@@ -191,6 +194,11 @@
 		{
 			expr_result = $2;
 		}
+	| START_VAR ID opt_value_list
+		{
+			var_id = $2;
+			var_value_list = $3;
+		}
 	;
 
 fpd:
@@ -652,3 +660,15 @@
 			$$ = $2;
 		}
 	;
+
+/* special sub-grammar */
+
+opt_value_list:
+		{
+			$$ = NULL;
+		}
+	| '=' row
+		{
+			$$ = $2;
+		}
+	;

Modified: trunk/eda/fped/fped.c
===================================================================
--- trunk/eda/fped/fped.c	2009-08-16 01:51:21 UTC (rev 5458)
+++ trunk/eda/fped/fped.c	2009-08-16 04:12:37 UTC (rev 5459)
@@ -22,11 +22,9 @@
 #include "inst.h"
 #include "file.h"
 #include "gui.h"
+#include "fpd.h"
 
 
-extern void scan_empty(void);
-extern int yyparse(void);
-
 char *save_file_name = NULL;
 
 

Modified: trunk/eda/fped/gui_frame.c
===================================================================
--- trunk/eda/fped/gui_frame.c	2009-08-16 01:51:21 UTC (rev 5458)
+++ trunk/eda/fped/gui_frame.c	2009-08-16 04:12:37 UTC (rev 5459)
@@ -451,7 +451,8 @@
 /* ----- variable name editor ---------------------------------------------- */
 
 
-static int find_var_in_frame(const struct frame *frame, const char *name)
+static int find_var_in_frame(const struct frame *frame, const char *name,
+    const struct var *self)
 {
 	const struct table *table;
 	const struct loop *loop;
@@ -459,10 +460,10 @@
 
 	for (table = frame->tables; table; table = table->next)
 		for (var = table->vars; var; var = var->next)
-			if (!strcmp(var->name, name))
+			if (var != self && !strcmp(var->name, name))
 				return 1;
 	for (loop = frame->loops; loop; loop = loop->next)
-		if (!strcmp(loop->var.name, name))
+		if (&loop->var != self && !strcmp(loop->var.name, name))
 			return 1;
 	return 0;
 }
@@ -474,7 +475,7 @@
 
 	if (!is_id(s))
 		return 0;
-	return !find_var_in_frame(var->frame, s);
+	return !find_var_in_frame(var->frame, s, var);
 }
 
 
@@ -486,14 +487,17 @@
 }
 
 
-static void edit_var(struct var *var)
+static void edit_var(struct var *var,
+    void (*set_values)(void *user, const struct value *values, int n_values),
+    void *user, int max_values)
 {
 	inst_select_outside(var, unselect_var);
 	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);
+	edit_unique_with_values(&var->name, validate_var_name, var,
+	    set_values, user, max_values);
 }
 
 
@@ -549,6 +553,29 @@
 /* ----- assignments ------------------------------------------------------- */
 
 
+static void set_col_values(void *user, const struct value *values,
+    int n_values)
+{
+	struct var *var = user;
+	struct table *table = var->table;
+	struct value *value;
+	const struct var *walk;
+	struct row **row;
+
+	row = &table->rows;
+	while (values) {
+		if (!*row)
+			add_row_here(table, row);
+		value = (*row)->values;
+		for (walk = table->vars; walk != var; walk = walk->next)
+			value = value->next;
+		value->expr = values->expr;
+		values = values->next;
+		row = &(*row)->next;
+	}
+}
+
+
 static gboolean assignment_var_select_event(GtkWidget *widget,
     GdkEventButton *event, gpointer data)
 {
@@ -556,8 +583,7 @@
 
 	switch (event->button) {
 	case 1:
-		edit_nothing();
-		edit_var(var);
+		edit_var(var, set_col_values, var, -1);
 		break;
 	case 3:
 		pop_up_single_var(var, event);
@@ -642,8 +668,7 @@
 
 	switch (event->button) {
 	case 1:
-		edit_nothing();
-		edit_var(var);
+		edit_var(var, set_col_values, var, -1);
 		break;
 	case 3:
 		pop_up_table_var(var, event);
@@ -750,6 +775,30 @@
 /* ----- loops ------------------------------------------------------------- */
 
 
+static void set_loop_values(void *user, const struct value *values,
+    int n_values)
+{
+	struct loop *loop = user;
+
+	switch (n_values) {
+	case 2:
+		if (loop->to.expr)
+			free_expr(loop->to.expr);
+		loop->to.expr = values->next->expr;
+		/* fall through */
+	case 1:
+		if (loop->from.expr)
+			free_expr(loop->from.expr);
+		loop->from.expr = values->expr;
+		break;
+	case 0:
+		break;
+	default:
+		abort();
+	}
+}
+
+
 static gboolean loop_var_select_event(GtkWidget *widget,
     GdkEventButton *event, gpointer data)
 {
@@ -757,8 +806,7 @@
 
 	switch (event->button) {
 	case 1:
-		edit_nothing();
-		edit_var(&loop->var);
+		edit_var(&loop->var, set_loop_values, loop, 2);
 		break;
 	case 3:
 		pop_up_loop_var(loop, event);

Modified: trunk/eda/fped/gui_status.c
===================================================================
--- trunk/eda/fped/gui_status.c	2009-08-16 01:51:21 UTC (rev 5458)
+++ trunk/eda/fped/gui_status.c	2009-08-16 04:12:37 UTC (rev 5459)
@@ -15,6 +15,7 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
+#include <assert.h>
 #include <gtk/gtk.h>
 #include <gdk/gdkkeysyms.h>
 
@@ -341,6 +342,78 @@
 }
 
 
+/* ----- unique field (variable) optionally followed by values ------------- */
+
+
+struct edit_unique_with_values_ctx {
+	const char **s;
+	int (*validate)(const char *s, void *ctx);
+	void *ctx;
+	void (*set_values)(void *user, const struct value *values,
+	    int n_values);
+	void *user;
+	int max_values;
+};
+
+
+static enum edit_status unique_with_values_status(const char *s, void *ctx)
+{
+	const struct edit_unique_with_values_ctx *unique_ctx = ctx;
+	const char *id;
+	int n;
+
+	if (!strcmp(s, *unique_ctx->s))
+		return es_unchanged;
+	status_begin_reporting();
+	n = parse_var(s, &id, NULL, unique_ctx->max_values);
+	if (n < 0)
+		return es_bad;
+	return !unique_ctx->validate ||
+	    unique_ctx->validate(id, unique_ctx->ctx) ? es_good : es_bad;
+}
+
+
+static void unique_with_values_store(const char *s, void *ctx)
+{
+	const struct edit_unique_with_values_ctx *unique_ctx = ctx;
+	struct value *values;
+	int n;
+
+	status_begin_reporting();
+	n = parse_var(s, unique_ctx->s, &values, unique_ctx->max_values);
+	if (!n)
+		return;
+	assert(n >= 0);
+	assert(unique_ctx->max_values == -1 || n <= unique_ctx->max_values);
+	unique_ctx->set_values(unique_ctx->user, values, n);
+	free_values(values, 1);
+}
+
+
+static struct edit_ops edit_ops_unique_with_values = {
+	.retrieve	= unique_retrieve,
+	.status		= unique_with_values_status,
+	.store		= unique_with_values_store,
+};
+
+
+void edit_unique_with_values(const char **s,
+    int (*validate)(const char *s, void *ctx), void *ctx,
+    void (*set_values)(void *user, const struct value *values, int n_values),
+    void *user, int max_values)
+{
+	static struct edit_unique_with_values_ctx unique_ctx;
+
+	unique_ctx.s = s;
+	unique_ctx.validate = validate;
+	unique_ctx.ctx = ctx;
+	unique_ctx.set_values = set_values;
+	unique_ctx.user = user;
+	unique_ctx.max_values = max_values;
+	setup_edit(status_entry, &edit_ops_unique_with_values, &unique_ctx);
+}
+
+
 /* ----- string fields ----------------------------------------------------- */
 
 

Modified: trunk/eda/fped/gui_status.h
===================================================================
--- trunk/eda/fped/gui_status.h	2009-08-16 01:51:21 UTC (rev 5458)
+++ trunk/eda/fped/gui_status.h	2009-08-16 04:12:37 UTC (rev 5459)
@@ -24,6 +24,10 @@
     void *ctx);
 void edit_unique_null(const char **s, int (*validate)(const char *s, void *ctx),
     void *ctx);
+void edit_unique_with_values(const char **s,
+    int (*validate)(const char *s, void *ctx), void *ctx,
+    void (*set_values)(void *user, const struct value *values, int n_values),
+    void *user, int max_values);
 void edit_name(char **s, int (*validate)(const char *s, void *ctx), void *ctx);
 void edit_expr(struct expr **expr);
 void edit_x(struct expr **expr);




More information about the commitlog mailing list