/* $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 #include #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); }