mirror of
git://projects.qi-hardware.com/fped.git
synced 2024-11-25 18:01:54 +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
|
||||
- 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
48
expr.c
@ -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
5
expr.h
@ -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
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 "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
28
fpd.y
@ -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
4
fped.c
@ -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;
|
||||
|
||||
|
||||
|
72
gui_frame.c
72
gui_frame.c
@ -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);
|
||||
|
73
gui_status.c
73
gui_status.c
@ -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 ----------------------------------------------------- */
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user