/* $Id: hash_tools.c 1475 2005-09-24 16:25:07Z mipsator $ */
/*
* Copyright (c) 2004-2005 Damien Couderc
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* - Neither the name of the copyright holder(s) nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <stdlib.h>
#include <ctype.h>
#include "compat/pmk_stdio.h"
#include "compat/pmk_string.h"
#include "hash_tools.h"
#include "premake.h"
/**************
* parse_idtf *
***********************************************************************
DESCR
parse string for identifiers
IN
pstr : string to parse
pbuf : resulting string buffer
size : size of buffer
OUT
buffer address or NULL
***********************************************************************/
char *parse_idtf(char *pstr, char *pbuf, size_t size) {
while (((isalnum(*pstr) != 0) || (*pstr == '_')) && (size > 0)) {
*pbuf = *pstr;
pbuf++;
pstr++;
size--;
}
if (size == 0)
return(NULL);
*pbuf = CHAR_EOS;
/* return new cursor */
return(pstr);
}
/******************
* process_string *
***********************************************************************
DESCR
process string to substitute variables with their values
IN
pstr : string to process
pht : hash table where variables are stored
OUT
new string or NULL
***********************************************************************/
char *process_string(char *pstr, htable *pht) {
bool bs = false;
char buf[OPT_VALUE_LEN],
var[OPT_NAME_LEN],
*pvar,
*pval,
*pbuf;
size_t size;
size = sizeof(buf);
pbuf = buf;
while ((*pstr != CHAR_EOS) && (size > 0)) {
switch(*pstr) {
case '\\' :
bs = true;
pstr++;
break;
case '$' :
if (bs == false) {
/* found variable */
pstr++;
pstr = parse_idtf(pstr, var, size);
if (pstr == NULL) {
/* debugf("parse_idtf returned null."); */
return(NULL);
} else {
/* check if identifier exists */
pvar = hash_get(pht, var);
if (pvar != NULL) {
/* process identifer value */
pval = process_string(pvar, pht);
pvar = pval;
/* append value */
while ((*pvar != CHAR_EOS) && (size > 0)) {
*pbuf = *pvar;
pbuf++;
pvar++;
size--;
}
/* clean processed value */
free(pval);
}
}
} else {
/* copy character */
*pbuf = *pstr;
pbuf++;
pstr++;
size--;
bs = false;
}
break;
default :
if (bs == true) {
*pbuf = '\\';
pbuf++;
pstr++;
size--;
if (size == 0) {
/* debugf("overflow."); */
return(NULL);
}
bs = false;
}
/* copy character */
*pbuf = *pstr;
pbuf++;
pstr++;
size--;
break;
}
}
if (size == 0) {
/* debugf("overflow.");*/
return(NULL);
}
*pbuf = CHAR_EOS;
return(strdup(buf));
}
/*****************
* single_append *
***********************************************************************
DESCR
append only if not already in the string
IN
pht : hash table
key : key where to append
value : value to append
OUT
boolean
***********************************************************************/
bool single_append(htable *pht, char *key, char *value) {
bool found = false;
char *cval,
*pstr;
size_t s;
if (value == NULL)
return(false);
if (*value == CHAR_EOS)
return(true);
cval = hash_get(pht, key);
pstr = strstr(cval, value);
s = strlen (value);
while ((pstr != NULL) && (found == false)) {
pstr = pstr + s;
if ((*pstr == ' ') || (*pstr == CHAR_EOS)) {
/* found existing value */
found = true;
}
pstr = strstr(pstr, value);
}
if (found == false) {
if (hash_append(pht, key, value, " ") == HASH_ADD_FAIL) {
/* add failed */
return(false);
}
}
return(true);
}
syntax highlighted by Code2HTML, v. 0.9.1