1
0
mirror of git://projects.qi-hardware.com/eda-tools.git synced 2024-11-04 23:43:43 +02:00

b2: BOOM rewrite (WIP)

This commit is contained in:
Werner Almesberger 2012-03-18 13:24:12 -03:00
parent b8ab60aa91
commit aa2fe3ef16
15 changed files with 1273 additions and 0 deletions

66
b2/Makefile Normal file
View File

@ -0,0 +1,66 @@
#
# Makefile - BOOM's Makefile
#
# Copyright 2012 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.
#
CFLAGS = -Wall $(shell pkg-config --cflags glib-2.0)
SLOPPY = -Wno-unused -Wno-implicit-function-declaration
OBJS = boom.o chr.o comp.o db.o eval.o param.o util.o lex.yy.o y.tab.o
LDLIBS = -lfl $(shell pkg-config --libs glib-2.0)
YACC = bison -y
YYFLAGS = -v
CC_normal := $(CC)
YACC_normal := $(YACC)
LEX_normal := $(LEX)
DEPEND_normal := $(CPP) $(CFLAGS) -MM -MG
CC_quiet = @echo " CC " $@ && $(CC_normal)
YACC_quiet = @echo " YACC " $@ && $(YACC_normal)
LEX_quiet = @echo " LEX " $@ && $(LEX_normal)
GEN_quiet = @echo " GENERATE " $@ &&
DEPEND_quiet = @$(DEPEND_normal)
ifeq ($(V),1)
CC = $(CC_normal)
LEX = $(LEX_normal)
YACC = $(YACC_normal)
GEN =
DEPEND = $(DEPEND_normal)
else
CC = $(CC_quiet)
LEX = $(LEX_quiet)
YACC = $(YACC_quiet)
GEN = $(GEN_quiet)
DEPEND = $(DEPEND_quiet)
endif
.PHONY: all clean
all: boom
boom: $(OBJS)
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LDLIBS)
lex.yy.c: lang.l y.tab.h
$(LEX) lang.l
lex.yy.o: lex.yy.c y.tab.h
$(CC) -c $(CFLAGS) $(SLOPPY) lex.yy.c
y.tab.c y.tab.h: lang.y
$(YACC) $(YYFLAGS) -d lang.y
y.tab.o: y.tab.c
$(CC) -c $(CFLAGS) $(SLOPPY) y.tab.c
clean:
rm -f $(OBJS)
rm -f lex.yy.c y.tab.c y.tab.h

82
b2/bitset.h Normal file
View File

@ -0,0 +1,82 @@
/*
* bitset.h - Bit sets
*
* Copyright 2012 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 BITSET_H
#define BITSET_H
#include <stdint.h>
#include "bitset.h"
struct bitset {
uint64_t v;
};
static inline void bitset_zero(struct bitset *b)
{
b->v = 0;
}
static inline void bitset_set(struct bitset *b, int n)
{
b->v |= (uint64_t) 1 << n;
}
static inline void bitset_clear(struct bitset *b, int n)
{
b->v &= ~((uint64_t) 1 << n);
}
static inline int bitset_get(const struct bitset *b, int n)
{
return !!(b->v & ((uint64_t) 1 << n));
}
static inline int bitset_empty(const struct bitset *b)
{
return !!b->v;
}
static inline int bitset_first(const struct bitset *b)
{
int i;
for (i = 0; i != sizeof(b->v)*8; i++)
if (b->v & ((uint64_t) 1 << i))
return i;
return -1;
}
static inline int bitset_last(const struct bitset *b)
{
int i = sizeof(b->v)*8;
while (--i)
if (b->v & ((uint64_t) 1 << i))
break;
return i;
}
static inline int bitset_common(const struct bitset *a, const struct bitset *b)
{
return (a->v & b->v) != 0;
}
#endif /* !BITSET_H */

4
b2/boom.c Normal file
View File

@ -0,0 +1,4 @@
int main(void)
{
return 0;
}

102
b2/chr.c Normal file
View File

