mirror of
git://projects.qi-hardware.com/fped.git
synced 2024-11-22 13:14:04 +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:
parent
233fc4b683
commit
64f80e84a2
1
TODO
1
TODO
@ -26,6 +26,7 @@ Bugs:
|
|||||||
- default silk width has no business being hard-coded in obj.c
|
- default silk width has no business being hard-coded in obj.c
|
||||||
- undelete only works if not much has changed since the deletion
|
- undelete only works if not much has changed since the deletion
|
||||||
- focus should return to canvas if nobody else wants it
|
- 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:
|
Code cleanup:
|
||||||
- merge edit_unique with edit_name
|
- merge edit_unique with edit_name
|
||||||
|
48
expr.c
48
expr.c
@ -18,6 +18,7 @@
|
|||||||
#include "error.h"
|
#include "error.h"
|
||||||
#include "obj.h"
|
#include "obj.h"
|
||||||
#include "unparse.h"
|
#include "unparse.h"
|
||||||
|
#include "fpd.h"
|
||||||
#include "expr.h"
|
#include "expr.h"
|
||||||
|
|
||||||
|
|
||||||
@ -449,13 +450,6 @@ struct expr *new_num(struct num num)
|
|||||||
/* ----- expression-only parser -------------------------------------------- */
|
/* ----- expression-only parser -------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
void scan_expr(const char *s);
|
|
||||||
int yyparse(void);
|
|
||||||
|
|
||||||
|
|
||||||
struct expr *expr_result;
|
|
||||||
|
|
||||||
|
|
||||||
struct expr *parse_expr(const char *s)
|
struct expr *parse_expr(const char *s)
|
||||||
{
|
{
|
||||||
scan_expr(s);
|
scan_expr(s);
|
||||||
@ -487,3 +481,43 @@ void free_expr(struct expr *expr)
|
|||||||
vacate_op(expr);
|
vacate_op(expr);
|
||||||
free(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
5
expr.h
@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
struct frame;
|
struct frame;
|
||||||
struct expr;
|
struct expr;
|
||||||
|
struct value;
|
||||||
|
|
||||||
enum num_type {
|
enum num_type {
|
||||||
nt_none,
|
nt_none,
|
||||||
@ -137,4 +138,8 @@ struct expr *new_num(struct num num);
|
|||||||
struct expr *parse_expr(const char *s);
|
struct expr *parse_expr(const char *s);
|
||||||
void free_expr(struct expr *expr);
|
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 */
|
#endif /* !EXPR_H */
|
||||||
|
32
fpd.h
Normal file
32
fpd.h
Normal 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
8
fpd.l
@ -19,6 +19,7 @@
|
|||||||
#include "expr.h"
|
#include "expr.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
#include "meas.h"
|
#include "meas.h"
|
||||||
|
#include "fpd.h"
|
||||||
|
|
||||||
#include "y.tab.h"
|
#include "y.tab.h"
|
||||||
|
|
||||||
@ -41,6 +42,13 @@ void scan_expr(const char *s)
|
|||||||
yy_scan_string(s);
|
yy_scan_string(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void scan_var(const char *s)
|
||||||
|
{
|
||||||
|
start_token = START_VAR;
|
||||||
|
yy_scan_string(s);
|
||||||
|
}
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
|
||||||
|
28
fpd.y
28
fpd.y
@ -19,9 +19,13 @@
|
|||||||
#include "expr.h"
|
#include "expr.h"
|
||||||
#include "obj.h"
|
#include "obj.h"
|
||||||
#include "meas.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 frame *curr_frame;
|
||||||
static struct table *curr_table;
|
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_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_PAD TOK_RPAD TOK_RECT TOK_LINE TOK_CIRC TOK_ARC
|
||||||
%token TOK_MEAS TOK_MEASX TOK_MEASY
|
%token TOK_MEAS TOK_MEASX TOK_MEASY
|
||||||
@ -162,7 +166,7 @@ static struct obj *new_obj(enum obj_type type)
|
|||||||
%type <table> table
|
%type <table> table
|
||||||
%type <var> vars var
|
%type <var> vars var
|
||||||
%type <row> rows
|
%type <row> rows
|
||||||
%type <value> row value
|
%type <value> row value opt_value_list
|
||||||
%type <vec> vec base qbase
|
%type <vec> vec base qbase
|
||||||
%type <obj> obj meas
|
%type <obj> obj meas
|
||||||
%type <expr> expr opt_expr add_expr mult_expr unary_expr primary_expr
|
%type <expr> expr opt_expr add_expr mult_expr unary_expr primary_expr
|
||||||
@ -178,7 +182,6 @@ all:
|
|||||||
root_frame = zalloc_type(struct frame);
|
root_frame = zalloc_type(struct frame);
|
||||||
set_frame(root_frame);
|
set_frame(root_frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
fpd
|
fpd
|
||||||
{
|
{
|
||||||
root_frame->prev = last_frame;
|
root_frame->prev = last_frame;
|
||||||
@ -191,6 +194,11 @@ all:
|
|||||||
{
|
{
|
||||||
expr_result = $2;
|
expr_result = $2;
|
||||||
}
|
}
|
||||||
|
| START_VAR ID opt_value_list
|
||||||
|
{
|
||||||
|
var_id = $2;
|
||||||
|
var_value_list = $3;
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
fpd:
|
fpd:
|
||||||
@ -652,3 +660,15 @@ primary_expr:
|
|||||||
$$ = $2;
|
$$ = $2;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
/* special sub-grammar */
|
||||||
|
|
||||||
|
opt_value_list:
|
||||||
|
{
|
||||||
|
$$ = NULL;
|
||||||
|
}
|
||||||
|
| '=' row
|
||||||
|
{
|
||||||
|
$$ = $2;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
4
fped.c
4
fped.c
@ -22,11 +22,9 @@
|
|||||||
#include "inst.h"
|
#include "inst.h"
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
#include "gui.h"
|
#include "gui.h"
|
||||||
|
#include "fpd.h"
|
||||||
|
|
||||||
|
|
||||||
extern void scan_empty(void);
|
|
||||||
extern int yyparse(void);
|
|
||||||
|
|
||||||
char *save_file_name = NULL;
|
char *save_file_name = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
72
gui_frame.c
72
gui_frame.c
@ -451,7 +451,8 @@ static void add_sep(GtkWidget *box, int size)
|
|||||||
/* ----- variable name editor ---------------------------------------------- */
|
/* ----- 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 table *table;
|
||||||
const struct loop *loop;
|
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 (table = frame->tables; table; table = table->next)
|
||||||
for (var = table->vars; var; var = var->next)
|
for (var = table->vars; var; var = var->next)
|
||||||
if (!strcmp(var->name, name))
|
if (var != self && !strcmp(var->name, name))
|
||||||
return 1;
|
return 1;
|
||||||
for (loop = frame->loops; loop; loop = loop->next)
|
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 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -474,7 +475,7 @@ static int validate_var_name(const char *s, void *ctx)
|
|||||||
|
|
||||||
if (!is_id(s))
|
if (!is_id(s))
|
||||||
return 0;
|
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);
|
inst_select_outside(var, unselect_var);
|
||||||
label_in_box_bg(var->widget, COLOR_VAR_EDITING);
|
label_in_box_bg(var->widget, COLOR_VAR_EDITING);
|
||||||
status_set_type_entry("name =");
|
status_set_type_entry("name =");
|
||||||
status_set_name("%s", var->name);
|
status_set_name("%s", var->name);
|
||||||
edit_nothing();
|
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 ------------------------------------------------------- */
|
/* ----- 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,
|
static gboolean assignment_var_select_event(GtkWidget *widget,
|
||||||
GdkEventButton *event, gpointer data)
|
GdkEventButton *event, gpointer data)
|
||||||
{
|
{
|
||||||
@ -556,8 +583,7 @@ static gboolean assignment_var_select_event(GtkWidget *widget,
|
|||||||
|
|
||||||
switch (event->button) {
|
switch (event->button) {
|
||||||
case 1:
|
case 1:
|
||||||
edit_nothing();
|
edit_var(var, set_col_values, var, -1);
|
||||||
edit_var(var);
|
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
pop_up_single_var(var, event);
|
pop_up_single_var(var, event);
|
||||||
@ -642,8 +668,7 @@ static gboolean table_var_select_event(GtkWidget *widget,
|
|||||||
|
|
||||||
switch (event->button) {
|
switch (event->button) {
|
||||||
case 1:
|
case 1:
|
||||||
edit_nothing();
|
edit_var(var, set_col_values, var, -1);
|
||||||
edit_var(var);
|
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
pop_up_table_var(var, event);
|
pop_up_table_var(var, event);
|
||||||
@ -750,6 +775,30 @@ static void build_table(GtkWidget *vbox, struct frame *frame,
|
|||||||
/* ----- loops ------------------------------------------------------------- */
|
/* ----- 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,
|
static gboolean loop_var_select_event(GtkWidget *widget,
|
||||||
GdkEventButton *event, gpointer data)
|
GdkEventButton *event, gpointer data)
|
||||||
{
|
{
|
||||||
@ -757,8 +806,7 @@ static gboolean loop_var_select_event(GtkWidget *widget,
|
|||||||
|
|
||||||
switch (event->button) {
|
switch (event->button) {
|
||||||
case 1:
|
case 1:
|
||||||
edit_nothing();
|
edit_var(&loop->var, set_loop_values, loop, 2);
|
||||||
edit_var(&loop->var);
|
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
pop_up_loop_var(loop, event);
|
pop_up_loop_var(loop, event);
|
||||||
|
73
gui_status.c
73
gui_status.c
@ -15,6 +15,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
#include <gdk/gdkkeysyms.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 ----------------------------------------------------- */
|
/* ----- string fields ----------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
@ -24,6 +24,10 @@ void edit_unique(const char **s, int (*validate)(const char *s, void *ctx),
|
|||||||
void *ctx);
|
void *ctx);
|
||||||
void edit_unique_null(const char **s, int (*validate)(const char *s, void *ctx),
|
void edit_unique_null(const char **s, int (*validate)(const char *s, void *ctx),
|
||||||
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_name(char **s, int (*validate)(const char *s, void *ctx), void *ctx);
|
||||||
void edit_expr(struct expr **expr);
|
void edit_expr(struct expr **expr);
|
||||||
void edit_x(struct expr **expr);
|
void edit_x(struct expr **expr);
|
||||||
|
Loading…
Reference in New Issue
Block a user