lib/keys.c File Reference

#include "common.h"
#include "keys.h"
#include "kxTok.h"

Include dependency graph for keys.c:

Go to the source code of this file.

Data Structures

struct  kvt
struct  exp

Enumerations

enum  keyExpType {
  kxMatch, kxWildMatch, kxGT, kxGE,
  kxLT, kxLE, kxAnd, kxOr,
  kxNot, kxXor
}

Functions

kvtnewKvt (int size)
void freeKvt (struct kvt **pKvt)
void kvtClear (struct kvt *kvt)
keyValkvtAdd (struct kvt *kvt, char *key, char *val)
void kvtParseAdd (struct kvt *kvt, char *text)
keyValkvtGet (struct kvt *kvt, char *key)
char * kvtLookup (struct kvt *kvt, char *key)
void kvtWriteAll (struct kvt *kvt, FILE *f, struct slName *hideList)
static void getIntVals (struct kvt *kvt, struct exp *exp, int *retLeft, int *retRight)
static boolean rkeyEval (struct kvt *kvt, struct exp *exp)
boolean keyExpEval (struct keyExp *keyExp, struct kvt *kvt)
static void advanceToken ()
static struct expnextExp ()
static struct expparseRelation ()
static struct expparseParenthesized ()
static struct expparseNot ()
static struct expparseAndExp ()
static struct expparseOrExp ()
static struct expparseExp (struct kxTok *tokList)
keyExpkeyExpParse (char *text)
boolean keyTextScan (char *text, char *key, char *valBuf, int valBufSize)

Variables

static char const rcsid [] = "$Id: keys.c,v 1.10 2005/04/10 14:41:23 markd Exp $"
static struct kxToktoken


Enumeration Type Documentation

enum keyExpType

Enumerator:
kxMatch 
kxWildMatch 
kxGT 
kxGE 
kxLT 
kxLE 
kxAnd 
kxOr 
kxNot 
kxXor 

Definition at line 131 of file keys.c.

00132     {
00133     kxMatch,
00134     kxWildMatch,
00135     kxGT,      /* Greater Than */
00136     kxGE,      /* Greater Than or Equal */
00137     kxLT,      /* Less Than */
00138     kxLE,      /* Less Than or Equal */
00139     kxAnd,
00140     kxOr,
00141     kxNot,
00142     kxXor,
00143     };


Function Documentation

static void advanceToken (  )  [static]

Definition at line 331 of file keys.c.

References kxTok::next, and token.

Referenced by parseAndExp(), parseNot(), parseOrExp(), parseParenthesized(), and parseRelation().

00333 {
00334 token = token->next;
00335 }

Here is the caller graph for this function:

void freeKvt ( struct kvt **  pKvt  ) 

Definition at line 32 of file keys.c.

References freeMem(), freez(), and kvt::table.

00034 {
00035 struct kvt *kvt;
00036 if ((kvt = *pKvt) != NULL)
00037     {
00038     freeMem(kvt->table);
00039     freez(pKvt);
00040     }
00041 }

Here is the call graph for this function:

static void getIntVals ( struct kvt kvt,
struct exp exp,
int *  retLeft,
int *  retRight 
) [static]

Definition at line 152 of file keys.c.

References kvtLookup(), exp::left, and exp::right.

Referenced by rkeyEval().

00155 {
00156 char *rightString = exp->right;
00157 char *leftKey = exp->left;
00158 char *leftString = kvtLookup(kvt, leftKey);
00159 
00160 if (leftString == NULL)
00161     *retLeft = 0;
00162 else
00163     *retLeft = atoi(leftString);
00164 if (rightString == NULL)
00165     *retRight = 0;
00166 else
00167     *retRight = atoi(rightString);
00168 }

Here is the call graph for this function:

Here is the caller graph for this function:

boolean keyExpEval ( struct keyExp keyExp,
struct kvt kvt 
)

Definition at line 321 of file keys.c.