@ -0,0 +1,102 @@
/*
* chr.h - Part characteristics
*
* Copyright 2012 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.
*/
#include "util.h"
#include "param.h"
#include "chr.h"
struct condition {
struct value value;
enum relop relop;
struct condition *next;
};
struct selector {
struct condition *cond;
struct selector *next;
};
struct field {
const char *name;
const struct format *fmt;
struct field *mark;
struct selector *sel;
struct field *next;
};
static struct field *fields = NULL, *curr_field = NULL, *mark = NULL;
const struct format *field_find(const char *name)
{
const struct field *f;
for (f = fields; f; f = f->next)
if (f->name == name)
return f->fmt;
return NULL;
}
void field_add(const char *name, const struct format *fmt)
{
struct field *field;
if (field_find(name))
yyerrorf("duplicate field \"%s\"", name);
field = alloc_type(struct field);
field->name = name;
field->fmt = fmt;
field->mark = (void *) 1; /* poison */
field->sel = NULL;
if (curr_field)
curr_field->next = field;
else
fields = field;
curr_field = field;
}
void field_mark(void)
{
if (mark)
mark->mark = curr_field;
mark = curr_field;
}
void field_release(void)
{
curr_field = mark;
if (curr_field)
mark = curr_field->mark;
}
void field_add_selector(enum relop relop, const char *word)
{
}
void field_more_selectors(void)
{
if (curr_field->fmt->ops != &param_ops_set)
;//yyerrorf("
}
void field_add_wildcard(void)
{
}

27
b2/chr.h Normal file
View File

@ -0,0 +1,27 @@
/*
* chr.h - Part characteristics
*
* Copyright 2012 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 CHR_H
#define CHR_H
#include "param.h"
void field_add(const char *name, const struct format *fmt);
const struct format *field_find(const char *name);
void field_mark(void);
void field_release(void);
void field_add_selector(enum relop relop, const char *word);
void field_more_selectors(void);
void field_add_wildcard(void);
#endif /* !CHR_H */

110
b2/comp.c Normal file
View File

@ -0,0 +1,110 @@
/*
* comp.c - Parameter comparison
*
* Copyright 2012 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.
*/
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "bitset.h"
#include "param.h"
#define EQUAL(relop) ((relop) & (rel_le | rel_eq | rel_ge))
#define LESS(relop) ((relop) & (rel_lt | rel_le))
#define GREATER(relop) ((relop) & (rel_ge | rel_gt))
static int do_comp_name(const char *a, enum relop relop, const char *b)
{
int cmp;
if (EQUAL(relop))
return a == b;
cmp = strcmp(a, b);
assert(cmp);
if (cmp < 0)
return LESS(relop);
else
return GREATER(relop);
}
int comp_name(const struct value *a, enum relop relop, const struct value *b)
{
return do_comp_name(a->u.name, relop, b->u.name);
}
static int do_comp_set(const struct bitset *a, enum relop relop,
const struct bitset *b)
{
assert(!bitset_empty(a));
assert(!bitset_empty(b));
if (EQUAL(relop) && bitset_common(a, b))
return 1;
if (LESS(relop) && bitset_first(a) < bitset_last(b))
return 1;
if (GREATER(relop) && bitset_last(a) > bitset_first(b))
return 1;
return 0;
}
int comp_set(const struct value *a, enum relop relop, const struct value *b)
{
return do_comp_set(&a->u.set, relop, &b->u.set);
}
static int do_comp_abs(double a, enum relop relop, double b)
{
if (a == b)
return EQUAL(relop);
if (a < b)
return LESS(relop);
else
return GREATER(relop);
}
int comp_abs(const struct value *a, enum relop relop, const struct value *b)
{
return do_comp_abs(a->u.abs, relop, b->u.abs);
}
static int do_comp_rel(const struct rel_value *a, enum relop relop,
const struct rel_value *b)
{
if (a->fract != b->fract)
return 0;
if (a->plus == b->plus && a->minus == b->minus)
return EQUAL(relop);
if (a->plus <= b->plus && a->minus <= b->minus)
return LESS(relop);
if (a->plus >= b->plus && a->minus >= b->minus)
return GREATER(relop);
return 0;
}
int comp_rel(const struct value *a, enum relop relop, const struct value *b)
{
return do_comp_rel(&a->u.rel, relop, &b->u.rel);
}
int compare(const struct format *fmt,
const struct value *a, enum relop relop, const struct value *b)
{
return fmt->ops->comp(a, relop, b);
}

