1
0
mirror of git://projects.qi-hardware.com/fped.git synced 2024-12-22 23:28:38 +02:00

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, ...



git-svn-id: http://svn.openmoko.org/trunk/eda/fped@5459 99fdad57-331a-0410-800a-d7fa5415bdb3
This commit is contained in:
werner 2009-08-16 04:12:37 +00:00
parent 233fc4b683
commit 64f80e84a2
10 changed files with 249 additions and 26 deletions

1
TODO
View File

@ -26,6 +26,7 @@ Bugs:
- 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

48
expr.c
View File

@ -18,6 +18,7 @@
#include "error.h"
#include "obj.h"
#include "unparse.h"
#include "fpd.h"
#include "expr.h"
@ -449,13 +450,6 @@ struct expr *new_num(struct num num)
/* ----- 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 @@ void free_expr(struct expr *expr)
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;
}
}

5
expr.h
View File

@ -22,6 +22,7 @@
struct frame;
struct expr;
struct value;
enum num_type {
nt_none,
@ -137,4 +138,8 @@ struct expr *new_num(struct num num);
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 */

32
fpd.h Normal file
View File

@ -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 */

8
fpd.l
View File

@ -19,6 +19,7 @@
#include "expr.h"
#include "error.h"
#include "meas.h"
#include "fpd.h"
#include "y.tab.h"
@ -41,6 +42,13 @@ void scan_expr(const char *s)
yy_scan_string(s);
}
void scan_var(const char *s)
{
start_token = START_VAR;
yy_scan_string(s);
}
%}

28
fpd.y
View File

@ -19,9 +19,13 @@
#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;
@ -149,7 +153,7 @@ static struct obj *new_obj(enum obj_type type)
};
%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 @@ static struct obj *new_obj(enum obj_type type)
%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 @@ all:
root_frame = zalloc_type(struct frame);
set_frame(root_frame);
}
fpd
{
root_frame->prev = last_frame;
@ -191,6 +194,11 @@ all:
{
expr_result = $2;
}
| START_VAR ID opt_value_list
{
var_id = $2;
var_value_list = $3;
}
;
fpd:
@ -652,3 +660,15 @@ primary_expr:
$$ = $2;
}
;
/* special sub-grammar */
opt_value_list:
{
$$ = NULL;
}
| '=' row
{
$$ = $2;
}
;

4
fped.c
View File

@ -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;

View File

@ -451,7 +451,8 @@ static void add_sep(GtkWidget *box, int size)
/* ----- 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 @@ static int find_var_in_frame(const struct frame *frame, const char *name)
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 @@ static int validate_var_name(const char *s, void *ctx)
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 unselect_var(void *data)
}
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 @@ static GtkWidget *add_activator(GtkWidget *hbox, int active,
/* ----- 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 @@ static gboolean assignment_var_select_event(GtkWidget *widget,
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 @@ static gboolean table_var_select_event(GtkWidget *widget,
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 @@ static void build_table(GtkWidget *vbox, struct frame *frame,
/* ----- 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 @@ static gboolean loop_var_select_event(GtkWidget *widget,
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);

View File

@ -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 @@ void edit_unique_null(const char **s,
}
/* ----- 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 ----------------------------------------------------- */

View File

@ -24,6 +24,10 @@ void edit_unique(const char **s, int (*validate)(const char *s, void *ctx),
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);