#include <stdio.h>
#include <string.h>
#include "parser.h"
#include "trace.h"
#include "util.h"
#include "symtab.h"
#include "io.h"
#include "bindings.h"
#include "errlog.h"
static void generate_a_binding(char *, char *);
static int strpqcmp(char *, char *, char *);
static void strpqprint(char *, char *, FILE *);
int
need_bindings(char *exception)
{
errlog(BEGIN, "need_bindings() {");
if (exception == NULL)
exception = "";
if (strcmp(exception, "false") == 0 ||
*exception == '\0') {
errlog(END, "}");
return (NO);
}
errlog(END, "}");
return (YES);
}
int
need_exception_binding(void)
{
ENTRY *e;
char *exception;
exception = ((e = symtab_get_exception()) != NULL)?
(name_of(e)? name_of(e): ""): "";
return (need_bindings(exception));
}
int
generate_bindings(char *exception)
{
int ret = NO;
errlog(BEGIN, "generate_bindings() {");
errlog(TRACING, "exception=%s\n", exception ? exception : "NULL");
if (exception != NULL) {
generate_a_binding("exception", exception);
errlog(END, "}");
}
return (ret);
}
int
bindings_exist(void)
{
int ret;
errlog(BEGIN, "bindings_exist() {");
errlog(END, "}");
ret = validity_of(symtab_get_exception()) == YES;
return (ret);
}
static void
generate_a_binding(char *name, char *value)
{
char *p = value;
ENTRY *e = symtab_get_errval();
char *errvar = (e == NULL)? NULL: name_of(e);
char *q;
errlog(BEGIN, "generate_a_binding() {");
if (*value == '\0') {
errlog(FATAL, "programmer error: asked to generate an "
"empty binding");
}
{
ENTRY *exc = symtab_get_exception();
if (exc != NULL)
(void) fprintf(Bodyfp,
"#line %d \"%s\"\n",
line_of(exc), symtab_get_filename());
}
(void) fprintf(Bodyfp, " %s = (", name);
for (; *p != '\0'; p = q) {
p = skipb(p);
q = nextsep(p);
if (p == q) {
if (*p == '(') {
q++;
} else if (*p == ')') {
q++;
} else if (*p == '!' && *(p+1) != '=') {
q++;
} else if ((q = nextb(p)) == p) {
break;
}
}
if (strpqcmp("$return", p, q) == 0) {
(void) fputs("_return", Bodyfp);
} else if (errvar != NULL && strpqcmp(errvar, p, q) == 0) {
(void) fputs("functions_errvar", Bodyfp);
} else if (strpqcmp("unchanged", p, q) == 0) {
(void) fputs("0 == ", Bodyfp);
} else if (strpqcmp("oneof", p, q) == 0) {
errlog(WARNING, "Oneof unimplemented in spec2trace"
"It will be treated as the token 'false'");
(void) fputs("false", Bodyfp);
break;
} else if (strpqcmp("someof", p, q) == 0) {
errlog(WARNING, "Someof unimplemented in spec2trace, "
"It will be treated as the token 'false'");
(void) fputs("false", Bodyfp);
break;
} else if (strpqcmp("errno", p, q) == 0) {
(void) fputs("ABI_ERRNO", Bodyfp);
} else {
strpqprint(p, q, Bodyfp);
}
(void) putc(' ', Bodyfp);
}
(void) (void) fputs(");\n", Bodyfp);
errlog(END, "}");
}
static int
strpqcmp(char *v1, char *p, char *q)
{
int rc;
char saved;
errlog(BEGIN, "strpqcmp() {");
saved = *q;
*q = '\0';
rc = (strcmp(v1, p));
*q = saved;
errlog(END, "}");
return (rc);
}
static void
strpqprint(char *p, char *q, FILE *fp)
{
char saved;
errlog(BEGIN, "strpqprint() {");
saved = *q;
*q = '\0';
(void) fputs(p, fp);
*q = saved;
errlog(END, "}");
}