82
b2/db.c Normal file
View File

@ -0,0 +1,82 @@
/*
* db.c - Parts database
*
* Copyright 2012 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.
*/
#include <glib.h>
#include "util.h"
#include "db.h"
static GTree *tree = NULL;
static gint comp(gconstpointer a, gconstpointer b)
{
const struct part *pa = a;
const struct part *pb = b;
/*
* Just subtracting the pointers may produce values outside the
* range of gint values.
*/
return pa->domain == pb->domain ?
pa->name < pb->name ? -1 : pa->name > pb->name ? 1 : 0 :
pa->domain < pb->domain ? -1 : 1;
}
struct part *part_lookup(const char *domain, const char *name)
{
struct part part = {
.domain = domain,
.name = name,
};
if (!tree)
return NULL;
return g_tree_lookup(tree, &part);
}
struct part *part_add(const char *domain, const char *name)
{
struct part part = {
.domain = domain,
.name = name,
};
struct part *p;
if (!tree)
tree = g_tree_new(comp);
p = g_tree_lookup(tree, &part);
if (!p) {
p = alloc_type(struct part);
p->stock = NULL;
p->next = p->prev = p;
g_tree_insert(tree, p, p);
}
return p;
}
void part_alias(struct part *a, struct part *b)
{
struct part *tmp, *tmp2;
tmp = a->next;
a->next = b;
b->prev->next = tmp;
tmp2 = b->prev;
b->prev = a;
tmp->prev = tmp2;
}

66
b2/db.h Normal file
View File

@ -0,0 +1,66 @@
/*
* db.h - Parts database
*
* Copyright 2012 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 DB_H
#define DB_H
struct exchange {
const struct currency *dst;
double factor;
struct exchange *next;
};
struct currency {
const char *name;
struct exchange *exchange;
struct currency *next;
};
struct price {
int qty; /* order quantity */
double value; /* per quantity cost */
const struct currency *curr;
int fract; /* 0 if > qty at same price; 1 if multiples of qty */
struct price *next; /* next lower qty */
};
struct provider {
const char *name;
double shipping; /* S&H cost */
double minimum; /* minimum order */
const struct currency *curr;
struct provider *next;
};
struct stock {
int avail; /* items in stock */
int package; /* "natural" quantity (reel, tray, bag, etc.) */
struct price *manual; /* single parts, for manual assembly only */
double reeling; /* cost of converting "manual" to "fab"; <0 if n/a */
struct price *fab; /* for automated assembly */
} stock;
struct part {
const char *domain;
const char *name;
struct param *param; /* NULL if @@@ */
struct stock *stock; /* NULL if vendor part */
struct part *next; /* alias loop (cyclic) */
struct part *prev;
};
struct part *part_lookup(const char *domain, const char *name);
struct part *part_add(const char *domain, const char *name);
void part_alias(struct part *a, struct part *b);
#endif /* !DB_H */

216
b2/eval.c Normal file
View File

