home *** CD-ROM | disk | FTP | other *** search
- #ifdef NODEBUG
- #undef NODEBUG
- #endif
- #define TRACESTUFF
- #include <useful.h>
- #include <ctype.h>
-
- VERSIONID("$Header: traceset.c,v 2.0 89/12/24 00:56:33 eric Exp $");
-
- /*
- ** TRACESET -- set trace flags
- **
- ** Parameters:
- ** s -- the string describing the trace flags desired.
- **
- ** Returns:
- ** none.
- **
- ** Side Effects:
- ** Sets values in the trace vector.
- **
- ** Globals:
- ** _TraceVect -- used by TRACE and TRACEF to determine the
- ** current trace flag settings.
- **
- ** Syntax:
- ** The argument points to a set of comma separated trace
- ** flag settings. Each setting is a trace flag name, or
- ** a range of trace flags separated by a hyphen. The
- ** setting may be followed by a dot and a level. For
- ** example, "5,23-26.4" sets trace flag 5 to level 1 (the
- ** default), and flags 23 through 26 to level 4.
- **
- ** Trace flags names may be numeric or symbolic. Symbolic
- ** names are looked up in the file "lib/traceflags", which
- ** is found somewhere in the search path. This file has a
- ** simple "name <white-space> value" syntax.
- **
- ** Author:
- ** Eric Allman
- ** University of California, Berkeley
- */
-
- STATIC FILE *_TraceSymFile = FILENULL;
- STATIC BOOL _TraceSymCant = FALSE;
- unsigned char _TraceVect[_TRACE_SIZE];
-
- VOID
- traceset(s)
- char *s;
- {
- int lo;
- int hi;
- int lev;
-
- if (s == CHARNULL || *s == '\0')
- s = "0-999";
-
- do
- {
- /* get the low limit of the range */
- lo = _tracetok(&s, TRUE);
- if (lo < 0)
- lo = 0;
-
- /* get the high limit of the range */
- if (*s == '-')
- hi = _tracetok(&s, TRUE);
- else
- hi = lo;
- if (hi >= _TRACE_SIZE)
- hi = _TRACE_SIZE - 1;
-
- /* get the trace level */
- if (*s == '.')
- lev = _tracetok(&s, FALSE);
- else
- lev = 1;
- if (lev < 0)
- lev = 1;
-
- /* now do the actual setting */
- while (lo <= hi)
- _TraceVect[lo++] = lev;
- } while (*s != '\0');
-
- if (_TraceSymFile != FILENULL)
- {
- fclose(_TraceSymFile);
- _TraceSymFile = FILENULL;
- }
- }
- /*
- ** _TRACETOK -- extract a token
- **
- ** Parameters:
- ** sp -- an indirect pointer to the string form. It is
- ** updated to point to the token terminator.
- ** symok -- if TRUE, a symbolic representation can be
- ** used.
- **
- ** Returns:
- ** The value of the token.
- ** -1 on error.
- **
- ** Side Effects:
- ** none.
- */
-
- STATIC int
- _tracetok(sp, symok)
- char **sp;
- BOOL symok;
- {
- register char *s = *sp;
- register char *tp;
- char tbuf[MAXWORDLEN + 1];
- char dbuf[MAXINPUTLINE];
-
- /* skip leading cruft */
- while (*s != '\0' && !isalnum(*s))
- s++;
-
- /* extract token */
- for (tp = tbuf; isalnum(*s); *tp++ = *s++)
- continue;
- *tp = '\0';
-
- /* drop trailing cruft */
- while (isspace(*s))
- s++;
- *sp = s;
-
- /* now decode token */
- if (isdigit(tbuf[0]))
- return (atoi(tbuf));
- if (!symok)
- return (-1);
-
- /* look up symbol */
- if (!_TraceSymCant && _TraceSymFile == FILENULL)
- {
- extern FILE *openpath ARGS((char *, char *, char *));
-
- _TraceSymFile = openpath("lib/traceflags", "r", CHARNULL);
- }
- if (_TraceSymFile == FILENULL)
- {
- _TraceSymCant = TRUE;
- return (-1);
- }
- rewind(_TraceSymFile);
-
- /* search through the trace file for a matching line */
- while (fgets(dbuf, sizeof dbuf, _TraceSymFile) != CHARNULL)
- {
- register char *ep;
- extern char *_tracematch ARGS((char *, char *));
-
- /* comment? */
- if (dbuf[0] == '#' || dbuf[0] == '\n')
- continue;
-
- /* does it match? */
- ep = _tracematch(tbuf, dbuf);
- if (ep != CHARNULL)
- return (atoi(ep));
- }
- return (-1);
- }
-
- STATIC char *
- _tracematch(tp, dp)
- register char *tp;
- register char *dp;
- {
- for ( ; *tp != '\0'; tp++, dp++)
- {
- /* if we have an exact match, continue trying */
- if (*tp == *dp)
- continue;
-
- /* well, let's try a caseless match */
- if (isupper(*tp) && tolower(*tp) == *dp)
- continue;
- if (isupper(*dp) && tolower(*dp) == *tp)
- continue;
-
- /* well foo... I guess it doesn't match */
- return (CHARNULL);
- }
-
- /* check the boundary conditions */
- if (!isspace(*dp))
- return (CHARNULL);
-
- /* drop the trailing white space and return the pointer */
- while (isspace(*dp))
- dp++;
- return (dp);
- }
-