References rkeyEval(), and keyExp::rootExp.

00323 {
00324 return rkeyEval(kvt, keyExp->rootExp);
00325 }

Here is the call graph for this function:

struct keyExp* keyExpParse ( char *  text  )  [read]

Definition at line 519 of file keys.c.

References AllocVar, kxTokenize(), parseExp(), keyExp::rootExp, tok, keyExp::tokenList, and TRUE.

00522 {
00523 struct keyExp *ke;
00524 struct kxTok *tok;
00525 AllocVar(ke);
00526 ke->tokenList = tok = kxTokenize(text, TRUE);
00527 ke->rootExp = parseExp(tok);
00528 
00529 return ke;
00530 }

Here is the call graph for this function:

boolean keyTextScan ( char *  text,
char *  key,
char *  valBuf,
int  valBufSize 
)

Definition at line 534 of file keys.c.

References FALSE, and TRUE.

00536 {
00537 int keySize = strlen(key);
00538 char *s, *nl;
00539 boolean ok = FALSE;
00540 
00541 for (s = text; !isspace(s[0]); s = nl+1)
00542     {
00543     nl = strchr(s, '\n');
00544     assert(nl != NULL);
00545     if (s[keySize] == ' ' && memcmp(s, key, keySize) == 0)
00546         {
00547         char *val = s + keySize + 1;
00548         int valSize = nl - val;
00549         if (valSize >= valBufSize)
00550             valSize = valBufSize-1;
00551         memcpy(valBuf, val, valSize);
00552         valBuf[valSize] = 0;
00553         ok = TRUE;
00554         break;
00555         }
00556     }
00557 return ok;
00558 }

struct keyVal* kvtAdd ( struct kvt kvt,
char *  key,
char *  val 
) [read]

Definition at line 49 of file keys.c.

References kvt::alloced, errAbort(), keyVal::key, kvt::table, kvt::used, and keyVal::val.

Referenced by kvtParseAdd().

00051 {
00052 struct keyVal *kv;
00053 if (kvt->used == kvt->alloced)
00054     errAbort("Too many keys in keyVal(%s %s)", key, val);
00055 kv = &kvt->table[kvt->used++];
00056 kv->key = key;
00057 kv->val = val;
00058 return kv;
00059 }

Here is the call graph for this function:

Here is the caller graph for this function:

void kvtClear ( struct kvt kvt  ) 

Definition at line 43 of file keys.c.

References kvt::used.

00045 {
00046 kvt->used = 0;
00047 }

struct keyVal* kvtGet ( struct kvt kvt,
char *  key 
) [read]

Definition at line 85 of file keys.c.

References sameString, kvt::table, and kvt::used.

Referenced by kvtLookup().

00087 {
00088 int i;
00089 struct keyVal *keyTable = kvt->table;
00090 int keysUsed = kvt->used;
00091 
00092 for (i=0; i<keysUsed; ++i)
00093     {
00094     if (sameString(key, keyTable[i].key))
00095         return &keyTable[i];
00096     }
00097 return NULL;
00098 }

Here is the caller graph for this function:

char* kvtLookup ( struct kvt kvt,
char *  key 
)

Definition at line 100 of file keys.c.

References kvtGet(), and keyVal::val.

Referenced by getIntVals(), and rkeyEval().

00103 {
00104 struct keyVal *keyVal = kvtGet(kvt, key);
00105 if (keyVal == NULL)
00106     return NULL;
00107 else
00108     return keyVal->val;
00109 }

Here is the call graph for this function:

Here is the caller graph for this function:

void kvtParseAdd ( struct kvt kvt,
char *  text 
)

Definition at line 61 of file keys.c.

References ArraySize, chopString(), and kvtAdd().