@ -0,0 +1,216 @@
/*
* eval.c - String to parameter
*
* Copyright 2012 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.
*/
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "bitset.h"
#include "param.h"
int eval_name(const struct format *fmt, const char *s, struct value *res)
{
res->u.name = s;
return 1;
}
static int lookup_name(const struct names *name, const char *s)
{
const struct equiv *eq;
int n;
for (n = 0; name; n++)
for (eq = name->equiv; eq; eq = eq->next)
if (eq->name == s)
return n;
return -1;
}
int eval_set(const struct format *fmt, const char *s, struct value *res)
{
int n;
bitset_zero(&res->u.set);
n = lookup_name(fmt->u.set, s);
if (n < 0)
return 0;
bitset_set(&res->u.set, n);
return 1;
}
static int decode_mult(char c, double *mult)
{
switch (c) {
case 'f':
*mult = 1e-15;
return 1;
case 'p':
*mult = 1e-12;
return 1;
case 'n':
*mult = 1e-9;
return 1;
case 'u':
*mult = 1e-6;
return 1;
case 'm':
*mult = 1e-3;
return 1;
case 'k':
*mult = 1e3;
return 1;
case 'M':
*mult = 1e6;
return 1;
default:
return 0;
}
}
static int strip_unit(const char *s, const char **stop, const char *unit,
double *mult)
{
int n;
n = strlen(unit);
if (*stop-n < s)
return 0;
if (!strcmp(*stop-n, unit))
*stop -= n;
if (*stop > s) {
if (decode_mult((*stop)[-1], mult))
(*stop)--;
else
*mult = 1;
} else {
*mult = 1;
}
return 1;
}
int eval_abs(const struct format *fmt, const char *s,
struct value *res)
{
const char *slash, *stop;
char *end;
double mult, a, b;
stop = strchr(s, 0);
if (!strip_unit(s, &stop, fmt->u.abs, &mult))
return 0;
slash = strchr(s, '/');
if (!slash) {
res->u.abs = strtod(s, &end)*mult;
return end == stop;
}
a = strtod(s, &end);
if (end != slash)
return 0;
b = strtod(slash+1, &end);
if (end != stop)
return 0;
res->u.abs = a/b*mult;
return 1;
}
static int plusminus(const char *s, const char *slash, const char *stop,
double *plus, double *minus)
{
char *end;
if (s == slash || slash == stop)
return 0;
/* -M/+P */
if (*s == '-') {
if (slash[1] != '+')
return 0;
*minus = strtod(s+1, &end);
if (end != slash)
return 0;
*plus = strtod(slash+2, &end);
return end == stop;
}
/* +P/-M */
if (*s == '+') {
if (slash[1] != '-')
return 0;
*plus = strtod(s+1, &end);
if (end != slash)
return 0;
*minus = strtod(slash+2, &end);
return end == stop;
}
/* M/P */
*minus = strtod(s, &end);
if (end != slash)
return 0;
*plus = strtod(slash+1, &end);
return end == stop;
}
static int relative(const char *s, const char *stop, double *plus,
double *minus)
{
const char *slash;
char *end;
slash = strchr(s, '/');
if (slash >= stop)
return 0;
if (slash)
return plusminus(s, slash, stop, plus, minus);
*plus = *minus = strtod(s, &end);
return *plus >= 0 && end == stop;
}
int eval_rel(const struct format *fmt, const char *s,
struct value *res)
{
const char *perc, *stop;
double mult = 1;
perc = strchr(s, '%');
res->u.rel.fract = !!perc;
if (perc) {
if (perc[1])
return 0;
return relative(s, perc, &res->u.rel.plus, &res->u.rel.minus);
}
assert(fmt->u.rel->ops == &param_ops_abs);
stop = strchr(s, 0);
if (!strip_unit(s, &stop, fmt->u.rel->u.abs, &mult))
return 0;
if (!relative(s, perc, &res->u.rel.plus, &res->u.rel.minus))
return 0;
res->u.rel.plus *= mult;
res->u.rel.minus *= mult;
return 1;
}
int evaluate(const struct format *fmt, const char *s, struct value *res)
{
return fmt->ops->eval(fmt, s, res);
}

59
b2/lang.l Normal file
View File

@ -0,0 +1,59 @@
%{
/*
* lang.l - BOOM syntax
*
* Copyright 2012 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.
*/
#include <stdarg.h>
#include <stdlib.h>
#include "util.h"
#include "param.h"
#include "y.tab.h"
static int lineno = 1;
%}
%%
[-_A-Za-z0-9()+./]+ { yylval.s = unique(yytext);
return WORD; }
"<=" return TOK_LE;
">=" return TOK_GE;
[ \t] ;
\n lineno++;
^#[^n]*\n lineno++;
. return *yytext;
%%
void yyerrorf(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
fprintf(stderr, "%d: ", lineno);
vfprintf(stderr, fmt, ap) ;
fprintf(stderr, "\n");
va_end(ap);
exit(1);
}
void yyerror(const char *s)
{
fprintf(stderr, "%d: %s\n", lineno, s);
exit(1);
}

