diff options
Diffstat (limited to 'src/pmlogextract/gram.y')
-rw-r--r-- | src/pmlogextract/gram.y | 381 |
1 files changed, 381 insertions, 0 deletions
diff --git a/src/pmlogextract/gram.y b/src/pmlogextract/gram.y new file mode 100644 index 0000000..66330a9 --- /dev/null +++ b/src/pmlogextract/gram.y @@ -0,0 +1,381 @@ +/* + * Copyright (c) 1997-2002 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +%{ +/* + * pmlogextract parser + */ +#include "pmapi.h" +#include "impl.h" +#include "logger.h" + +int i; +int found; +int argcount; /* number of arguments in config file */ +char *arglist[24]; /* arguments from config file */ +char emess[240]; + +static char *name; +static int sts; +static int numinst; /* num instances (per metric) in config file */ +static int *intlist; /* instance id's (internal list) */ +static char **extlist; /* instance names (external list) */ +static int warn = 1; + +extern int lineno; + +static void buildinst(int *, int **, char ***, int , char *); +static void freeinst(int *, int *, char **); + +%} +%union { + long lval; + char * str; +} + +%token LSQB + RSQB + COMMA + +%token<str> NAME STRING +%token<lval> NUMBER +%% + +config : somemetrics + ; + +somemetrics : metriclist + | /* nothing */ + ; + +metriclist : metricspec + | metriclist metricspec + | metriclist COMMA metricspec + ; + +metricspec : NAME { name = strdup($1); numinst = 0; } optinst + { + if (name == NULL) { + snprintf(emess, sizeof(emess), "malloc failed: %s", osstrerror()); + yyerror(emess); + } + found = 0; + for (i=0; i<inarchnum; i++) { + if ((sts = pmUseContext(inarch[i].ctx)) < 0) { + fprintf(stderr, + "%s: Error: cannot use context (%d) " + "from archive \"%s\"\n", + pmProgname, inarch[i].ctx, inarch[i].name); + exit(1); + } + + if ((sts = pmTraversePMNS (name, dometric)) >= 0) { + found = 1; + break; + } + } + + if (!found) { + snprintf(emess, sizeof(emess), + "Problem with lookup for metric \"%s\" ... " + "metric ignored", name); + yywarn(emess); + fprintf(stderr, "Reason: %s\n", pmErrStr(sts)); + } + + free(name); + freeinst(&numinst, intlist, extlist); + } + ; + +optinst : LSQB instancelist RSQB + | /* nothing */ + ; + +instancelist : instance + | instance instancelist + | instance COMMA instancelist + ; + +instance : NAME { buildinst(&numinst, &intlist, &extlist, -1, $1); } + | NUMBER{ buildinst(&numinst, &intlist, &extlist, $1, NULL);} + | STRING{ buildinst(&numinst, &intlist, &extlist, -1, $1);} + ; + +%% + +void +dometric(const char *name) +{ + int i; + int j; + int inst; + int skip; + int sts; + pmID pmid; + pmDesc *dp; + + if ((dp = (pmDesc *)malloc(sizeof(pmDesc))) == NULL) { + goto nomem; + } + + /* Cast away const, pmLookUpName should not modify name + */ + if ((sts = pmLookupName(1,(char **)&name,&pmid)) < 0 || pmid == PM_ID_NULL){ + snprintf(emess, sizeof(emess), "Metric \"%s\" is unknown ... not logged", name); + goto defer; + } + + if ((sts = pmLookupDesc(pmid, dp)) < 0) { + snprintf(emess, sizeof(emess), + "Description unavailable for metric \"%s\" ... not logged", name); + goto defer; + } + + + ml_numpmid++; + if (ml_size < ml_numpmid) { + ml_size = ml_numpmid; + ml = (mlist_t *) realloc(ml, ml_size * sizeof(mlist_t)); + if (ml == NULL) { + goto nomem; + } + } + + ml[ml_numpmid-1].name = NULL; + ml[ml_numpmid-1].idesc = NULL; + ml[ml_numpmid-1].odesc = NULL; + ml[ml_numpmid-1].numinst = 0; + ml[ml_numpmid-1].instlist = NULL; + + + /* + * ml_nmpmid-1 == index of latest addition to the list + */ + + ml[ml_numpmid-1].name = strdup(name); + if (ml[ml_numpmid-1].name == NULL) { + goto nomem; + } + + /* input descriptor (idesc) and output descriptor (odesc) are initially + * pointed at the same descriptor + */ + ml[ml_numpmid-1].idesc = dp; + ml[ml_numpmid-1].odesc = dp; + ml[ml_numpmid-1].numinst = numinst; + + skip = 0; + if (numinst == 0) { + intlist = NULL; + extlist = NULL; + /* user hasn't specified any instances + * - if there is NO instance domain, then allocate at least one + * - if there is an instance domain, then need to get them all + */ + if (dp->indom == PM_INDOM_NULL) { + ml[ml_numpmid-1].numinst = 1; + } + else { + if ((sts = pmGetInDomArchive(dp->indom, &intlist, &extlist)) < 0) { + if (sts == PM_ERR_INDOM_LOG) { + /* + * If instance domain is not in archive, then there + * are no instances, this is not a fatal error + */ + ml[ml_numpmid-1].numinst = 0; + ml[ml_numpmid-1].instlist = NULL; + } + else { + snprintf(emess, sizeof(emess), + "Cannot get instance domain for metric %s - %s)\n", + name, pmErrStr(sts)); + yyerror(emess); + } + } + else + ml[ml_numpmid-1].numinst = sts; + } + + if (ml[ml_numpmid-1].numinst >= 1) { + /* + * malloc here, and keep ... gets buried + */ + ml[ml_numpmid-1].instlist = (int *)malloc(ml[ml_numpmid-1].numinst * sizeof(int)); + if (ml[ml_numpmid-1].instlist == NULL) { + goto nomem; + } + + for (i=0; i<ml[ml_numpmid-1].numinst; i++) { + if (intlist == NULL) { + /* PM_INDOM_NULL case */ + ml[ml_numpmid-1].instlist[i] = -1; + } + else + ml[ml_numpmid-1].instlist[i] = intlist[i]; + + } /*for(i)*/ + } + + if (intlist != NULL) + free(intlist); + if (extlist != NULL) + free(extlist); + + intlist = NULL; + extlist = NULL; + } + else if (numinst) { + /* + * malloc here, and keep ... gets buried + */ + ml[ml_numpmid-1].instlist = (int *)malloc(numinst * sizeof(int)); + if (ml[ml_numpmid-1].instlist == NULL) { + goto nomem; + } + + j = 0; + for (i=0; i<numinst; i++) { + inst = -1; + if (extlist[i] != NULL) { + if ((sts = pmLookupInDomArchive(dp->indom, extlist[i])) < 0) { + snprintf(emess, sizeof(emess), + "Instance \"%s\" is not defined for the metric \"%s\"", + extlist[i], name); + yywarn(emess); + ml[ml_numpmid-1].numinst--; + continue; + } + inst = sts; + } + else { + char *p; + if ((sts = pmNameInDomArchive(dp->indom, intlist[i], &p)) < 0) { + snprintf(emess, sizeof(emess), + "Instance \"%d\" is not defined for the metric \"%s\"", + intlist[i], name); + yywarn(emess); + ml[ml_numpmid-1].numinst--; + continue; + } + else { + inst = intlist[i]; + } + free(p); + } + + /* if inst is > -1 then this instance exists, and its id is `inst' + */ + if (inst > -1) { + ml[ml_numpmid-1].instlist[j] = inst; + ++j; + } + } /* for(i) */ + + if (ml[ml_numpmid-1].numinst == 0) + skip = 1; + + } + + + /* if skip has been set, then this metric has no instances + * (probably because all instances specified by user are invalid) + * then we don't want this metric, so ... + * - free dp (the descriptor) + * - free the instance list + * - adjust ml_numpmid ... do not free the space ... it isn't much + * and we may need it (if there is another metric) + */ + if (skip) { + free(dp); + free(ml[ml_numpmid-1].instlist); + --ml_numpmid; + } + else { + /* EXCEPTION PCP 2.1.1 - may want to check instances here + */ + } + return; + +defer: + /* EXCEPTION PCP 2.1.1 - defer this one until sometime later ... */ + if (warn) { + yywarn(emess); + fprintf(stderr, "Reason: %s\n", pmErrStr(sts)); + } + free(dp); + return; + +nomem: + snprintf(emess, sizeof(emess), "malloc failed: %s", osstrerror()); + yyerror(emess); +} + + +static void +buildinst(int *numinst, int **intlist, char ***extlist, int intid, char *extid) +{ + char **el; + int *il; + int num = *numinst; + + if (num == 0) { + il = NULL; + el = NULL; + } + else { + il = *intlist; + el = *extlist; + } + + el = (char **)realloc(el, (num+1)*sizeof(el[0])); + il = (int *)realloc(il, (num+1)*sizeof(il[0])); + + il[num] = intid; + + if (extid == NULL) + el[num] = NULL; + else { + if (*extid == '"') { + char *p; + p = ++extid; + while (*p && *p != '"') p++; + *p = '\0'; + } + el[num] = strdup(extid); + } + + *numinst = ++num; + *intlist = il; + *extlist = el; +} + + +static void +freeinst(int *numinst, int *intlist, char **extlist) +{ + int i; + + if (*numinst) { + free(intlist); + for (i = 0; i < *numinst; i++) + free(extlist[i]); + free(extlist); + + intlist = NULL; + extlist = NULL; + *numinst = 0; + } +} + |