00062                                             :
00063  *     key val
00064  * for each line of text. Text gets many of it's
00065  * space characters and newlines replaced by 0's
00066  * and should persist until call to keysClear(). */
00067 {
00068 char *lines[256];
00069 int lineCount;
00070 int i;
00071 char *k, *v;
00072 
00073 lineCount = chopString(text, "\n\r", lines, ArraySize(lines));
00074 for (i=0; i<lineCount; ++i)
00075     {
00076     k = lines[i];
00077     if ((v = strchr(k, ' ')) != NULL)
00078         {
00079         *v++ = 0;
00080         kvtAdd(kvt, k, v);
00081         }
00082     }
00083 }

Here is the call graph for this function:

void kvtWriteAll ( struct kvt kvt,
FILE *  f,
struct slName hideList 
)

Definition at line 111 of file keys.c.

References keyVal::key, mustWrite(), slNameInList(), kvt::table, kvt::used, and keyVal::val.

00113 {
00114 int i;
00115 static char lf = '\n';
00116 struct keyVal *kv = kvt->table;
00117 int keyCount = kvt->used;
00118 
00119 for (i=0; i<keyCount; ++i)
00120     {
00121     char *key = kv->key;
00122     if (kv->val != NULL && !slNameInList(hideList, key))
00123         fprintf(f, "%s %s\n", key, kv->val);
00124     ++kv;
00125     }
00126 mustWrite(f, &lf, 1);   /* Instead of fputc for error checking. */
00127 }

Here is the call graph for this function:

struct kvt* newKvt ( int  size  )  [read]

Definition at line 21 of file keys.c.

References kvt::alloced, AllocVar, needMem(), and kvt::table.

00023 {
00024 struct kvt *kvt;
00025 AllocVar(kvt);
00026 kvt->alloced = size;
00027 kvt->table = needMem(size * sizeof(kvt->table[0]));
00028 return kvt;
00029 }

Here is the call graph for this function:

static struct exp * nextExp (  )  [static, read]

Definition at line 500 of file keys.c.

References parseOrExp().

Referenced by parseAndExp(), parseExp(), parseNot(), parseOrExp(), and parseParenthesized().

00502 {
00503 return parseOrExp();
00504 }

Here is the call graph for this function:

Here is the caller graph for this function:

static struct exp* parseAndExp (  )  [static, read]

Definition at line 439 of file keys.c.

References advanceToken(), AllocVar, errAbort(), kxAnd, kxtAnd, exp::left, nextExp(), parseNot(), exp::right, kxTok::string, tok, token, exp::type, and kxTok::type.

Referenced by parseOrExp().

00441 {
00442 struct exp *left;
00443 struct exp *right, *exp;
00444 struct kxTok *tok;
00445 enum kxTokType type;
00446 
00447 if ((left = parseNot()) == NULL)
00448     return NULL;
00449 if ((tok = token) == NULL)
00450     return left;
00451 type = token->type;
00452 if (type == kxtAnd)
00453     {
00454     advanceToken();
00455     right = nextExp();
00456     if (right == NULL)
00457         errAbort("Expecting expression on the other side of %s", tok->string);
00458     AllocVar(exp);
00459     exp->left = left;
00460     exp->right = right;
00461     exp->type = kxAnd;
00462     return exp;
00463     }
00464 else
00465     return left;    
00466 }

Here is the call graph for this function:

Here is the caller graph for this function:

static struct exp* parseExp ( struct kxTok tokList  )  [static, read]

Definition at line 506 of file keys.c.

References errAbort(), kxtEnd, nextExp(), token, and kxTok::type.

Referenced by keyExpParse().

00508 {
00509 struct exp *exp;
00510 token = tokList;
00511 exp =  nextExp();
00512 if (token->type != kxtEnd)
00513     {
00514     errAbort("Extra tokens past end of expression.  Missing &?");
00515     }
00516 return exp;
00517 }

Here is the call graph for this function:

Here is the caller graph for this function:

static struct exp* parseNot (  )  [static, read]

Definition at line 418 of file keys.c.

References advanceToken(), AllocVar, kxNot, kxtNot, nextExp(), parseParenthesized(), exp::right, token, exp::type, and kxTok::type.

