/* $Id: cfgtool.c 1535 2006-01-29 12:35:19Z 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_stdbool.h" #include "compat/pmk_stdio.h" #include "compat/pmk_string.h" #include "cfgtool.h" #include "common.h" #include "parse.h" #include "premake.h" /*#define CFGT_DEBUG 1*/ /* config tools data file keyword */ prskw kw_pmkcfgtool[] = { {"ADD_CFGTOOL", CFGT_TOK_ADDCT, PRS_KW_CELL, PRS_TOK_NULL, NULL} }; int nbkwct = sizeof(kw_pmkcfgtool) / sizeof(prskw); /********************** * cfgtcell_destroy() * *********************************************************************** DESCR free cfgtcell structure IN pcc : configtool cell OUT NONE ***********************************************************************/ void cfgtcell_destroy(cfgtcell *pcc) { #ifdef CFGT_DEBUG debugf("free cfgtcell '%s'", pcc->name); #endif free(pcc->name); free(pcc->binary); if (pcc->version != NULL) free(pcc->version); if (pcc->module != NULL) free(pcc->module); if (pcc->cflags != NULL) free(pcc->cflags); if (pcc->libs != NULL) free(pcc->libs); free(pcc); } /******************* * cfgtdata_init() * *********************************************************************** DESCR initialize cfgtdata structure IN NONE OUT config data structure ***********************************************************************/ cfgtdata *cfgtdata_init(void) { cfgtdata *pcd; /* initialise configt tool data structure */ pcd = (cfgtdata *) malloc(sizeof(cfgtdata)); if (pcd == NULL) { #ifdef CFGT_DEBUG debugf("cannot initialize config tool data"); #endif return(NULL); } /* initialize config tool hash table */ pcd->by_mod = hash_init_adv(CFGTOOL_HT_SIZE, NULL, (void (*)(void *)) cfgtcell_destroy, NULL); if (pcd->by_mod == NULL) { free(pcd); #ifdef CFGT_DEBUG debugf("cannot initialize config tool hash table"); #endif return(NULL); } /* initialize config tool hash table */ pcd->by_bin = hash_init(CFGTOOL_HT_SIZE); if (pcd->by_bin == NULL) { hash_destroy(pcd->by_mod); free(pcd); #ifdef CFGT_DEBUG debugf("cannot initialize config tool hash table"); #endif return(NULL); } return(pcd); } /********************** * cfgtdata_destroy() * *********************************************************************** DESCR free cfgtdata structure IN pcd : config data structure OUT ***********************************************************************/ void cfgtdata_destroy(cfgtdata *pcd) { #ifdef CFGT_DEBUG debugf("destroying module hash table."); #endif if (pcd->by_mod != NULL) { hash_destroy(pcd->by_mod); #ifdef CFGT_DEBUG debugf("destroyed module hash table."); } else { debugf("WARNING : by_mod doesn't exists !!!"); #endif } #ifdef CFGT_DEBUG debugf("destroying binary links hash table."); #endif if (pcd->by_mod != NULL) { hash_destroy(pcd->by_bin); #ifdef CFGT_DEBUG debugf("destroyed binary links hash table."); } else { debugf("WARNING : by_bin doesn't exists !!!"); #endif } } /***************** * add_cfgtool() * *********************************************************************** DESCR add a new config tool cell IN pcd : config tool data structure pht : parsed data OUT boolean ***********************************************************************/ bool add_cfgtool(cfgtdata *pcd, htable *pht) { cfgtcell *pcell; char *pstr; pcell = (cfgtcell *) malloc(sizeof(cfgtcell)); if (pcell == NULL) return(false); pstr = po_get_str(hash_get(pht, "NAME")); if (pstr == NULL) { free(pcell); return(false); } else { pcell->name = strdup(pstr); if (pcell->name == NULL) { free(pcell); errorf(ERRMSG_MEM); return(false); } } pstr = po_get_str(hash_get(pht, "BINARY")); if (pstr == NULL) { free(pcell->name); free(pcell); return(false); } else { pcell->binary = strdup(pstr); if (pcell->binary == NULL) { free(pcell); errorf(ERRMSG_MEM); return(false); } } pstr = po_get_str(hash_get(pht, "VERSION")); if (pstr != NULL) { pcell->version = strdup(pstr); if (pcell->version == NULL) { free(pcell); errorf(ERRMSG_MEM); return(false); } } else { pcell->version = NULL; } pstr = po_get_str(hash_get(pht, "MODULE")); if (pstr != NULL) { pcell->module = strdup(pstr); if (pcell->module == NULL) { free(pcell); errorf(ERRMSG_MEM); return(false); } } else { pcell->module = NULL; } pstr = po_get_str(hash_get(pht, "CFLAGS")); if (pstr != NULL) { pcell->cflags = strdup(pstr); if (pcell->cflags == NULL) { free(pcell); errorf(ERRMSG_MEM); return(false); } } else { pcell->cflags = NULL; } pstr = po_get_str(hash_get(pht, "LIBS")); if (pstr != NULL) { pcell->libs = strdup(pstr); if (pcell->libs == NULL) { free(pcell); errorf(ERRMSG_MEM); return(false); } } else { pcell->libs = NULL; } /* no need to strdup */ if (hash_update(pcd->by_mod, pcell->name, pcell) == HASH_ADD_FAIL) return(false); #ifdef CFGT_DEBUG debugf("added cfgtcell '%s'", pcell->name); #endif if (hash_update_dup(pcd->by_bin, pcell->binary, pcell->name) == HASH_ADD_FAIL) return(false); #ifdef CFGT_DEBUG debugf("added cfgtcell '%s'", pcell->binary); #endif return(true); } /********************* * parse_cfgt_file() * *********************************************************************** DESCR parse data from PMKCFG_DATA file IN NONE OUT compiler data structure or NULL ***********************************************************************/ cfgtdata *parse_cfgt_file(void) { FILE *fp; bool rval; cfgtdata *pcd; prscell *pcell; prsdata *pdata; /* initialize parsing structure */ pdata = prsdata_init(); if (pdata == NULL) { errorf("cannot intialize prsdata."); return(NULL); } /* initialise configt tool data structure */ pcd = cfgtdata_init(); if (pcd == NULL) { prsdata_destroy(pdata); debugf("cannot initialize config tool data"); return(NULL); } fp = fopen(PMKCFG_DATA, "r"); if (fp == NULL) { hash_destroy(pcd->by_mod); hash_destroy(pcd->by_bin); free(pcd); prsdata_destroy(pdata); errorf("cannot open '%s' : %s.", PMKCFG_DATA, strerror(errno)); return(NULL); } /* parse data file and fill prsdata strucutre */ rval = parse_pmkfile(fp, pdata, kw_pmkcfgtool, nbkwct); fclose(fp); if (rval == true) { pcell = pdata->tree->first; while (pcell != NULL) { switch(pcell->token) { case CFGT_TOK_ADDCT : add_cfgtool(pcd, pcell->data); break; default : errorf("parsing of data file failed."); hash_destroy(pcd->by_mod); hash_destroy(pcd->by_bin); free(pcd); prsdata_destroy(pdata); return(NULL); break; } pcell = pcell->next; } } else { errorf("parsing of data file failed."); hash_destroy(pcd->by_mod); hash_destroy(pcd->by_bin); free(pcd); prsdata_destroy(pdata); return(NULL); } /* parsing data no longer needed */ prsdata_destroy(pdata); return(pcd); } /************************* * cfgtcell_get_binary() * *********************************************************************** DESCR get binary name from a given module name IN pgd : global data structure mod : module name buf : buffer to store binary name sb : buffer size OUT boolean ***********************************************************************/ bool cfgtcell_get_binary(cfgtdata *pcd, char *mod, char *buf, size_t sb) { cfgtcell *pcc; if (pcd == NULL) { /* not found */ return(false); } pcc = hash_get(pcd->by_mod, mod); if (pcc == NULL) { /* not found */ return(false); } else { /* found, copy */ if (strlcpy_b(buf, pcc->binary, sb) == false) return(false); return(true); } } /*********************** * cfgtcell_get_cell() * *********************************************************************** DESCR get cell relative to a given config tool filename IN pgd : global data structure binary : binary name OUT cfgtcell structure or NULL ***********************************************************************/ cfgtcell *cfgtcell_get_cell(cfgtdata *pcd, char *binary) { char *mod; if (pcd == NULL) { /* not found */ return(false); } mod = hash_get(pcd->by_bin, binary); if (mod == NULL) { /* not found */ return(NULL); } else { /* found, copy */ return(hash_get(pcd->by_mod, mod)); } } /******************** * ct_get_version() * *********************************************************************** DESCR use config tool to get the version IN ctpath : config tool path vstr : option string to get version buffer : storage buffer for the result sbuf : size of buffer OUT boolean ***********************************************************************/ bool ct_get_version(char *ctpath, char *vstr, char *buffer, size_t sbuf) { FILE *rpipe; bool rval = false; char cfgcmd[MAXPATHLEN]; if (snprintf_b(cfgcmd, sizeof(cfgcmd), CT_FORMAT_VERSION, ctpath, vstr) == false) return(false); rpipe = popen(cfgcmd, "r"); if (rpipe != NULL) { /* get version line */ rval = get_line(rpipe, buffer, sbuf); pclose(rpipe); } return(rval); } /***************** * ct_get_data() * *********************************************************************** DESCR use config tool to get data IN ctpath : config tool path vstr : option string to get version buffer : storage buffer for the result sbuf : size of buffer OUT boolean ***********************************************************************/ bool ct_get_data(char *ctpath, char *ostr, char *mod, char *buffer, size_t sbuf) { FILE *rpipe; bool rval = false; char cfgcmd[MAXPATHLEN]; if (mod == NULL) { /* no module */ if (snprintf_b(cfgcmd, sizeof(cfgcmd), CT_FORMAT_DATA, ctpath, ostr) == false) return(false); } else { /* use module */ if (snprintf_b(cfgcmd, sizeof(cfgcmd), CT_FORMAT_DATA_MOD, ctpath, ostr, mod) == false) return(false); } rpipe = popen(cfgcmd, "r"); if (rpipe != NULL) { /* get version line */ rval = get_line(rpipe, buffer, sbuf); pclose(rpipe); } return(rval); }