2006-04-11 21:52:54 +00:00
|
|
|
/*
|
2007-04-11 08:12:51 +00:00
|
|
|
* Copyright (c) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
|
|
|
|
* NOVELL (All rights reserved)
|
2006-04-11 21:52:54 +00:00
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of version 2 of the GNU General Public
|
|
|
|
* License published by the Free Software Foundation.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, contact Novell, Inc.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <search.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdarg.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <libintl.h>
|
2010-07-31 16:00:52 -07:00
|
|
|
#include <linux/limits.h>
|
2006-04-11 21:52:54 +00:00
|
|
|
#define _(s) gettext(s)
|
|
|
|
|
|
|
|
#include "immunix.h"
|
|
|
|
#include "parser.h"
|
|
|
|
|
|
|
|
enum var_type {
|
|
|
|
sd_boolean,
|
|
|
|
sd_set,
|
|
|
|
};
|
|
|
|
|
|
|
|
struct symtab {
|
|
|
|
char *var_name;
|
|
|
|
enum var_type type;
|
|
|
|
int boolean;
|
|
|
|
struct set_value *values;
|
|
|
|
struct set_value *expanded;
|
|
|
|
};
|
|
|
|
|
|
|
|
static void *my_symtab = NULL;
|
|
|
|
|
|
|
|
static int __expand_variable(struct symtab *symbol);
|
|
|
|
|
|
|
|
static struct symtab *new_symtab_entry(const char *name)
|
|
|
|
{
|
|
|
|
struct symtab *new = calloc(1, sizeof(*new));
|
|
|
|
|
|
|
|
if (!new) {
|
|
|
|
PERROR("Failed to allocate memory: %s\n", strerror(errno));
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
new->var_name = strndup(name, PATH_MAX);
|
|
|
|
if (!new->var_name) {
|
|
|
|
PERROR("Failed to allocate memory: %s\n", strerror(errno));
|
|
|
|
free(new);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return new;
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct set_value *new_set_value(const char *val)
|
|
|
|
{
|
|
|
|
struct set_value *new = calloc(1, sizeof(*new));
|
|
|
|
|
|
|
|
if (!new) {
|
|
|
|
PERROR("Failed to allocate memory: %s\n", strerror(errno));
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
new->val = strndup(val, PATH_MAX);
|
|
|
|
if (!new->val) {
|
|
|
|
PERROR("Failed to allocate memory: %s\n", strerror(errno));
|
|
|
|
free(new);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return new;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void free_values(struct set_value *val)
|
|
|
|
{
|
|
|
|
struct set_value *this = val, *tmp;
|
|
|
|
|
|
|
|
while (this) {
|
|
|
|
if (this->val)
|
|
|
|
free(this->val);
|
|
|
|
tmp = this;
|
|
|
|
this = this->next;
|
|
|
|
free(tmp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void free_symtab(struct symtab *symtab)
|
|
|
|
{
|
|
|
|
if (!symtab)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (symtab->var_name)
|
|
|
|
free(symtab->var_name);
|
|
|
|
|
|
|
|
free_values(symtab->values);
|
2009-07-24 13:24:53 +00:00
|
|
|
free_values(symtab->expanded);
|
2006-04-11 21:52:54 +00:00
|
|
|
free(symtab);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* abstract this out in case we switch data structures */
|
|
|
|
static void add_to_set(struct set_value **list, const char *val)
|
|
|
|
{
|
|
|
|
struct set_value *new_item = new_set_value(val);
|
|
|
|
|
|
|
|
new_item->next = *list;
|
|
|
|
*list = new_item;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int compare_symtabs(const void *a, const void *b)
|
|
|
|
{
|
|
|
|
char *a_name = ((struct symtab *) a)->var_name;
|
|
|
|
char *b_name = ((struct symtab *) b)->var_name;
|
|
|
|
return strcmp(a_name, b_name);
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct symtab *lookup_existing_symbol(const char *var)
|
|
|
|
{
|
|
|
|
struct symtab *tmp, **lookup;
|
|
|
|
struct symtab *result = NULL;
|
|
|
|
|
|
|
|
tmp = new_symtab_entry(var);
|
|
|
|
if (!tmp) {
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
lookup = (struct symtab **) tfind(tmp, &my_symtab, (comparison_fn_t) &compare_symtabs);
|
|
|
|
if (!lookup) {
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
result = (*lookup);
|
|
|
|
|
|
|
|
out:
|
|
|
|
free_symtab(tmp);
|
|
|
|
return result;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/* add_boolean_var
|
|
|
|
* creates copies of arguments, so caller can free them after use
|
|
|
|
*/
|
|
|
|
|
|
|
|
int add_boolean_var(const char *var, int value)
|
|
|
|
{
|
|
|
|
struct symtab *new, **result;
|
|
|
|
int rc = 0;
|
|
|
|
|
|
|
|
new = new_symtab_entry(var);
|
|
|
|
if (!new) {
|
|
|
|
rc = ENOMEM;
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
|
|
|
new->type = sd_boolean;
|
|
|
|
new->boolean = value;
|
|
|
|
|
|
|
|
result = (struct symtab **) tsearch(new, &my_symtab, (comparison_fn_t) &compare_symtabs);
|
|
|
|
if (!result) {
|
|
|
|
PERROR("Failed to allocate memory: %s\n", strerror(errno));
|
|
|
|
rc = errno;
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (*result != new) {
|
|
|
|
/* already existing variable */
|
|
|
|
PERROR("'%s' is already defined\n", var);
|
|
|
|
rc = 1;
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
err:
|
|
|
|
free_symtab(new);
|
|
|
|
return rc;
|
|
|
|
};
|
|
|
|
|
|
|
|
int get_boolean_var(const char *var)
|
|
|
|
{
|
|
|
|
struct symtab *result;
|
|
|
|
int rc = 0;
|
|
|
|
|
|
|
|
result = lookup_existing_symbol(var);
|
|
|
|
if (!result) {
|
|
|
|
rc = -1;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (result->type != sd_boolean) {
|
|
|
|
PERROR("Variable %s is not a boolean variable\n", var);
|
|
|
|
rc = -2; /* XXX - might change this to specific values */
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = result->boolean;
|
|
|
|
out:
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* new_set_var
|
|
|
|
* creates copies of arguments, so caller can free them after use
|
|
|
|
*/
|
|
|
|
int new_set_var(const char *var, const char *value)
|
|
|
|
{
|
|
|
|
struct symtab *new, **result;
|
|
|
|
int rc = 0;
|
|
|
|
|
|
|
|
new = new_symtab_entry(var);
|
|
|
|
if (!new) {
|
|
|
|
rc = ENOMEM;
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
|
|
|
new->type = sd_set;
|
|
|
|
add_to_set(&(new->values), value);
|
|
|
|
|
|
|
|
result = (struct symtab **) tsearch(new, &my_symtab, (comparison_fn_t) &compare_symtabs);
|
|
|
|
if (!result) {
|
|
|
|
PERROR("Failed to allocate memory: %s\n", strerror(errno));
|
|
|
|
rc = errno;
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (*result != new) {
|
|
|
|
/* already existing variable */
|
|
|
|
PERROR("'%s' is already defined\n", var);
|
|
|
|
rc = 1;
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
err:
|
|
|
|
free_symtab(new);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* add_set_value
|
|
|
|
* creates copies of arguments, so caller can free them after use
|
|
|
|
*/
|
|
|
|
int add_set_value(const char *var, const char *value)
|
|
|
|
{
|
|
|
|
struct symtab *result;
|
|
|
|
int rc = 0;
|
|
|
|
|
|
|
|
result = lookup_existing_symbol(var);
|
|
|
|
if (!result) {
|
|
|
|
PERROR("Failed to find declaration for: %s\n", var);
|
|
|
|
rc = 1;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (result->type != sd_set) {
|
|
|
|
PERROR("Variable %s is not a set variable\n", var);
|
|
|
|
rc = 2; /* XXX - might change this to specific values */
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (strcmp(result->var_name, var) != 0) {
|
|
|
|
PERROR("ASSERT: tfind found %s when looking up variable %s\n",
|
|
|
|
result->var_name, var);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
add_to_set(&(result->values), value);
|
|
|
|
|
|
|
|
out:
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* returns a pointer to the value list, which should be used as the
|
|
|
|
* argument to the get_next_set_value() function. */
|
2010-03-12 14:41:58 -08:00
|
|
|
struct set_value *get_set_var(const char *var)
|
2006-04-11 21:52:54 +00:00
|
|
|
{
|
|
|
|
struct symtab *result;
|
|
|
|
struct set_value *valuelist = NULL;
|
|
|
|
|
|
|
|
result = lookup_existing_symbol(var);
|
|
|
|
if (!result) {
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (result->type != sd_set) {
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (strcmp(result->var_name, var) != 0) {
|
|
|
|
PERROR("ASSERT: tfind found %s when looking up variable %s\n",
|
|
|
|
result->var_name, var);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!result->expanded) {
|
|
|
|
int err = __expand_variable(result);
|
|
|
|
if (err) {
|
|
|
|
PERROR("failure expanding variable %s\n", var);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
valuelist = result->expanded;
|
|
|
|
out:
|
|
|
|
return valuelist;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* iterator to walk the list of set values */
|
2010-03-12 14:41:58 -08:00
|
|
|
char *get_next_set_value(struct set_value **list)
|
2006-04-11 21:52:54 +00:00
|
|
|
{
|
2010-03-12 14:41:58 -08:00
|
|
|
struct set_value *next;
|
2006-04-11 21:52:54 +00:00
|
|
|
char *ret;
|
|
|
|
|
2010-03-12 14:41:58 -08:00
|
|
|
if (!list || !(*list))
|
2006-04-11 21:52:54 +00:00
|
|
|
return NULL;
|
|
|
|
|
2010-03-12 14:41:58 -08:00
|
|
|
ret = (*list)->val;
|
|
|
|
next = (*list)->next;
|
|
|
|
(*list) = next;
|
2006-04-11 21:52:54 +00:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *seenlist = NULL;
|
|
|
|
|
|
|
|
static int is_seen(const char *var)
|
|
|
|
{
|
|
|
|
char **lookup;
|
|
|
|
lookup = (char **) tfind(var, &seenlist, (comparison_fn_t) &strcmp);
|
|
|
|
return (lookup != NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void push_seen_var(const char *var)
|
|
|
|
{
|
|
|
|
char **lookup;
|
|
|
|
lookup = (char **) tsearch(var, &seenlist, (comparison_fn_t) &strcmp);
|
|
|
|
if (*lookup != var) {
|
|
|
|
PERROR("ASSERT: '%s' is already in the seenlist\n", var);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void pop_seen_var(const char *var)
|
|
|
|
{
|
|
|
|
char **lookup;
|
|
|
|
lookup = (char **) tdelete(var, &seenlist, (comparison_fn_t) &strcmp);
|
|
|
|
if (lookup == NULL) {
|
|
|
|
PERROR("ASSERT: popped var '%s' not found on the seenlist\n", var);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int __expand_variable(struct symtab *symbol)
|
|
|
|
{
|
|
|
|
struct set_value *list, *expanded = NULL;
|
|
|
|
int retval = 0;
|
|
|
|
struct var_string *split = NULL;
|
|
|
|
|
|
|
|
if (symbol->type == sd_boolean) {
|
|
|
|
PERROR("Referenced variable %s is a boolean used in set context\n",
|
|
|
|
symbol->var_name);
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* already done */
|
|
|
|
if (symbol->expanded)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
push_seen_var(symbol->var_name);
|
|
|
|
|
|
|
|
for (list = symbol->values; list; list = list->next) {
|
|
|
|
struct set_value *work_list = new_set_value(list->val);
|
|
|
|
while (work_list) {
|
|
|
|
struct symtab *ref;
|
|
|
|
struct set_value *ref_item;
|
|
|
|
struct set_value *this_value = work_list;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
work_list = work_list->next;
|
|
|
|
|
|
|
|
split = split_out_var(this_value->val);
|
|
|
|
if (!split) {
|
|
|
|
/* fully expanded */
|
|
|
|
add_to_set(&expanded, this_value->val);
|
|
|
|
goto next;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (is_seen(split->var)) {
|
|
|
|
PERROR("Variable @{%s} is referenced recursively (by @{%s})\n",
|
|
|
|
split->var, symbol->var_name);
|
|
|
|
retval = 1;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
ref = lookup_existing_symbol(split->var);
|
|
|
|
if (!ref) {
|
|
|
|
PERROR("Variable @{%s} references undefined variable @{%s}\n",
|
|
|
|
symbol->var_name, split->var);
|
|
|
|
retval = 3;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = __expand_variable(ref);
|
|
|
|
if (rc != 0) {
|
|
|
|
retval = rc;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!ref->expanded) {
|
|
|
|
PERROR("ASSERT: Variable @{%s} should have been expanded but isn't\n",
|
|
|
|
split->var);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (ref_item = ref->expanded; ref_item; ref_item = ref_item->next) {
|
|
|
|
char *expanded_string;
|
2010-07-26 09:22:45 -07:00
|
|
|
if (!asprintf(&expanded_string, "%s%s%s",
|
2006-04-11 21:52:54 +00:00
|
|
|
split->prefix ? split->prefix : "",
|
|
|
|
ref_item->val,
|
2010-07-26 09:22:45 -07:00
|
|
|
split->suffix ? split->suffix : "")) {
|
|
|
|
PERROR("Out of memory\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
2006-04-11 21:52:54 +00:00
|
|
|
add_to_set(&work_list, expanded_string);
|
|
|
|
free(expanded_string);
|
|
|
|
}
|
|
|
|
|
|
|
|
next:
|
|
|
|
this_value->next = NULL;
|
|
|
|
free_values(this_value);
|
|
|
|
free_var_string(split);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
symbol->expanded = expanded;
|
|
|
|
pop_seen_var(symbol->var_name);
|
|
|
|
out:
|
|
|
|
free_var_string(split);
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void expand_variable(const void *nodep, VISIT value, int __unused level)
|
|
|
|
{
|
|
|
|
struct symtab **t = (struct symtab **) nodep;
|
|
|
|
|
|
|
|
if (value == preorder || value == endorder)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if ((*t)->type == sd_boolean)
|
|
|
|
return;
|
|
|
|
|
|
|
|
__expand_variable(*t);
|
|
|
|
}
|
|
|
|
|
|
|
|
void expand_variables(void)
|
|
|
|
{
|
|
|
|
twalk(my_symtab, &expand_variable);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void dump_set_values(struct set_value *value)
|
|
|
|
{
|
|
|
|
struct set_value *this = value;
|
|
|
|
while (this) {
|
|
|
|
printf(" \"%s\"", this->val);
|
|
|
|
this = this->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void __dump_symtab_entry(struct symtab *entry, int do_expanded)
|
|
|
|
{
|
|
|
|
switch (entry->type) {
|
|
|
|
case sd_boolean:
|
|
|
|
printf("$%s = %s\n", entry->var_name,
|
|
|
|
entry->boolean ? "true" : "false");
|
|
|
|
break;
|
|
|
|
case sd_set:
|
|
|
|
printf("@%s =", entry->var_name);
|
|
|
|
if (do_expanded) {
|
|
|
|
if (!entry->expanded) {
|
|
|
|
__expand_variable(entry);
|
|
|
|
}
|
|
|
|
dump_set_values(entry->expanded);
|
|
|
|
} else {
|
|
|
|
dump_set_values(entry->values);
|
|
|
|
}
|
|
|
|
printf("\n");
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
PERROR("ASSERT: unknown symbol table type for %s\n", entry->var_name);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void dump_symtab_entry(const void *nodep, VISIT value, int __unused level)
|
|
|
|
{
|
|
|
|
struct symtab **t = (struct symtab **) nodep;
|
|
|
|
|
|
|
|
if (value == preorder || value == endorder)
|
|
|
|
return;
|
|
|
|
|
|
|
|
__dump_symtab_entry(*t, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void dump_expanded_symtab_entry(const void *nodep, VISIT value, int __unused level)
|
|
|
|
{
|
|
|
|
struct symtab **t = (struct symtab **) nodep;
|
|
|
|
|
|
|
|
if (value == preorder || value == endorder)
|
|
|
|
return;
|
|
|
|
|
|
|
|
__dump_symtab_entry(*t, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
void dump_symtab(void)
|
|
|
|
{
|
|
|
|
twalk(my_symtab, &dump_symtab_entry);
|
|
|
|
}
|
|
|
|
|
|
|
|
void dump_expanded_symtab(void)
|
|
|
|
{
|
|
|
|
twalk(my_symtab, &dump_expanded_symtab_entry);
|
|
|
|
}
|
|
|
|
|
2009-07-24 07:34:11 +00:00
|
|
|
void free_symtabs(void)
|
|
|
|
{
|
|
|
|
if (my_symtab)
|
|
|
|
tdestroy(my_symtab, (__free_fn_t)&free_symtab);
|
|
|
|
my_symtab = NULL;
|
|
|
|
}
|
|
|
|
|
2006-04-11 21:52:54 +00:00
|
|
|
#ifdef UNIT_TEST
|
|
|
|
int main(void)
|
|
|
|
{
|
|
|
|
int rc = 0;
|
|
|
|
int retval;
|
2010-03-12 14:41:58 -08:00
|
|
|
struct set_value *retptr;
|
2006-04-11 21:52:54 +00:00
|
|
|
struct symtab *a, *b;
|
|
|
|
|
|
|
|
a = new_symtab_entry("blah");
|
|
|
|
b = new_symtab_entry("suck");
|
|
|
|
MY_TEST(a && b, "allocation test");
|
|
|
|
|
|
|
|
retval = compare_symtabs(a, b);
|
|
|
|
MY_TEST(retval < 0, "comparison 1");
|
|
|
|
|
|
|
|
retval = compare_symtabs(b, a);
|
|
|
|
MY_TEST(retval > 0, "comparison 2");
|
|
|
|
|
|
|
|
retval = compare_symtabs(b, a);
|
|
|
|
MY_TEST(retval != 0, "comparison 3");
|
|
|
|
|
|
|
|
retval = new_set_var("test", "test value");
|
|
|
|
MY_TEST(retval == 0, "new set variable 1");
|
|
|
|
|
|
|
|
retval = new_set_var("test", "different value");
|
|
|
|
MY_TEST(retval != 0, "new set variable 2");
|
|
|
|
|
[v2: added clean-ups, backed off on some of the build silencing]
This is a rather large rearrangement of how a subset of the parser global
variables are defined. Right now, there are unit tests built without
linking against parser_main.c. As a result, none of the globals defined in
parser_main.c could be used in the code that is built for unit tests
(misc, regex, symtab, variable). To get a clean build, either stubs needed
to be added to "#ifdef UNIT_TEST" blocks in each .c file, or we had to
depend on link-time optimizations that would throw out the unused routines.
First, this is a problem because all the compile-time warnings had to be
explicitly silenced, so reviewing the build logs becomes difficult on
failures, and we can potentially (in really unlucky situations) test
something that isn't actually part of the "real" parser.
Second, not all compilers will allow this kind of linking (e.g. mips gcc),
and the missing symbols at link time will fail the entire build even though
they're technically not needed.
To solve all of this, I've moved all of the global variables used in lex,
yacc, and main to parser_common.c, and adjusted the .h files. On top of
this, I made sure to fully link the tst builds so all symbols are resolved
(including aare lib) and removedonly tst build-log silencing (for now,
deferring to another future patchset to consolidate the build silencing).
Signed-off-by: Kees Cook <kees.cook@canonical.com>
2011-05-13 02:12:49 -07:00
|
|
|
retval = new_set_var("testing", "testing");
|
2006-04-11 21:52:54 +00:00
|
|
|
MY_TEST(retval == 0, "new set variable 3");
|
|
|
|
|
|
|
|
retval = new_set_var("monopuff", "Mockingbird");
|
|
|
|
MY_TEST(retval == 0, "new set variable 4");
|
|
|
|
|
|
|
|
retval = new_set_var("stereopuff", "Unsupervised");
|
|
|
|
MY_TEST(retval == 0, "new set variable 5");
|
|
|
|
|
|
|
|
retval = add_set_value("stereopuff", "Fun to Steal");
|
|
|
|
MY_TEST(retval == 0, "add set value 1");
|
|
|
|
|
|
|
|
retval = add_set_value("stereopuff", "/in/direction");
|
|
|
|
MY_TEST(retval == 0, "add set value 2");
|
|
|
|
|
|
|
|
retval = add_set_value("no_such_variable", "stereopuff");
|
|
|
|
MY_TEST(retval != 0, "add to non-existent set var");
|
|
|
|
|
|
|
|
retval = add_boolean_var("abuse", 0);
|
|
|
|
MY_TEST(retval == 0, "new boolean variable 1");
|
|
|
|
|
|
|
|
retval = add_boolean_var("abuse", 1);
|
|
|
|
MY_TEST(retval != 0, "duplicate boolean variable 1");
|
|
|
|
|
|
|
|
retval = add_boolean_var("stereopuff", 1);
|
|
|
|
MY_TEST(retval != 0, "duplicate boolean variable 2");
|
|
|
|
|
|
|
|
retval = add_boolean_var("shenanigan", 1);
|
|
|
|
MY_TEST(retval == 0, "new boolean variable 2");
|
|
|
|
|
|
|
|
retval = get_boolean_var("shenanigan");
|
|
|
|
MY_TEST(retval == 1, "get boolean variable 1");
|
|
|
|
|
|
|
|
retval = get_boolean_var("abuse");
|
|
|
|
MY_TEST(retval == 0, "get boolean variable 2");
|
|
|
|
|
|
|
|
retval = get_boolean_var("non_existant");
|
|
|
|
MY_TEST(retval < 0, "get nonexistant boolean variable");
|
|
|
|
|
|
|
|
retval = get_boolean_var("stereopuff");
|
|
|
|
MY_TEST(retval < 0, "get boolean variable that's declared a set var");
|
|
|
|
|
|
|
|
retptr = get_set_var("daves_not_here_man");
|
|
|
|
MY_TEST(retptr == NULL, "get non-existent set variable");
|
|
|
|
|
|
|
|
retptr = get_set_var("abuse");
|
|
|
|
MY_TEST(retptr == NULL, "get set variable that's declared a boolean");
|
|
|
|
|
|
|
|
retptr = get_set_var("monopuff");
|
|
|
|
MY_TEST(retptr != NULL, "get set variable 1");
|
|
|
|
|
|
|
|
retval = strcmp(get_next_set_value(&retptr), "Mockingbird");
|
|
|
|
MY_TEST(retval == 0, "get set value 1");
|
|
|
|
|
|
|
|
MY_TEST(get_next_set_value(&retptr) == NULL, "get no more set values 1");
|
|
|
|
|
|
|
|
MY_TEST(!is_seen("oogabooga"), "lookup unseen variable");
|
|
|
|
|
|
|
|
push_seen_var("oogabooga");
|
|
|
|
MY_TEST(is_seen("oogabooga"), "lookup seen variable 1");
|
|
|
|
MY_TEST(!is_seen("not_seen"), "lookup unseen variable 2");
|
|
|
|
|
|
|
|
push_seen_var("heebiejeebie");
|
|
|
|
MY_TEST(is_seen("oogabooga"), "lookup seen variable 2");
|
|
|
|
MY_TEST(is_seen("heebiejeebie"), "lookup seen variable 3");
|
|
|
|
MY_TEST(!is_seen("not_seen"), "lookup unseen variable 3");
|
|
|
|
|
|
|
|
pop_seen_var("oogabooga");
|
|
|
|
MY_TEST(!is_seen("oogabooga"), "lookup unseen variable 4");
|
|
|
|
MY_TEST(is_seen("heebiejeebie"), "lookup seen variable 4");
|
|
|
|
MY_TEST(!is_seen("not_seen"), "lookup unseen variable 5");
|
|
|
|
|
|
|
|
pop_seen_var("heebiejeebie");
|
|
|
|
MY_TEST(!is_seen("heebiejeebie"), "lookup unseen variable 6");
|
|
|
|
|
|
|
|
//pop_seen_var("not_seen"); /* triggers assert */
|
|
|
|
|
|
|
|
retval = new_set_var("eek", "Mocking@{monopuff}bir@{stereopuff}d@{stereopuff}");
|
|
|
|
MY_TEST(retval == 0, "new set variable 4");
|
|
|
|
|
|
|
|
dump_symtab();
|
|
|
|
expand_variables();
|
|
|
|
dump_symtab();
|
|
|
|
dump_expanded_symtab();
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
#endif /* UNIT_TEST */
|