Referenced by parseAndExp().

00420 {
00421 struct exp *exp;
00422 struct exp *right;
00423 
00424 if (token == NULL)
00425     return NULL;
00426 if (token->type == kxtNot)
00427     {
00428     advanceToken();
00429     right = nextExp();
00430     AllocVar(exp);
00431     exp->right = right;
00432     exp->type = kxNot;
00433     return exp;
00434     }
00435 else
00436     return parseParenthesized();
00437 }

Here is the call graph for this function:

Here is the caller graph for this function:

static struct exp* parseOrExp (  )  [static, read]

Definition at line 468 of file keys.c.

References advanceToken(), AllocVar, errAbort(), kxOr, kxtOr, kxtXor, kxXor, exp::left, nextExp(), parseAndExp(), exp::right, kxTok::string, tok, token, exp::type, and kxTok::type.

Referenced by nextExp().

00470 {
00471 struct exp *left;
00472 struct exp *right, *exp;
00473 struct kxTok *tok;
00474 enum kxTokType type;
00475 
00476 if ((left = parseAndExp()) == NULL)
00477     return NULL;
00478 if ((tok = token) == NULL)
00479     return left;
00480 type = token->type;
00481 if (type == kxtOr || type == kxtXor)
00482     {
00483     advanceToken();
00484     right = nextExp();
00485     if (right == NULL)
00486         errAbort("Expecting expression on the other side of %s", tok->string);
00487     AllocVar(exp);
00488     exp->left = left;
00489     exp->right = right;
00490     if (type == kxtOr)
00491         exp->type = kxOr;
00492     else
00493         exp->type = kxXor;
00494     return exp;
00495     }
00496 else
00497     return left;    
00498 }

Here is the call graph for this function:

Here is the caller graph for this function:

static struct exp* parseParenthesized (  )  [static, read]

Definition at line 397 of file keys.c.

References advanceToken(), errAbort(), kxtCloseParen, kxtOpenParen, nextExp(), parseRelation(), token, and kxTok::type.

Referenced by parseNot().

00399 {
00400 struct exp *exp;
00401 if (token == NULL)
00402     return NULL;
00403 if (token->type == kxtOpenParen)
00404     {
00405     advanceToken();
00406     exp = nextExp();
00407     if (token->type != kxtCloseParen)
00408         errAbort("Unmatched parenthesis");
00409     advanceToken();
00410     return exp;
00411     }
00412 else
00413     {
00414     return parseRelation();
00415     }            
00416 }

Here is the call graph for this function:

Here is the caller graph for this function:

static struct exp* parseRelation (  )  [static, read]

Definition at line 339 of file keys.c.

References advanceToken(), AllocVar, errAbort(), kxGE, kxGT, kxLE, kxLT, kxMatch, kxtEquals, kxtGE, kxtGT, kxtLE, kxtLT, kxtString, kxtWildString, kxWildMatch, exp::left, exp::right, kxTok::string, token, exp::type, and kxTok::type.

Referenced by parseParenthesized().