206
b2/lang.y Normal file
View File

@ -0,0 +1,206 @@
%{
/*
* lang.y - BOOM grammar
*
* Copyright 2012 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.
*/
#include <stdlib.h>
#include "util.h"
#include "param.h"
#include "chr.h"
#include "y.tab.h"
%}
%union {
const char *s;
struct equiv *equiv;
struct names *names;
struct format *format;
enum relop relop;
};
%token TOK_LE TOK_GE
%token <s> WORD
%type <equiv> nameqs
%type <names> names nameq
%type <format> format
%type <relop> relop opt_relop
%%
all:
| nameset ';'
| rules
;
nameset:
'<' WORD '>' '=' names ';'
{
register_nameset($2, $5);
}
;
names:
nameq
{
$$ = $1;
}
| nameq '<' names
{
$$ = $1;
$$->next = $3;
}
;
nameq:
nameqs
{
$$ = alloc_type(struct names);
$$->equiv = $1;
$$->next = NULL;
}
;
nameqs:
WORD
{
$$ = alloc_type(struct equiv);
$$->name = $1;
$$->next = NULL;
}
| WORD '=' nameqs
{
$$ = alloc_type(struct equiv);
$$->name = $1;
$$->next = $3;
}
;
rules:
field '{'
{
field_mark();
}
selections opt_wildcard '}'
{
field_release();
}
;
selections:
| selectors ':' opt_fields rules selections
;
selectors:
selector
| selector '|'
{
field_more_selectors();
}
selectors
;
selector:
opt_relop WORD
{
field_add_selector($1, $2);
}
;
opt_wildcard:
'*' ':'
{
field_add_wildcard();
}
;
opt_relop:
{
$$ = rel_eq;
}
| relop
{
$$ = $1;
}
;
relop:
'='
{
$$ = rel_eq;
}
| '<'
{
$$ = rel_le;
}
| '>'
{
$$ = rel_gt;
}
| TOK_LE
{
$$ = rel_le;
}
| TOK_GE
{
$$ = rel_ge;
}
;
opt_fields:
| '{' fields '}'
;
fields:
| field fields
;
field:
WORD ':' format
{
field_add($1, $3);
}
;
format:
'*'
{
$$ = alloc_type(struct format);
$$->ops = &param_ops_name;
}
| '<' WORD '>'
{
$$ = alloc_type(struct format);
$$->ops = &param_ops_set;
$$->u.set = find_nameset($2);
if (!$$->u.set)
yyerrorf("unknown name set \"%s\"", $2);
}
| '#' WORD
{
$$ = alloc_type(struct format);
$$->ops = &param_ops_abs;
$$->u.abs = $2;
}
| '%' WORD
{
$$ = alloc_type(struct format);
$$->ops = &param_ops_rel;
$$->u.rel = field_find($2);
if (!$$->u.rel)
yyerrorf("unknown field \"%s\"", $2);
}
;

82
b2/param.c Normal file
View File

@ -0,0 +1,82 @@
/*
* param.c - Parameters and values
*
* Copyright 2012 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.
*/
#include <glib.h>
#include "util.h"
#include "param.h"
static GTree *tree;
static int duplicate(const char *a, const struct equiv *b)
{
while (b) {
if (a == b->name)
return 1;
b = b->next;
}
return 0;
}
static void check_duplicates(const struct names *n)
{
const struct names *na, *nb;
const struct equiv *ea;
for (na = n; na; na = na->next) {
for (ea = na->equiv; ea; ea = ea->next)
if (duplicate(ea->name, ea->next))
yyerrorf("duplicate name \"%s\"", ea->name);
for (nb = na->next; nb; nb = nb->next)
if (duplicate(ea->name, nb->equiv))
yyerrorf("duplicate name \"%s\"", ea->name);
}
}
static gint comp(gconstpointer a, gconstpointer b)
{
return a == b ? 0 : a < b ? -1 : 1;
}
void register_nameset(const char *name, const struct names *set)
{
if (!tree)
tree = g_tree_new(comp);
if (g_tree_lookup(tree, name))
yyerrorf("duplicate name set \"%s\"", name);
check_duplicates(set);
g_tree_insert(tree, (void *) name, (void *) set);
}
const struct names *find_nameset(const char *name)
{
return tree ? g_tree_lookup(tree, name) : NULL;
}
#define MKOPS(type) \
const struct param_ops param_ops_##type = { \
.eval = eval_##type, \
.comp = comp_##type, \
}
MKOPS(name);
MKOPS(set);
MKOPS(abs);
MKOPS(rel);

