56 else if (subop >
' ' && subop <=
'~')
63 else if (op >
' ' && op <=
'~')
84 if (ex->disc->inf !=
NULL) {
98 key = ex->disc->keyf(v,
type);
101 snprintf(buf,
sizeof(buf),
"%llx", (
unsigned long long)key.
integer);
128 char buf[2*
sizeof(key.
integer)+1];
146 key = ex->disc->keyf(v,
type);
149 snprintf(buf,
sizeof(buf),
"%llx", (
unsigned long long)key.
integer);
155 b = calloc(1,
sizeof(
Exassoc_t) + strlen(keyname));
159 strcpy(b->
name, keyname);
212 exerror(
"printf: not enough arguments");
216 const long from =
node->type;
245 node->data.operand.left = 0;
253 exerror(
"printf: out of memory");
271 fmt->
fmt.
size =
sizeof(double);
275 dp->
size =
sizeof(
long long);
291 if (*(
char**)vp ==
NULL) {
292 exerror(
"printf: out of memory");
299 dp->
flags &= ~SFFMT_LONG;
315 *
s = (
char)tolower(*
s);
317 *
s = (char)toupper(*
s);
339 if ((tm = *(
long long *)vp) == -1)
342 exerror(
"printf: no time format provided");
345 stm = localtime(&tm);
349 exerror(
"printf: out of memory");
392 v =
eval(ex, exnode->
data.print.descriptor, env);
401 memset(&fmt, 0,
sizeof(fmt));
405 x = exnode->
data.print.args;
417 }
while ((x = x->
next));
442 exerror(
"scanf: not enough arguments");
452 exerror(
"scanf: %s: floating variable address argument expected",
node->data.variable.symbol->name);
455 fmt->
fmt.
size =
sizeof(double);
456 const void *
const value = &
node->data.variable.symbol->value->data.constant.value;
457 memcpy(vp, &value,
sizeof(value));
464 exerror(
"scanf: %s: string variable address argument expected",
node->data.variable.symbol->name);
468 node->data.variable.symbol->value->data.constant.value.string = 0;
470 char *
s =
node->data.variable.symbol->value->data.constant.value.string;
473 memset(
s, 0,
sizeof(
char) * (
size_t)fmt->
fmt.
size);
474 memcpy(vp, &
s,
sizeof(
s));
475 node->data.variable.symbol->value->data.constant.value.string =
s;
480 exerror(
"scanf: %s: char variable address argument expected",
node->data.variable.symbol->name);
483 fmt->
fmt.
size =
sizeof(
long long);
484 const void *
const value = &
node->data.variable.symbol->value->data.constant.value;
485 memcpy(vp, &value,
sizeof(value));
491 exerror(
"scanf: %s: integer variable address argument expected",
node->data.variable.symbol->name);
494 dp->
size =
sizeof(
long long);
495 const void *
const value = &
node->data.variable.symbol->value->data.constant.value;
496 memcpy(vp, &value,
sizeof(value));
517 if (exnode->
data.scan.descriptor)
519 v =
eval(ex, exnode->
data.scan.descriptor, env);
520 if (exnode->
data.scan.descriptor->type ==
STRING)
532 memset(&fmt, 0,
sizeof(fmt));
536 u =
eval(ex, exnode->
data.scan.format, env);
542 exerror(
"scanf: failed to open temporary file");
564 size_t sz = strlen(l) + strlen(r) + 1;
569 snprintf(
s, sz,
"%s%s", l, r);
581 for (
const char *p = l; *p !=
'\0'; ++p) {
582 if (strchr(p + 1, *p) ==
NULL) {
586 for (
const char *p = r; *p !=
'\0'; ++p) {
587 if (strchr(l, *p) ==
NULL && strchr(p + 1, *p) ==
NULL) {
594 if (result ==
NULL) {
600 for (
const char *p = l; *p !=
'\0'; ++p) {
601 if (strchr(p + 1, *p) ==
NULL) {
602 assert(i <
len &&
"incorrect preceding length computation");
607 for (
const char *p = r; *p !=
'\0'; ++p) {
608 if (strchr(l, *p) ==
NULL && strchr(p + 1, *p) ==
NULL) {
609 assert(i <
len &&
"incorrect preceding length computation");
614 assert(i + 1 ==
len &&
"incorrect preceding length computation");
628 for (
const char *p = l; *p !=
'\0'; ++p) {
629 if (strchr(r, *p) !=
NULL && strchr(p + 1, *p) ==
NULL) {
636 if (result ==
NULL) {
642 for (
const char *p = l; *p !=
'\0'; ++p) {
643 if (strchr(r, *p) !=
NULL && strchr(p + 1, *p) ==
NULL) {
644 assert(i <
len &&
"incorrect preceding length computation");
649 assert(i + 1 ==
len &&
"incorrect preceding length computation");
663 for (
const char *p = l; *p !=
'\0'; ++p) {
664 if (strchr(r, *p) ==
NULL && strchr(p + 1, *p) ==
NULL) {
668 for (
const char *p = r; *p !=
'\0'; ++p) {
669 if (strchr(l, *p) ==
NULL && strchr(p + 1, *p) ==
NULL) {
676 if (result ==
NULL) {
682 for (
const char *p = l; *p !=
'\0'; ++p) {
683 if (strchr(r, *p) ==
NULL && strchr(p + 1, *p) ==
NULL) {
684 assert(i <
len &&
"incorrect preceding length computation");
689 for (
const char *p = r; *p !=
'\0'; ++p) {
690 if (strchr(l, *p) ==
NULL && strchr(p + 1, *p) ==
NULL) {
691 assert(i <
len &&
"incorrect preceding length computation");
696 assert(i + 1 ==
len &&
"incorrect preceding length computation");
710 for (
const char *p = l; *p !=
'\0'; ++p) {
711 if (strchr(r, *p) ==
NULL && strchr(p + 1, *p) ==
NULL) {
718 if (result ==
NULL) {
724 for (
const char *p = l; *p !=
'\0'; ++p) {
725 if (strchr(r, *p) ==
NULL && strchr(p + 1, *p) ==
NULL) {
726 assert(i <
len &&
"incorrect preceding length computation");
731 assert(i + 1 ==
len &&
"incorrect preceding length computation");
744 size_t len = strlen(l);
746 size_t len2 = strlen(r);
755 if (result ==
NULL) {
761 for (; l[i] !=
'\0' && r[i] !=
'\0'; ++i) {
762 assert(i <
len &&
"incorrect preceding length computation");
763 result[i] = l[i] == r[i] ? l[i] :
' ';
765 assert(i + 1 ==
len &&
"incorrect preceding length computation");
779 while ((c = *repl++)) {
784 const size_t offset =
sub[2 * idx];
803 exerror(
"out of space [assoc]");
821 Dt_t* arr = exnode->
data.split.array->local;
824 if (exnode->
data.split.seps)
831 sz = strspn (
str, seps);
837 for (
size_t i = 1; i < sz; i++) {
848 sz = strcspn (
str, seps);
874 Dt_t* arr = exnode->
data.split.array->local;
877 if (exnode->
data.split.seps)
884 sz = strspn (
str, seps);
889 sz = strcspn (
str, seps);
922 if (exnode->
data.string.repl)
938 if (p > pat && p[-1] ==
'\\') {
958 exwarn(
"pattern match of empty string - ill-specified pattern \"%s\"?", pat);
999 s =
eval(ex, exnode->
data.string.base, env);
1000 len = strlen(
s.string);
1001 i =
eval(ex, exnode->
data.string.pat, env);
1003 exerror(
"illegal start index in substr(%s,%lld)",
s.string, i.
integer);
1004 if (exnode->
data.string.repl) {
1005 l =
eval(ex, exnode->
data.string.repl, env);
1007 exerror(
"illegal length in substr(%s,%lld,%lld)",
1013 if (exnode->
data.string.repl) {
1029 if (ex->disc->convertf(tmp,
type, 0)) {
1030 exerror(
"%s: cannot convert %s value to %s",
1043 if (ex->disc->stringof(ex, tmp, 0))
1044 exerror(
"%s: no string representation of %s value",
1071 if (!exnode || ex->loopcount)
1081 v =
eval(ex, x, env);
1083 ex->loopop = exnode->
op;
1091 r =
getdyn(ex, x, env, &assoc);
1149 if (exnode->subop ==
PRE)
1153 return getdyn(ex, exnode, env, &assoc);
1155 return exsplit(ex, exnode, env);
1159 return exsub(ex, exnode, env,
true);
1161 return exsub(ex, exnode, env,
false);
1169 seed = (long)time(0);
1176 v =
eval(ex, x, env);
1177 if (ex->disc->exitf)
1178 ex->disc->exitf(env, (
int)v.
integer);
1183 v =
eval(ex, x, env);
1195 r =
eval(ex, x, env);
1204 if (ex->loopcount > 0 && (--ex->loopcount > 0 || ex->loopop !=
CONTINUE))
1215 v =
eval(ex, x, env);
1232 if ((*t)->integer == v.
integer)
1255 if (ex->loopcount > 0)
1264 r =
eval(ex, a, env);
1265 if (ex->loopcount > 0)
1282 if (ex->loopcount > 0 && (--ex->loopcount > 0 || ex->loopop !=
CONTINUE))
1298 if (ex->loopcount > 0 && (--ex->loopcount > 0 || ex->loopop !=
CONTINUE))
1310 for (assoc =
dtlast(exnode->
data.generate.array->
1311 data.variable.symbol->local); assoc;
1320 if (ex->loopcount > 0 && (--ex->loopcount > 0 || ex->loopop !=
CONTINUE)) {
1332 if (ex->loopcount > 0 && (--ex->loopcount > 0 || ex->loopop !=
CONTINUE)) {
1341 if (ex->disc->lengthf !=
NULL) {
1364 x = exnode->
data.call.args;
1370 args[n++] =
eval(ex, x->data.operand.left, env);
1374 x = x->data.operand.right;
1376 for (n = 0, a = exnode->
data.call.procedure->
value->data.procedure.args;
1380 exerror(
"too many actual args");
1382 exerror(
"not enough actual args");
1383 v =
exeval(ex, exnode->
data.call.procedure->
value->data.procedure.body, env);
1384 for (n = 0, a = exnode->
data.call.procedure->
value->data.procedure.args;
1391 x = x->data.operand.right)
1392 args[n++] =
eval(ex, x->data.operand.left, env);
1401 x = x->data.operand.right)
1402 args[n++] =
eval(ex, x->data.operand.left, env);
1429 ex->loopret =
eval(ex, x, env);
1430 ex->loopcount = 32767;
1431 ex->loopop = exnode->
op;
1438 FILE *buffer = tmpfile();
1439 if (buffer ==
NULL) {
1440 fprintf(stderr,
"out of memory\n");
1443 print(ex, exnode, env, buffer);
1444 const size_t size =
gv_ftell(buffer);
1450 if (fread(v.
string, size, 1, buffer) < 1) {
1451 fprintf(stderr,
"failed to read back temporary file\n");
1461 if (exnode->subop !=
'=')
1465 v =
getdyn(ex, x, env, &assoc);
1468 if (x->data.variable.index)
1469 v =
eval(ex, x->data.variable.index, env);
1472 if (x->data.variable.dyna) {
1474 locv =
getdyn(ex, x->data.variable.dyna, env, &assoc);
1475 x->data.variable.dyna->data.variable.dyna->data.constant.value = locv;
1477 v = ex->disc->getf(ex, x, x->data.variable.symbol,
1478 x->data.variable.reference, env, (
int)v.
integer,
1484 switch (exnode->subop)
1497 exerror(
"floating divide by 0");
1503 exerror(
"floating 0 modulus");
1532 switch (exnode->subop)
1545 exerror(
"integer divide by 0");
1575 switch (exnode->subop)
1604 getdyn(ex, x, env, &assoc);
1611 v =
eval(ex, x, env);
1618 return exnode ?
eval(ex, exnode, env) : v;
1620 v =
eval(ex, x, env);
1623 v =
eval(ex, x, env);
1626 v =
eval(ex, x, env);
1629 v =
eval(ex, x, env);
1631 r =
eval(ex, x, env);
1637 if (!ex->disc->binaryf(&tmp, exnode, &rtmp, 0))
1656 else if (ex->disc->convertf(&tmp,
STRING, 0)) {
1664 if (ex->disc->convertf(&tmp, exnode->
type, 0))
1697 exerror(
"floating divide by 0");
1703 exerror(
"floating 0 modulus");
1749 xPrint(ex, exnode, v, &tmp);
1760 if (!ex->disc->binaryf(&tmp, exnode, rp, 0))
1807 else if (ex->disc->convertf(&tmp,
STRING, 0)) {
1820 if (ex->disc->convertf(&tmp, exnode->
type, 0))
1853 exerror(
"integer divide by 0");
1898 if (ex->disc->convertf(&tmp,
FLOATING, 0))
1909 if (ex->disc->convertf(&tmp,
INTEGER, 0))
1924 if (ex->disc->convertf(&tmp, exnode->
type, 0))
1973 char *op =
lexname(exnode->
op, exnode->subop);
1977 exerror(
"operator %s %s %s not implemented",
left, op,
1981 exerror(
"operator %s %s not implemented", op,
left);
1996 switch (exnode->
type)
2011 v =
eval(ex, exnode, env);
2012 if (ex->loopcount > 0)
2015 if (ex->loopop ==
RETURN)
Agobj_t * copy(Agraph_t *g, Agobj_t *obj)
static void agxbfree(agxbuf *xb)
free any malloced resources
static size_t agxbput_n(agxbuf *xb, const char *s, size_t ssz)
append string s of length ssz into xb
static int agxbprint(agxbuf *xb, const char *fmt,...)
Printf-style output to an agxbuf.
static WUR char * agxbuse(agxbuf *xb)
static int agxbputc(agxbuf *xb, char c)
add character to buffer
static char * agxbdisown(agxbuf *xb)
Memory allocation wrappers that exit on failure.
static char * gv_strdup(const char *original)
char * fmtquote(const char *, const char *, const char *)
quote string as with qb...qe
int strmatch(char *, char *)
int strgrpmatch(char *, char *, size_t *, int, int)
CDT_API int dtsize(Dt_t *)
void exwarn(const char *format,...)
void exerror(const char *format,...)
static int prints(Expr_t *ex, Exnode_t *exnode, void *env, FILE *sp)
static int scformat(void *vp, Sffmt_t *dp)
static Extype_t getdyn(Expr_t *ex, Exnode_t *exnode, void *env, Exassoc_t **assoc)
static void xConvert(Expr_t *ex, Exnode_t *exnode, long type, Extype_t v, Exnode_t *tmp)
static char * str_add(Expr_t *ex, char *l, char *r)
static Extype_t exsub(Expr_t *ex, Exnode_t *exnode, void *env, bool global)
static char * str_xor(Expr_t *ex, const char *l, const char *r)
char * exstring(Expr_t *ex, char *s)
static char * str_and(Expr_t *ex, const char *l, const char *r)
static Extype_t eval(Expr_t *, Exnode_t *, void *)
Extype_t exeval(Expr_t *ex, Exnode_t *exnode, void *env)
static char * str_mpy(Expr_t *ex, const char *l, const char *r)
static Extype_t exsplit(Expr_t *ex, Exnode_t *exnode, void *env)
static void xPrint(Expr_t *ex, Exnode_t *exnode, Extype_t v, Exnode_t *tmp)
static void addItem(Dt_t *arr, Extype_t v, char *tok)
static int prformat(void *vp, Sffmt_t *dp)
static Extype_t exsubstr(Expr_t *ex, Exnode_t *exnode, void *env)
static void replace(agxbuf *s, char *base, char *repl, int ng, size_t *sub)
static char * str_mod(Expr_t *ex, const char *l, const char *r)
static char * lexname(long op, int subop)
static int evaldyn(Expr_t *ex, Exnode_t *exnode, void *env, int delete)
static int scan(Expr_t *ex, Exnode_t *exnode, void *env, FILE *sp)
static int print(Expr_t *ex, Exnode_t *exnode, void *env, FILE *sp)
static char * str_ior(Expr_t *ex, const char *l, const char *r)
static Extype_t extokens(Expr_t *ex, Exnode_t *exnode, void *env)
void * exstralloc(Expr_t *ex, size_t sz)
static NORETURN void graphviz_exit(int status)
const char * exop(size_t id)
Exnode_t * excast(Expr_t *, Exnode_t *, long, Exnode_t *, int)
static char * exprintf(Vmalloc_t *vm, const char *fmt,...)
char * extypename(Expr_t *p, long)
Extype_t exzero(long int)
static double len(glCompPoint p)
replacements for ctype.h functions
static void gv_tolower_str(char *s)
static bool gv_islower(int c)
static bool gv_isupper(int c)
static bool gv_isalnum(int c)
static void gv_toupper_str(char *s)
static bool gv_isdigit(int c)
static bool gv_isalpha(int c)
static size_t gv_ftell(FILE *stream)
ftell, accounting for platform limitations
GVIO_API const char * format
textitem scanner parser str
static Ppoint_t add(Ppoint_t, Ppoint_t)
int sfprint(FILE *, Sffmt_t *format)
int sfvscanf(FILE *, Sffmt_t *format)
void * local
user defined local stuff
long long(* integer)(char **)
INTEGER|UNSIGNED return value.
char *(* string)(char **)
double(* floating)(char **)
union Exnode_s::@93 compiled
bool binary
data.operand.{left,right} ok
struct Exnode_s * param[3]
a non-owning string reference
const char * data
start of the pointed to string
size_t size
extent of the string in bytes
Non-owning string references.
static bool strview_str_eq(strview_t a, const char *b)
compare a string reference to a string for equality
static tok_t tok(const char *input, const char *separators)
begin tokenization of a new string
struct Exdata_u::@89 constant
struct Exdata_u::@90 operand
struct Exdata_u::@92 variable
struct Exdata_u::@91 select
void vmfree(Vmalloc_t *vm, void *data)
void * vmalloc(Vmalloc_t *vm, size_t size)
char * vmstrdup(Vmalloc_t *, const char *)