902 lines
20 KiB
Plaintext
902 lines
20 KiB
Plaintext
/* $OpenBSD: keynote.y,v 1.19 2022/12/27 17:10:06 jmc Exp $ */
|
|
/*
|
|
* The author of this code is Angelos D. Keromytis (angelos@dsl.cis.upenn.edu)
|
|
*
|
|
* This code was written by Angelos D. Keromytis in Philadelphia, PA, USA,
|
|
* in April-May 1998
|
|
*
|
|
* Copyright (C) 1998, 1999 by Angelos D. Keromytis.
|
|
*
|
|
* Permission to use, copy, and modify this software with or without fee
|
|
* is hereby granted, provided that this entire notice is included in
|
|
* all copies of any software which is or includes a copy or
|
|
* modification of this software.
|
|
*
|
|
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
|
|
* IMPLIED WARRANTY. IN PARTICULAR, THE AUTHORS MAKES NO
|
|
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
|
|
* MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
|
|
* PURPOSE.
|
|
*/
|
|
%union {
|
|
char *string;
|
|
double doubval;
|
|
int intval;
|
|
int bool;
|
|
};
|
|
%type <bool> stringexp numexp expr floatexp
|
|
%type <intval> NUM KOF numex afterhint notemptyprog
|
|
%type <intval> notemptykeypredicate prog key keyexp keylist
|
|
%type <doubval> FLOAT floatex
|
|
%type <string> STRING VARIABLE str strnotconcat
|
|
%token TRUE FALSE NUM FLOAT STRING VARIABLE
|
|
%token OPENPAREN CLOSEPAREN EQQ COMMA ACTSTR LOCINI KOF KEYPRE KNVERSION
|
|
%token DOTT SIGNERKEY HINT OPENBLOCK CLOSEBLOCK SIGNATUREENTRY PRIVATEKEY
|
|
%token SEMICOLON TRUE FALSE
|
|
%nonassoc EQ NE LT GT LE GE REGEXP
|
|
%left OR
|
|
%left AND
|
|
%right NOT
|
|
%left PLUS MINUS DOTT
|
|
%left MULT DIV MOD
|
|
%left EXP
|
|
%nonassoc UNARYMINUS DEREF OPENNUM OPENFLT
|
|
%start grammarswitch
|
|
%{
|
|
#include <sys/types.h>
|
|
|
|
#include <ctype.h>
|
|
#include <math.h>
|
|
#include <regex.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "keynote.h"
|
|
#include "assertion.h"
|
|
|
|
static int *keynote_kth_array = NULL;
|
|
static int keylistcount = 0;
|
|
|
|
static int resolve_assertion(char *);
|
|
static int keynote_init_kth(void);
|
|
static int isfloatstring(char *);
|
|
static int checkexception(int);
|
|
static char *my_lookup(char *);
|
|
static int intpow(int, int);
|
|
static int get_kth(int);
|
|
%}
|
|
%%
|
|
|
|
grammarswitch: LOCINI { keynote_exceptionflag = keynote_donteval = 0; }
|
|
localinit
|
|
| ACTSTR { keynote_exceptionflag = keynote_donteval = 0; } program
|
|
| KEYPRE { keynote_exceptionflag = keynote_donteval = 0; }
|
|
keypredicate
|
|
| SIGNERKEY { keynote_exceptionflag = keynote_donteval = 0; } key
|
|
| SIGNATUREENTRY { keynote_exceptionflag = keynote_donteval = 0; }
|
|
key
|
|
| KNVERSION { keynote_exceptionflag = keynote_donteval = 0; }
|
|
STRING { keynote_lex_remove($3);
|
|
if (strcmp($3, KEYNOTE_VERSION_STRING))
|
|
keynote_errno = ERROR_SYNTAX;
|
|
free($3);
|
|
}
|
|
| PRIVATEKEY { keynote_exceptionflag = keynote_donteval = 0; }
|
|
STRING { keynote_lex_remove($3);
|
|
keynote_privkey = $3;
|
|
}
|
|
|
|
keypredicate: /* Nothing */ { keynote_returnvalue = 0;
|
|
return 0;
|
|
}
|
|
| notemptykeypredicate { keynote_returnvalue = $1;
|
|
return 0;
|
|
}
|
|
|
|
notemptykeypredicate: key { $$ = $1; }
|
|
| keyexp { $$ = $1; }
|
|
|
|
keyexp: notemptykeypredicate AND { if (($1 == 0) && !keynote_justrecord)
|
|
keynote_donteval = 1;
|
|
} notemptykeypredicate
|
|
{ if ($1 > $4)
|
|
$$ = $4;
|
|
else
|
|
$$ = $1;
|
|
keynote_donteval = 0;
|
|
} /* Min */
|
|
| notemptykeypredicate OR { if (($1 == (keynote_current_session->ks_values_num - 1)) && !keynote_justrecord)
|
|
keynote_donteval = 1;
|
|
} notemptykeypredicate
|
|
{ if ($1 >= $4)
|
|
$$ = $1;
|
|
else
|
|
$$ = $4;
|
|
keynote_donteval = 0;
|
|
} /* Max */
|
|
| OPENPAREN keyexp CLOSEPAREN { $$ = $2; }
|
|
| KOF { keylistcount = 0; } OPENPAREN {
|
|
if (!keynote_justrecord && !keynote_donteval)
|
|
if (keynote_init_kth() == -1)
|
|
return -1;
|
|
} keylist CLOSEPAREN
|
|
{
|
|
if (keylistcount < $1)
|
|
{
|
|
keynote_errno = ERROR_SYNTAX;
|
|
return -1;
|
|
}
|
|
|
|
if (!keynote_justrecord && !keynote_donteval)
|
|
$$ = get_kth($1);
|
|
else
|
|
$$ = 0;
|
|
} /* K-th */
|
|
|
|
keylist: key
|
|
{ /* Don't do anything if we're just recording */
|
|
if (!keynote_justrecord && !keynote_donteval)
|
|
if (($1 < keynote_current_session->ks_values_num) && ($1 >= 0))
|
|
keynote_kth_array[$1]++;
|
|
|
|
keylistcount++;
|
|
}
|
|
| key COMMA keylist
|
|
{ /* Don't do anything if we're just recording */
|
|
if (!keynote_justrecord && !keynote_donteval)
|
|
if (($1 < keynote_current_session->ks_values_num) && ($1 >= 0))
|
|
keynote_kth_array[$1]++;
|
|
|
|
keylistcount++;
|
|
}
|
|
|
|
key: str {
|
|
if (keynote_donteval)
|
|
$$ = 0;
|
|
else
|
|
{
|
|
keynote_lex_remove($1);
|
|
if (keynote_justrecord)
|
|
{
|
|
if (keynote_keylist_add(&keynote_keypred_keylist,
|
|
$1) == -1)
|
|
{
|
|
free($1);
|
|
return -1;
|
|
}
|
|
|
|
$$ = 0;
|
|
}
|
|
else
|
|
switch (keynote_in_action_authorizers($1, KEYNOTE_ALGORITHM_UNSPEC))
|
|
{
|
|
case -1:
|
|
free($1);
|
|
return -1;
|
|
|
|
case RESULT_TRUE:
|
|
free($1);
|
|
$$ = keynote_current_session->ks_values_num -
|
|
1;
|
|
break;
|
|
|
|
default:
|
|
$$ = resolve_assertion($1);
|
|
free($1);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
localinit: /* Nothing */
|
|
| localconstants
|
|
|
|
localconstants: VARIABLE EQQ STRING
|
|
{
|
|
int i;
|
|
|
|
keynote_lex_remove($1);
|
|
keynote_lex_remove($3);
|
|
|
|
/*
|
|
* Variable names starting with underscores are illegal here.
|
|
*/
|
|
if ($1[0] == '_')
|
|
{
|
|
free($1);
|
|
free($3);
|
|
keynote_errno = ERROR_SYNTAX;
|
|
return -1;
|
|
}
|
|
|
|
/* If the identifier already exists, report error. */
|
|
if (keynote_env_lookup($1, &keynote_init_list, 1) != NULL)
|
|
{
|
|
free($1);
|
|
free($3);
|
|
keynote_errno = ERROR_SYNTAX;
|
|
return -1;
|
|
}
|
|
|
|
i = keynote_env_add($1, $3, &keynote_init_list, 1, 0);
|
|
free($1);
|
|
free($3);
|
|
|
|
if (i != RESULT_TRUE)
|
|
return -1;
|
|
}
|
|
| VARIABLE EQQ STRING
|
|
{
|
|
int i;
|
|
|
|
keynote_lex_remove($1);
|
|
keynote_lex_remove($3);
|
|
|
|
/*
|
|
* Variable names starting with underscores are illegal here.
|
|
*/
|
|
if ($1[0] == '_')
|
|
{
|
|
free($1);
|
|
free($3);
|
|
keynote_errno = ERROR_SYNTAX;
|
|
return -1;
|
|
}
|
|
|
|
/* If the identifier already exists, report error. */
|
|
if (keynote_env_lookup($1, &keynote_init_list, 1) != NULL)
|
|
{
|
|
free($1);
|
|
free($3);
|
|
keynote_errno = ERROR_SYNTAX;
|
|
return -1;
|
|
}
|
|
|
|
i = keynote_env_add($1, $3, &keynote_init_list, 1, 0);
|
|
free($1);
|
|
free($3);
|
|
|
|
if (i != RESULT_TRUE)
|
|
return -1;
|
|
} localconstants
|
|
|
|
program: prog {
|
|
keynote_returnvalue = $1;
|
|
return 0;
|
|
}
|
|
|
|
prog: /* Nada */ { $$ = 0; }
|
|
| notemptyprog {
|
|
/*
|
|
* Cleanup envlist of additions such as
|
|
* regexp results
|
|
*/
|
|
keynote_env_cleanup(&keynote_temp_list, 1);
|
|
} SEMICOLON prog
|
|
{
|
|
if ($1 > $4)
|
|
$$ = $1;
|
|
else
|
|
$$ = $4;
|
|
}
|
|
|
|
notemptyprog: expr HINT afterhint
|
|
{
|
|
if (checkexception($1))
|
|
$$ = $3;
|
|
else
|
|
$$ = 0;
|
|
}
|
|
| expr
|
|
{
|
|
if (checkexception($1))
|
|
$$ = keynote_current_session->ks_values_num - 1;
|
|
else
|
|
$$ = 0;
|
|
}
|
|
|
|
afterhint: str { if (keynote_exceptionflag || keynote_donteval)
|
|
$$ = 0;
|
|
else
|
|
{
|
|
keynote_lex_remove($1);
|
|
|
|
$$ = keynote_retindex($1);
|
|
if ($$ == -1) /* Invalid return value */
|
|
$$ = 0;
|
|
|
|
free($1);
|
|
}
|
|
}
|
|
| OPENBLOCK prog CLOSEBLOCK { $$ = $2; }
|
|
|
|
|
|
expr: OPENPAREN expr CLOSEPAREN { $$ = $2; }
|
|
| expr AND { if ($1 == 0)
|
|
keynote_donteval = 1;
|
|
} expr { $$ = ($1 && $4);
|
|
keynote_donteval = 0;
|
|
}
|
|
| expr OR { if ($1)
|
|
keynote_donteval = 1;
|
|
} expr { $$ = ($1 || $4);
|
|
keynote_donteval = 0;
|
|
}
|
|
| NOT expr { $$ = !($2); }
|
|
| numexp { $$ = $1; }
|
|
| floatexp { $$ = $1; }
|
|
| stringexp { $$ = $1; }
|
|
| TRUE { $$ = 1; }
|
|
| FALSE { $$ = 0; }
|
|
|
|
numexp: numex LT numex { $$ = $1 < $3; }
|
|
| numex GT numex { $$ = $1 > $3; }
|
|
| numex EQ numex { $$ = $1 == $3; }
|
|
| numex LE numex { $$ = $1 <= $3; }
|
|
| numex GE numex { $$ = $1 >= $3; }
|
|
| numex NE numex { $$ = $1 != $3; }
|
|
|
|
floatexp: floatex LT floatex { $$ = $1 < $3; }
|
|
| floatex GT floatex { $$ = $1 > $3; }
|
|
| floatex LE floatex { $$ = $1 <= $3; }
|
|
| floatex GE floatex { $$ = $1 >= $3; }
|
|
|
|
numex: numex PLUS numex { $$ = $1 + $3; }
|
|
| numex MINUS numex { $$ = $1 - $3; }
|
|
| numex MULT numex { $$ = $1 * $3; }
|
|
| numex DIV numex { if ($3 == 0)
|
|
{
|
|
if (!keynote_donteval)
|
|
keynote_exceptionflag = 1;
|
|
}
|
|
else
|
|
$$ = ($1 / $3);
|
|
}
|
|
| numex MOD numex { if ($3 == 0)
|
|
{
|
|
if (!keynote_donteval)
|
|
keynote_exceptionflag = 1;
|
|
}
|
|
else
|
|
$$ = $1 % $3;
|
|
}
|
|
| numex EXP numex { $$ = intpow($1, $3); }
|
|
| MINUS numex %prec UNARYMINUS { $$ = -($2); }
|
|
| OPENPAREN numex CLOSEPAREN { $$ = $2; }
|
|
| NUM { $$ = $1; }
|
|
| OPENNUM strnotconcat { if (keynote_exceptionflag ||
|
|
keynote_donteval)
|
|
$$ = 0;
|
|
else
|
|
{
|
|
keynote_lex_remove($2);
|
|
|
|
if (!isfloatstring($2))
|
|
$$ = 0;
|
|
else
|
|
$$ = (int) floor(atof($2));
|
|
free($2);
|
|
}
|
|
}
|
|
|
|
floatex: floatex PLUS floatex { $$ = ($1 + $3); }
|
|
| floatex MINUS floatex { $$ = ($1 - $3); }
|
|
| floatex MULT floatex { $$ = ($1 * $3); }
|
|
| floatex DIV floatex { if ($3 == 0)
|
|
{
|
|
if (!keynote_donteval)
|
|
keynote_exceptionflag = 1;
|
|
}
|
|
else
|
|
$$ = ($1 / $3);
|
|
}
|
|
| floatex EXP floatex { if (!keynote_exceptionflag &&
|
|
!keynote_donteval)
|
|
$$ = pow($1, $3);
|
|
}
|
|
| MINUS floatex %prec UNARYMINUS { $$ = -($2); }
|
|
| OPENPAREN floatex CLOSEPAREN { $$ = $2; }
|
|
| FLOAT { $$ = $1; }
|
|
| OPENFLT strnotconcat {
|
|
if (keynote_exceptionflag ||
|
|
keynote_donteval)
|
|
$$ = 0.0;
|
|
else
|
|
{
|
|
keynote_lex_remove($2);
|
|
|
|
if (!isfloatstring($2))
|
|
$$ = 0.0;
|
|
else
|
|
$$ = atof($2);
|
|
free($2);
|
|
}
|
|
}
|
|
|
|
stringexp: str EQ str {
|
|
if (keynote_exceptionflag || keynote_donteval)
|
|
$$ = 0;
|
|
else
|
|
{
|
|
$$ = strcmp($1, $3) == 0 ? 1 : 0;
|
|
keynote_lex_remove($1);
|
|
keynote_lex_remove($3);
|
|
free($1);
|
|
free($3);
|
|
}
|
|
}
|
|
| str NE str {
|
|
if (keynote_exceptionflag || keynote_donteval)
|
|
$$ = 0;
|
|
else
|
|
{
|
|
$$ = strcmp($1, $3) != 0 ? 1 : 0;
|
|
keynote_lex_remove($1);
|
|
keynote_lex_remove($3);
|
|
free($1);
|
|
free($3);
|
|
}
|
|
}
|
|
| str LT str {
|
|
if (keynote_exceptionflag || keynote_donteval)
|
|
$$ = 0;
|
|
else
|
|
{
|
|
$$ = strcmp($1, $3) < 0 ? 1 : 0;
|
|
keynote_lex_remove($1);
|
|
keynote_lex_remove($3);
|
|
free($1);
|
|
free($3);
|
|
}
|
|
}
|
|
| str GT str {
|
|
if (keynote_exceptionflag || keynote_donteval)
|
|
$$ = 0;
|
|
else
|
|
{
|
|
$$ = strcmp($1, $3) > 0 ? 1 : 0;
|
|
keynote_lex_remove($1);
|
|
keynote_lex_remove($3);
|
|
free($1);
|
|
free($3);
|
|
}
|
|
}
|
|
| str LE str {
|
|
if (keynote_exceptionflag || keynote_donteval)
|
|
$$ = 0;
|
|
else
|
|
{
|
|
$$ = strcmp($1, $3) <= 0 ? 1 : 0;
|
|
keynote_lex_remove($1);
|
|
keynote_lex_remove($3);
|
|
free($1);
|
|
free($3);
|
|
}
|
|
}
|
|
| str GE str {
|
|
if (keynote_exceptionflag || keynote_donteval)
|
|
$$ = 0;
|
|
else
|
|
{
|
|
$$ = strcmp($1, $3) >= 0 ? 1 : 0;
|
|
keynote_lex_remove($1);
|
|
keynote_lex_remove($3);
|
|
free($1);
|
|
free($3);
|
|
}
|
|
}
|
|
| str REGEXP str
|
|
{
|
|
regmatch_t pmatch[32];
|
|
char grp[10], *gr;
|
|
regex_t preg;
|
|
int i;
|
|
|
|
if (keynote_exceptionflag || keynote_donteval)
|
|
$$ = 0;
|
|
else
|
|
{
|
|
keynote_lex_remove($1);
|
|
keynote_lex_remove($3);
|
|
|
|
memset(pmatch, 0, sizeof(pmatch));
|
|
memset(grp, 0, sizeof(grp));
|
|
|
|
if (regcomp(&preg, $3, REG_EXTENDED))
|
|
{
|
|
free($1);
|
|
free($3);
|
|
keynote_exceptionflag = 1;
|
|
}
|
|
else
|
|
{
|
|
/* Clean-up residuals from previous regexps */
|
|
keynote_env_cleanup(&keynote_temp_list, 1);
|
|
|
|
free($3);
|
|
i = regexec(&preg, $1, 32, pmatch, 0);
|
|
$$ = (i == 0 ? 1 : 0);
|
|
if (i == 0)
|
|
{
|
|
snprintf(grp, sizeof grp, "%lu",
|
|
(unsigned long)preg.re_nsub);
|
|
if (keynote_env_add("_0", grp, &keynote_temp_list,
|
|
1, 0) != RESULT_TRUE)
|
|
{
|
|
free($1);
|
|
regfree(&preg);
|
|
return -1;
|
|
}
|
|
|
|
for (i = 1; i < 32 && pmatch[i].rm_so != -1; i++)
|
|
{
|
|
gr = calloc(pmatch[i].rm_eo - pmatch[i].rm_so +
|
|
1, sizeof(char));
|
|
if (gr == NULL)
|
|
{
|
|
free($1);
|
|
regfree(&preg);
|
|
keynote_errno = ERROR_MEMORY;
|
|
return -1;
|
|
}
|
|
|
|
strncpy(gr, $1 + pmatch[i].rm_so,
|
|
pmatch[i].rm_eo - pmatch[i].rm_so);
|
|
gr[pmatch[i].rm_eo - pmatch[i].rm_so] = '\0';
|
|
snprintf(grp, sizeof grp, "_%d", i);
|
|
if (keynote_env_add(grp, gr, &keynote_temp_list,
|
|
1, 0) == -1)
|
|
{
|
|
free($1);
|
|
regfree(&preg);
|
|
free(gr);
|
|
return -1;
|
|
}
|
|
else
|
|
free(gr);
|
|
}
|
|
}
|
|
|
|
regfree(&preg);
|
|
free($1);
|
|
}
|
|
}
|
|
}
|
|
|
|
str: str DOTT str { if (keynote_exceptionflag || keynote_donteval)
|
|
$$ = NULL;
|
|
else
|
|
{
|
|
int len = strlen($1) + strlen($3) + 1;
|
|
$$ = calloc(len, sizeof(char));
|
|
keynote_lex_remove($1);
|
|
keynote_lex_remove($3);
|
|
if ($$ == NULL)
|
|
{
|
|
free($1);
|
|
free($3);
|
|
keynote_errno = ERROR_MEMORY;
|
|
return -1;
|
|
}
|
|
snprintf($$, len, "%s%s", $1, $3);
|
|
free($1);
|
|
free($3);
|
|
if (keynote_lex_add($$, LEXTYPE_CHAR) == -1)
|
|
return -1;
|
|
}
|
|
}
|
|
| strnotconcat { $$ = $1; }
|
|
|
|
strnotconcat: STRING { $$ = $1; }
|
|
| OPENPAREN str CLOSEPAREN { $$ = $2; }
|
|
| VARIABLE { if (keynote_exceptionflag || keynote_donteval)
|
|
$$ = NULL;
|
|
else
|
|
{
|
|
$$ = my_lookup($1);
|
|
keynote_lex_remove($1);
|
|
free($1);
|
|
if ($$ == NULL)
|
|
{
|
|
if (keynote_errno)
|
|
return -1;
|
|
$$ = strdup("");
|
|
}
|
|
else
|
|
$$ = strdup($$);
|
|
|
|
if ($$ == NULL)
|
|
{
|
|
keynote_errno = ERROR_MEMORY;
|
|
return -1;
|
|
}
|
|
|
|
if (keynote_lex_add($$, LEXTYPE_CHAR) == -1)
|
|
return -1;
|
|
}
|
|
}
|
|
| DEREF str { if (keynote_exceptionflag || keynote_donteval)
|
|
$$ = NULL;
|
|
else
|
|
{
|
|
$$ = my_lookup($2);
|
|
keynote_lex_remove($2);
|
|
free($2);
|
|
if ($$ == NULL)
|
|
{
|
|
if (keynote_errno)
|
|
return -1;
|
|
$$ = strdup("");
|
|
}
|
|
else
|
|
$$ = strdup($$);
|
|
|
|
if ($$ == NULL)
|
|
{
|
|
keynote_errno = ERROR_MEMORY;
|
|
return -1;
|
|
}
|
|
|
|
if (keynote_lex_add($$, LEXTYPE_CHAR) == -1)
|
|
return -1;
|
|
}
|
|
}
|
|
%%
|
|
|
|
/*
|
|
* Find all assertions signed by s and give us the one with the highest
|
|
* return value.
|
|
*/
|
|
static int
|
|
resolve_assertion(char *s)
|
|
{
|
|
int i, alg = KEYNOTE_ALGORITHM_NONE, p = 0;
|
|
void *key = (void *) s;
|
|
struct assertion *as;
|
|
struct keylist *kl;
|
|
|
|
kl = keynote_keylist_find(keynote_current_assertion->as_keylist, s);
|
|
if (kl != NULL)
|
|
{
|
|
alg = kl->key_alg;
|
|
key = kl->key_key;
|
|
}
|
|
|
|
for (i = 0;; i++)
|
|
{
|
|
as = keynote_find_assertion(key, i, alg);
|
|
if (as == NULL) /* Gone through all of them */
|
|
return p;
|
|
|
|
if (as->as_kresult == KRESULT_DONE)
|
|
if (p < as->as_result)
|
|
p = as->as_result;
|
|
|
|
/* Short circuit if we find an assertion with maximum return value */
|
|
if (p == (keynote_current_session->ks_values_num - 1))
|
|
return p;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* Environment variable lookup.
|
|
*/
|
|
static char *
|
|
my_lookup(char *s)
|
|
{
|
|
struct keynote_session *ks = keynote_current_session;
|
|
char *ret;
|
|
|
|
if (!strcmp(s, "_MIN_TRUST"))
|
|
{
|
|
keynote_used_variable = 1;
|
|
return ks->ks_values[0];
|
|
}
|
|
else
|
|
{
|
|
if (!strcmp(s, "_MAX_TRUST"))
|
|
{
|
|
keynote_used_variable = 1;
|
|
return ks->ks_values[ks->ks_values_num - 1];
|
|
}
|
|
else
|
|
{
|
|
if (!strcmp(s, "_VALUES"))
|
|
{
|
|
keynote_used_variable = 1;
|
|
return keynote_env_lookup("_VALUES", ks->ks_env_table,
|
|
HASHTABLESIZE);
|
|
}
|
|
else
|
|
{
|
|
if (!strcmp(s, "_ACTION_AUTHORIZERS"))
|
|
{
|
|
keynote_used_variable = 1;
|
|
return keynote_env_lookup("_ACTION_AUTHORIZERS",
|
|
ks->ks_env_table, HASHTABLESIZE);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Temporary list (regexp results) */
|
|
if (keynote_temp_list != NULL)
|
|
{
|
|
ret = keynote_env_lookup(s, &keynote_temp_list, 1);
|
|
if (ret != NULL)
|
|
return ret;
|
|
else
|
|
if (keynote_errno != 0)
|
|
return NULL;
|
|
}
|
|
|
|
/* Local-Constants */
|
|
if (keynote_init_list != NULL)
|
|
{
|
|
ret = keynote_env_lookup(s, &keynote_init_list, 1);
|
|
if (ret != NULL)
|
|
return ret;
|
|
else
|
|
if (keynote_errno != 0)
|
|
return NULL;
|
|
}
|
|
|
|
if (ks != NULL)
|
|
{
|
|
/* Action environment */
|
|
ret = keynote_env_lookup(s, ks->ks_env_table, HASHTABLESIZE);
|
|
if (ret != NULL)
|
|
{
|
|
keynote_used_variable = 1;
|
|
return ret;
|
|
}
|
|
else
|
|
if (keynote_errno != 0)
|
|
return NULL;
|
|
}
|
|
|
|
/* Regex table */
|
|
if ((ks != NULL) && (ks->ks_env_regex != NULL))
|
|
{
|
|
ret = keynote_env_lookup(s, &(ks->ks_env_regex), 1);
|
|
if (ret != NULL)
|
|
{
|
|
keynote_used_variable = 1;
|
|
return ret;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
/*
|
|
* If we had an exception, the boolean expression should return false.
|
|
* Otherwise, return the result of the expression (the argument).
|
|
*/
|
|
static int
|
|
checkexception(int i)
|
|
{
|
|
if (keynote_exceptionflag)
|
|
{
|
|
keynote_exceptionflag = 0;
|
|
return 0;
|
|
}
|
|
else
|
|
return i;
|
|
}
|
|
|
|
|
|
/*
|
|
* Integer exponentiation -- copied from Schneier's AC2, page 244.
|
|
*/
|
|
static int
|
|
intpow(int x, int y)
|
|
{
|
|
int s = 1;
|
|
|
|
/*
|
|
* x^y with y < 0 is equivalent to 1/(x^y), which for
|
|
* integer arithmetic is 0.
|
|
*/
|
|
if (y < 0)
|
|
return 0;
|
|
|
|
while (y)
|
|
{
|
|
if (y & 1)
|
|
s *= x;
|
|
|
|
y >>= 1;
|
|
x *= x;
|
|
}
|
|
|
|
return s;
|
|
}
|
|
|
|
/*
|
|
* Check whether the string is a floating point number.
|
|
*/
|
|
static int
|
|
isfloatstring(char *s)
|
|
{
|
|
int i, point = 0;
|
|
|
|
for (i = strlen(s) - 1; i >= 0; i--)
|
|
if (!isdigit((unsigned char)s[i]))
|
|
{
|
|
if (s[i] == '.')
|
|
{
|
|
if (point == 1)
|
|
return 0;
|
|
else
|
|
point = 1;
|
|
}
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
* Initialize array for threshold search.
|
|
*/
|
|
static int
|
|
keynote_init_kth(void)
|
|
{
|
|
int i = keynote_current_session->ks_values_num;
|
|
|
|
if (i == -1)
|
|
return -1;
|
|
|
|
keynote_kth_array = calloc(i, sizeof(int));
|
|
if (keynote_kth_array == NULL)
|
|
{
|
|
keynote_errno = ERROR_MEMORY;
|
|
return -1;
|
|
}
|
|
|
|
return RESULT_TRUE;
|
|
}
|
|
|
|
/*
|
|
* Get the k-th best return value.
|
|
*/
|
|
static int
|
|
get_kth(int k)
|
|
{
|
|
int i;
|
|
|
|
for (i = keynote_current_session->ks_values_num - 1; i >= 0; i--)
|
|
{
|
|
k -= keynote_kth_array[i];
|
|
|
|
if (k <= 0)
|
|
return i;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* Cleanup array.
|
|
*/
|
|
void
|
|
keynote_cleanup_kth(void)
|
|
{
|
|
if (keynote_kth_array != NULL)
|
|
{
|
|
free(keynote_kth_array);
|
|
keynote_kth_array = NULL;
|
|
}
|
|
}
|
|
|
|
void
|
|
knerror(char *s)
|
|
{}
|