00341 {
00342 struct kxTok *key, *match;
00343 
00344 if (token == NULL)
00345     return NULL;
00346 if (token->type != kxtString)
00347     errAbort("Expecting key got %s", token->string);
00348 key = token;
00349 advanceToken();
00350 if (token->type == kxtEquals)
00351     {
00352     advanceToken();
00353     if (token->type == kxtString || token->type == kxtWildString)
00354         {
00355         struct exp *exp;
00356         match = token;
00357         advanceToken();
00358         AllocVar(exp);
00359         exp->left = key->string;
00360         exp->right = match->string;
00361         exp->type = (match->type == kxtString ? kxMatch : kxWildMatch);
00362         return exp;
00363         }
00364     else
00365         {
00366         errAbort("Expecting string to match in key=match expression,\ngot %s", token->string);
00367         }
00368     }
00369 else if (token->type == kxtGT || token->type == kxtGE || token->type == kxtLT || token->type == kxtLE)
00370     {
00371     enum kxTokType relation = token->type;
00372     advanceToken();
00373     if (isdigit(token->string[0]))
00374         {
00375         struct exp *exp;
00376         match = token;
00377         advanceToken();
00378         AllocVar(exp);
00379         exp->left = key->string;
00380         exp->right = match->string;
00381         if (relation == kxtGT) exp->type = kxGT;
00382         else if (relation == kxtGE) exp->type = kxGE;
00383         else if (relation == kxtLT) exp->type = kxLT;
00384         else if (relation == kxtLE) exp->type = kxLE;
00385         return exp;
00386         }
00387     else
00388         {
00389         errAbort("Expecting number got %s", token->string);
00390         }
00391     }
00392 else
00393     errAbort("Expecting = got %s", token->string);
00394 return NULL;
00395 }

Here is the call graph for this function:

Here is the caller graph for this function:

static boolean rkeyEval ( struct kvt kvt,
struct exp exp 
) [static]

Definition at line 245 of file keys.c.

References errAbort(), getIntVals(), kvtLookup(), kxAnd, kxGE, kxGT, kxLE, kxLT, kxMatch, kxNot, kxOr, kxWildMatch, kxXor, exp::left, exp::right, sameString, sameWord, TRUE, exp::type, and wildMatch().

Referenced by keyExpEval().

00247 {
00248 if (exp == NULL)
00249     return TRUE;
00250 switch (exp->type)
00251     {
00252     case kxMatch:
00253         {
00254         char *key = exp->left;
00255         char *matcher = exp->right;
00256         char *val = kvtLookup(kvt, key);
00257         if (val == NULL)
00258             return sameWord(matcher, "null");
00259         else
00260             return sameWord(matcher, val);
00261         }
00262     case kxWildMatch:
00263         {
00264         char *key = exp->left;
00265         char *matcher = exp->right;
00266         char *val = kvtLookup(kvt, key);
00267         if (val == NULL)
00268             return sameString(matcher, "*");
00269         else
00270             return wildMatch(matcher, val);
00271         }
00272     case kxGT:
00273         {
00274         int left, right;
00275         getIntVals(kvt, exp, &left, &right);
00276         return left > right;
00277         }
00278     case kxGE:
00279         {
00280         int left, right;
00281         getIntVals(kvt, exp, &left, &right);
00282         return left >= right;
00283         }
00284     case kxLT:
00285         {
00286         int left, right;
00287         getIntVals(kvt, exp, &left, &right);
00288         return left < right;
00289         }
00290     case kxLE:
00291         {
00292         int left, right;
00293         getIntVals(kvt, exp, &left, &right);
00294         return left <= right;
00295         }
00296     
00297     case kxNot:
00298         {
00299         return !rkeyEval(kvt, exp->right);
00300         }
00301     case kxAnd:
00302         {
00303         return rkeyEval(kvt, exp->left) && rkeyEval(kvt, exp->right);
00304         }
00305     case kxOr:
00306         {
00307         return rkeyEval(kvt, exp->left) || rkeyEval(kvt, exp->right);
00308         }
00309     case kxXor:
00310         {
00311         return rkeyEval(kvt, exp->left) ^ rkeyEval(kvt, exp->right);
00312         }
00313     default:
00314         {
00315         errAbort("unknown expression type %d", exp->type);
00316         return 0;
00317         }
00318     }
00319 }

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

char const rcsid[] = "$Id: keys.c,v 1.10 2005/04/10 14:41:23 markd Exp $" [static]

Definition at line 11 of file keys.c.

struct kxTok* token [static]

Definition at line 329 of file keys.c.

Referenced by advanceToken(), parseAndExp(), parseExp(), parseNot(), parseOrExp(), parseParenthesized(), and parseRelation().


Generated on Tue Dec 25 19:57:16 2007 for blat by  doxygen 1.5.2