10eb10989Smrg/*
20eb10989Smrg
30eb10989SmrgCopyright (c) 1993, 1994, 1998  The Open Group
40eb10989Smrg
50eb10989SmrgPermission to use, copy, modify, distribute, and sell this software and its
60eb10989Smrgdocumentation for any purpose is hereby granted without fee, provided that
70eb10989Smrgthe above copyright notice appear in all copies and that both that
80eb10989Smrgcopyright notice and this permission notice appear in supporting
90eb10989Smrgdocumentation.
100eb10989Smrg
110eb10989SmrgThe above copyright notice and this permission notice shall be included in
120eb10989Smrgall copies or substantial portions of the Software.
130eb10989Smrg
140eb10989SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
150eb10989SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
160eb10989SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
170eb10989SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
180eb10989SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
190eb10989SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
200eb10989Smrg
210eb10989SmrgExcept as contained in this notice, the name of The Open Group shall not be
220eb10989Smrgused in advertising or otherwise to promote the sale, use or other dealings
230eb10989Smrgin this Software without prior written authorization from The Open Group.
240eb10989Smrg
250eb10989Smrg*/
260eb10989Smrg
270eb10989Smrg#include "def.h"
280eb10989Smrg
290eb10989Smrg#include "ifparser.h"
3063165362Smrg
310eb10989Smrgstruct _parse_data {
320eb10989Smrg    struct filepointer *filep;
330eb10989Smrg    struct inclist *inc;
3463165362Smrg    const char *filename;
350eb10989Smrg    const char *line;
360eb10989Smrg};
370eb10989Smrg
380eb10989Smrgstatic const char *
39fadff096Smrgmy_if_errors(IfParser *ip, const char *cp, const char *expecting)
400eb10989Smrg{
41fadff096Smrg    struct _parse_data *pd = ip->data;
42fadff096Smrg    long lineno = pd->filep->f_line;
4363165362Smrg    const char *filename = pd->filename;
440eb10989Smrg    char prefix[300];
45fadff096Smrg    long prefixlen;
46fadff096Smrg    long i;
470eb10989Smrg
48fadff096Smrg    snprintf(prefix, sizeof(prefix), "\"%s\":%ld", filename, lineno);
49fadff096Smrg    prefixlen = (long) strlen(prefix);
50fadff096Smrg    fprintf(stderr, "%s:  %s", prefix, pd->line);
510eb10989Smrg    i = cp - pd->line;
52fadff096Smrg    if (i > 0 && pd->line[i - 1] != '\n') {
53fadff096Smrg        putc('\n', stderr);
540eb10989Smrg    }
550eb10989Smrg    for (i += prefixlen + 3; i > 0; i--) {
56fadff096Smrg        putc(' ', stderr);
570eb10989Smrg    }
58fadff096Smrg    fprintf(stderr, "^--- expecting %s\n", expecting);
590eb10989Smrg    return NULL;
600eb10989Smrg}
610eb10989Smrg
620eb10989Smrg
630eb10989Smrg#define MAXNAMELEN 256
640eb10989Smrg
650eb10989Smrgstatic struct symtab **
66fadff096Smrglookup_variable(IfParser *ip, const char *var, int len)
670eb10989Smrg{
680eb10989Smrg    char tmpbuf[MAXNAMELEN + 1];
69fadff096Smrg    struct _parse_data *pd = ip->data;
700eb10989Smrg
710eb10989Smrg    if (len > MAXNAMELEN)
72fadff096Smrg        return NULL;
730eb10989Smrg
74fadff096Smrg    strncpy(tmpbuf, var, len);
750eb10989Smrg    tmpbuf[len] = '\0';
76fadff096Smrg    return isdefined(tmpbuf, pd->inc, NULL);
770eb10989Smrg}
780eb10989Smrg
790eb10989Smrg
800eb10989Smrgstatic int
81fadff096Smrgmy_eval_defined(IfParser *ip, const char *var, int len)
820eb10989Smrg{
83fadff096Smrg    if (lookup_variable(ip, var, len))
84fadff096Smrg        return 1;
850eb10989Smrg    else
86fadff096Smrg        return 0;
870eb10989Smrg}
880eb10989Smrg
890eb10989Smrg#define isvarfirstletter(ccc) (isalpha(ccc) || (ccc) == '_')
900eb10989Smrg
910eb10989Smrgstatic long
92fadff096Smrgmy_eval_variable(IfParser *ip, const char *var, int len)
930eb10989Smrg{
940eb10989Smrg    long val;
950eb10989Smrg    struct symtab **s;
960eb10989Smrg
97fadff096Smrg    s = lookup_variable(ip, var, len);
980eb10989Smrg    if (!s)
99fadff096Smrg        return 0;
1000eb10989Smrg    do {
101fadff096Smrg        var = (*s)->s_value;
102fadff096Smrg        if (!isvarfirstletter(*var) || !strcmp((*s)->s_name, var))
103fadff096Smrg            break;
104fadff096Smrg        s = lookup_variable(ip, var, strlen(var));
1050eb10989Smrg    } while (s);
1060eb10989Smrg
1070eb10989Smrg    var = ParseIfExpression(ip, var, &val);
108fadff096Smrg    if (var && *var)
109fadff096Smrg        debug(4, ("extraneous: '%s'\n", var));
1100eb10989Smrg    return val;
1110eb10989Smrg}
1120eb10989Smrg
1130eb10989Smrgint
114fadff096Smrgcppsetup(const char *filename, const char *line,
115fadff096Smrg         struct filepointer *filep, struct inclist *inc)
1160eb10989Smrg{
117fadff096Smrg    struct _parse_data pd = {
118fadff096Smrg        .filep = filep,
119fadff096Smrg        .inc = inc,
120fadff096Smrg        .line = line,
121fadff096Smrg        .filename = filename
122fadff096Smrg    };
123fadff096Smrg    IfParser ip = {
124fadff096Smrg        .funcs.handle_error = my_if_errors,
125fadff096Smrg        .funcs.eval_defined = my_eval_defined,
126fadff096Smrg        .funcs.eval_variable = my_eval_variable,
127fadff096Smrg        .data = &pd
128fadff096Smrg    };
1290eb10989Smrg    long val = 0;
1300eb10989Smrg
131fadff096Smrg    (void) ParseIfExpression(&ip, line, &val);
1320eb10989Smrg    if (val)
133fadff096Smrg        return IF;
1340eb10989Smrg    else
135fadff096Smrg        return IFFALSE;
1360eb10989Smrg}
137