ref: a8558cb1e89245ecb38501b0fe4b64462ba69889
dir: /preproc.c/
#include <u.h>
#include <libc.h>
#include <regexp.h>
#include <String.h>
#include "spread.h"
Reprog *rrange = nil;
/* begin test code */
/* acid:
* acid: new()
* acid: *PC=testpreproc
* acid: cont()
*/
void
t(char *s)
{
Cell c;
c.procvalue = nil;
c.value = strdup(s);
preprocess(&c);
fprint(2, "'%s' → '%s'\n", s, c.procvalue);
free(c.value);
}
void
testpreproc(void)
{
t("A1()+[A1()/B4()]+A5()");
t("A1()+[A1()+B4()]+A5()");
t("A1()+[A1()-B4()]+A5()");
t("A1()+[A1()*B4()]+A5()");
exits(nil);
}
/* end test code */
void
appendrange(String *s, char sign, P a, P b)
{
int x, y;
P na, nb;
P p;
char *ps;
int first;
na.x = a.x < b.x ? a.x : b.x;
na.y = a.y < b.y ? a.y : b.y;
nb.x = a.x > b.x ? a.x : b.x;
nb.y = a.y > b.y ? a.y : b.y;
first = 1;
s_putc(s, '(');
for (x = na.x; x <= nb.x; x++)
for (y = na.y; y <= nb.y; y++) {
p.x = x;
p.y = y;
ps = ptoa(p);
if (!first)
s_putc(s, sign);
first = 0;
s_append(s, ps);
s_append(s, "()");
}
s_putc(s, ')');
}
int
prange(Cell *c)
{
Resub match[4];
char *s;
String *str;
P a, b;
char sign;
if (!rrange)
rrange = regcomp("\\[([A-Z]+[0-9]+\\(\\))([+\\-*/])([A-Z]+[0-9]+\\(\\))\\]");
assert(rrange);
memset(match, 0, 4*sizeof(Resub));
s = c->procvalue ? c->procvalue : c->value;
str = nil;
while (regexec(rrange, s, match, 4)) {
if (!str)
str = s_new();
s_nappend(str, s, match[0].sp-s);
s = match[0].ep;
sign = *match[2].sp;
a = atop(match[1].sp);
b = atop(match[3].sp);
appendrange(str, sign, a, b);
match[0].sp = nil;
match[0].ep = nil;
}
if (str) {
s_append(str, s);
c->procvalue = strdup(s_to_c(str));
s_free(str);
} else
c->procvalue = c->value;
return 1;
}
int
preprocess(Cell *c)
{
int r = 0;
if (!prange(c))
r++;
return !r;
}