99
b2/param.h Normal file
View File

@ -0,0 +1,99 @@
/*
* param.h - Parameters and values
*
* Copyright 2012 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 PARAM_H
#define PARAM_H
#include "bitset.h"
/*
* Parameter types:
*
* "name" arbitrary name
* "set" names from an ordered list
* "abs" absolute numeric value
* "rel" numeric value relative to another parameter
*/
enum relop {
rel_lt = 1 << 0,
rel_le = 1 << 1,
rel_eq = 1 << 2,
rel_ge = 1 << 3,
rel_gt = 1 << 4,
};
struct equiv {
const char *name;
struct equiv *next;
};
struct names {
struct equiv *equiv; /* equivalent value(s) */
struct names *next; /* next/greater value */
};
struct param_ops;
struct format {
const struct param_ops *ops;
union {
const struct names *set;
const char *abs; /* unit name */
const struct format *rel;
} u;
};
struct value {
union {
const char *name;
struct bitset set;
double abs;
struct rel_value {
double plus, minus;
int fract; /* 0: abs. offset; 1: fract. offs. */
} rel;
} u;
};
struct param_ops {
int (*eval)(const struct format *fmt, const char *s,
struct value *res);
int (*comp)(const struct value *a, enum relop relop,
const struct value *b);
};
void register_nameset(const char *name, const struct names *set);
const struct names *find_nameset(const char *name);
int eval_name(const struct format *fmt, const char *s, struct value *res);
int eval_set(const struct format *fmt, const char *s, struct value *res);
int eval_abs(const struct format *fmt, const char *s, struct value *res);
int eval_rel(const struct format *fmt, const char *s, struct value *res);
int evaluate(const struct format *fmt, const char *s, struct value *res);
int comp_name(const struct value *a, enum relop relop, const struct value *b);
int comp_set(const struct value *a, enum relop relop, const struct value *b);
int comp_abs(const struct value *a, enum relop relop, const struct value *b);
int comp_rel(const struct value *a, enum relop relop, const struct value *b);
int compare(const struct format *fmt,
const struct value *a, enum relop relop, const struct value *b);
extern const struct param_ops param_ops_name;
extern const struct param_ops param_ops_set;
extern const struct param_ops param_ops_abs;
extern const struct param_ops param_ops_rel;
#endif /* !PARAM_H */

40
b2/util.c Normal file
View File

@ -0,0 +1,40 @@
/*
* util.h - Utility functions
*
* Copyright 2012 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.
*/
#include <string.h>
#include <glib.h>
#include "util.h"
static GTree *tree = NULL;
static gint comp(gconstpointer a, gconstpointer b)
{
return strcmp(a, b);
}
const char *unique(const char *s)
{
char *u;
if (!tree)
tree = g_tree_new(comp);
u = g_tree_lookup(tree, s);
if (!u) {
u = strdup(s);
g_tree_insert(tree, u, u);
}
return u;
}

32
b2/util.h Normal file
View File

@ -0,0 +1,32 @@
/*
* util.h - Utility functions
*
* Copyright 2012 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 UTIL_H
#define UTIL_H
#include <stdlib.h>
#define alloc_size(s) \
({ void *alloc_size_tmp = malloc(s); \
if (!alloc_size_tmp) \
abort(); \
alloc_size_tmp; })
#define alloc_type(t) ((t *) alloc_size(sizeof(t)))
const char *unique(const char *s);
void yyerrorf(const char *fmt, ...);
void yyerror(const char *s);
#endif /* !UTIL_H */