home *** CD-ROM | disk | FTP | other *** search
- /************************************************************************
- * *
- * Copyright (c) 1982, Fred Fish *
- * All Rights Reserved *
- * *
- * This software and/or documentation is released for public *
- * distribution for personal, non-commercial use only. *
- * Limited rights to use, modify, and redistribute are hereby *
- * granted for non-commercial purposes, provided that all *
- * copyright notices remain intact and all changes are clearly *
- * documented. The author makes no warranty of any kind with *
- * respect to this product and explicitly disclaims any implied *
- * warranties of merchantability or fitness for any particular *
- * purpose. *
- * *
- ************************************************************************
- */
-
-
- /*
- * FILE
- *
- * dex1.c dynamic reconfiguration functions
- *
- * KEY WORDS
- *
- * dex files
- * dex
- *
- * DESCRIPTION
- *
- * This file contains functions for doing dynamic
- * reconfiguration. DEX automatically searches
- * a directory for a reconfiguration file the first
- * time any file in that directory is processed.
- * The default reconfiguration file is ".dexrc" but
- * can be changed to any desired file via a command
- * line switch.
- *
- * FUNCTIONS
- *
- * make_entry make an entry in the name table
- * reconfig do dynamic reconfiguration
- * rc_name build reconfiguration name
- * do_reconfig process open reconfiguration file
- * do_flags process reconfiguration ".flags" line
- * file_out process reconfiguration ".output" line
- *
- * AUTHOR
- *
- * Fred Fish
- *
- */
-
- #include <stdio.h>
- #include "hashtbl.h"
- #include "dex.h"
-
- extern int debug; /* Global debug flag */
- extern int vflag; /* Global verbose flag */
- extern char *get_memory ();
-
- static struct flgwrd { /* Reconfiguration flags */
- char *word; /* String form of flag */
- int flag; /* Token form of flag */
- };
-
- static struct flgwrd flgwrds[] = { /* Flags recognized */
- "PROCESS", PROCESS,
- "EMITTEXT", EMITTEXT,
- "EMITBOX", EMITBOX,
- "EMITFILL", EMITFILL,
- "EMITUL", EMITUL,
- "EMITBP", EMITBP,
- "REGION", REGION,
- NULL, NULL /* Marks end of flags list */
- };
-
- /*
- * FUNCTION
- *
- * make_entry make an entry in table with specified name
- *
- * KEY WORDS
- *
- * hash table insertion
- *
- * SYNOPSIS
- *
- * struct tbl_data *make_entry(name)
- * char *name;
- *
- * DESCRIPTION
- *
- * Make_entry allocates memory for a table entry, initializes
- * it's name field, and then adds it to the hash table.
- * Each entry name is actually the string which is recognized
- * as starting a new documentation section, such as
- * "FUNCTION" or "DESCRIPTION".
- *
- * Note that make_entry allocates fresh memory for the name
- * string, and copies the name there. This insures that the
- * characters comprising the entry's name do not vanish
- * when somebody's stack is popped.
- *
- */
-
- /*
- * PSEUDO CODE
- *
- * Begin make_entry
- * Initialize entry pointer to NULL.
- * If name pointer is not invalid then
- * Get memory for the entry name.
- * If memory was allocated then
- * Copy the name to the fresh memory.
- * Get memory for the table data structure.
- * If memory was allocated then
- * Remember the name of the entry.
- * Add entry to table, getting pointer.
- * End if
- * End if
- * End if
- * Return table entry pointer.
- * End make_entry
- *
- */
-
- static struct tbl_data *make_entry(name)
- char *name;
- {
- struct tbl_data *temp, *tbl_add();
- char *name_save;
-
- temp = NULL;
- if (name != NULL) {
- name_save = (char *) get_memory(strlen(name)+1);
- if (name_save != NULL) {
- strcpy(name_save,name);
- temp = (struct tbl_data *) get_memory(sizeof(struct tbl_data));
- if (temp != NULL) {
- temp->name = name_save;
- temp = tbl_add(temp);
- if (debug) {printf("make_entry: added \"%s\"\n",temp->name);}
- }
- }
- }
- return(temp);
- }
-
- /*
- * FUNCTION
- *
- * reconfig do dynamic reconfiguration if necessary
- *
- * KEY WORDS
- *
- * dynamic reconfiguration
- * reconfiguration routines
- *
- * SYNOPSIS
- *
- * reconfig(pfn,rcfn)
- * char *pfn; (processed file name)
- * char *rcfn; (rc file base name)
- *
- * DESCRIPTION
- *
- * Tests to see if a new reconfiguration file needs to
- * be processed and if so, opens it and calls routine
- * to actually do the reconfiguration.
- *
- */
-
- /*
- * PSEUDO CODE
- *
- * Begin reconfig
- * Build reconfiguration file name.
- * If name is not same as last used name then
- * If the reconfiguration file can be opened
- * Do the reconfiguration.
- * Remember name of reconfig file.
- * Close the reconfiguration file.
- * End if
- * End if
- * End reconfig
- *
- */
-
- static char last_rcfile[MAXNAMESIZE];
-
- reconfig(pfn,rcfn)
- char *pfn;
- char *rcfn;
- {
- char buffer[MAXNAMESIZE];
- FILE *rcfp, *fopen();
-
- rc_name(buffer,pfn,rcfn);
- if (debug) {printf("reconfig: %s & %s => %s\n",pfn,rcfn,buffer);}
- if (strcmp(buffer,last_rcfile) != 0) {
- if ((rcfp = fopen(buffer,"r")) != NULL) {
- if (vflag) {printf("dex: reconfiguring using \"%s\"\n",buffer);}
- do_reconfig(rcfp);
- strcpy(last_rcfile,buffer);
- fclose(rcfp);
- }
- }
- }
-
- /*
- * FUNCTION
- *
- * rc_name build the reconfiguration file name
- *
- * KEY WORDS
- *
- * dynamic reconfiguration
- * reconfiguration file
- *
- * SYNOPSIS
- *
- * static rc_name(out,pfn,rcfn)
- * char *out; (output goes here)
- * char *pfn; (processed file name)
- * char *rcfn; (rc base file name)
- *
- * DESCRIPTION
- *
- * Builds the name used when an attempt is made to open
- * the reconfiguration file. Assumes that if the specified
- * base reconfiguration file name does not contain a slash character
- * "/" then any prefix in the processed file name is to be
- * extracted and prepended to the specified base reconfiguration
- * file name.
- *
- * For example, if the processed file name is "/usr/me/myfile"
- * and the base reconfiguration file name is
- * ".dexrc" then the name used to open the reconfiguration
- * file will be "/usr/me/.dexrc".
- * If however the base reconfiguration file name is
- * "/usr/me/newrc" then this name will simply be
- * returned unchanged
- *
- * This seems to be the best way of handling reconfiguration
- * file names since if the full pathname is given then
- * only that file will be used regardless of where the
- * processed file is. However a generic name may be
- * given (such as ".dexrc") in which case a search will
- * be made in the processed file's directory for a file
- * with that generic name.
- *
- */
-
- /*
- * PSEUDO CODE
- *
- * Begin rc_name
- * If the specified base rc file name contains "/"
- * Copy that name to output.
- * Else
- * Copy processed file name to work buffer.
- * If processed file name has no last "/" in it then
- * Simply copy base rc file name to output.
- * Else
- * Append base rc file name after last "/"
- * Copy concatenated names to output.
- * End if
- * End if
- * End rc_name
- *
- */
-
- static rc_name(out,pfn,rcfn)
- char *out; /* Pointer to output place */
- char *pfn; /* Pointer to processed file name */
- char *rcfn; /* Pointer to reconfig base file name */
- {
- char buffer[MAXNAMESIZE]; /* Concatenation work buffer */
- char *cp; /* Work pointer for name build */
- char *rindex(); /* Pointer to last occurrence of char */
-
- if (index(rcfn,'/') != NULL) {
- strcpy(out,rcfn);
- } else {
- strcpy(buffer,pfn);
- cp = rindex(buffer,'/');
- if (cp == NULL) {
- strcpy(out,rcfn);
- } else {
- strcpy(++cp,rcfn);
- strcpy(out,buffer);
- }
- }
- }
-
- /*
- * FUNCTION
- *
- * do_reconfig process open reconfiguration file
- *
- * KEY WORDS
- *
- * dynamic reconfiguration
- * reconfiguration routines
- *
- * SYNOPSIS
- *
- * do_reconfig(rcfp)
- * FILE *rcfp;
- *
- * DESCRIPTION
- *
- * Reads each record from the currently open reconfiguration
- * file, creating table entries if necessary, and adding
- * the reconfiguration information to the specified table
- * entries.
- *
- */
-
- /*
- * PSEUDO CODE
- *
- * Begin do_reconfig
- * While a record can be read from reconfiguration file
- * Zap the newline at the end.
- * Skip over any leading whitespace.
- * If the line has something useful then
- * Extract the option field.
- * Skip to start of next field.
- * If the option is to process flags then
- * Process all flags on the line.
- * Else if option is change output file
- * Change name of output file.
- * Else
- * Print warning message.
- * End if
- * End if
- * End while
- * End do_reconfig
- *
- */
-
- do_reconfig(rcfp)
- FILE *rcfp;
- {
- char buffer[256];
- char string[128];
- char *cp, *skpbt(), *xfield();
-
- while (fgets(buffer,sizeof(buffer),rcfp) != NULL) {
- buffer[strlen(buffer)-1] = NULL;
- cp = skpbt(buffer);
- if (*cp != '#' && *cp != NULL && *cp != '\014') {
- cp = xfield(string,cp);
- cp = skpbt(cp);
- if (strcmp(string,".flags") == 0) {
- do_flags(cp);
- } else if (strcmp(string,".output") == 0) {
- file_out(cp);
- } else {
- fprintf(stdout,"dex: \"%s\" reconfiguration action?\n",string);
- }
- }
- }
- }
-
- /*
- * FUNCTION
- *
- * do_flags process flags for specified section
- *
- * KEY WORDS
- *
- * dynamic reconfiguration
- * flags
- *
- * SYNOPSIS
- *
- * do_flags(flags_line)
- * char *flags_line;
- *
- * DESCRIPTION
- *
- * Processes all flags for the current section, setting
- * or resetting those specified. Flags not specified are
- * unchanged from the default (reset).
- *
- * Flags may begin with an explicit action character
- * "-" or "+" for reset or set respectively. The
- * default is to set the named flag.
- *
- */
-
- /*
- * PSEUDO CODE
- *
- * Begin do_flags
- * If the passed pointer is not invalid then
- * If there is a line to process then
- * Extract the name of the section.
- * Skip to next field (first flag).
- * If the section is not in table
- * Create a new table entry.
- * End if
- * While there is a flag field left
- * Extract flag field.
- * Skip to next field.
- * Init flag field pointer.
- * If explicit state character
- * Skip over it.
- * End if
- * For each entry in flags list
- * If entry matches flag string
- * If reset requested
- * Reset flag.
- * Else
- * Set flag.
- * End if
- * Break for loop
- * End if
- * End for
- * End while
- * End if
- * End if
- * End do_flags
- *
- */
-
- static do_flags(cp)
- char *cp;
- {
- char string[128];
- char *xfield(), *skpbt();
- struct tbl_data *rp, *make_entry(), *tbl_find();
- struct flgwrd *flagp;
- char *stp;
-
- if (cp != NULL) {
- if (*cp != NULL) {
- cp = xfield(string,cp);
- cp = skpbt(cp);
- if (debug) {printf("do_flags: region \"%s\"\n",string);}
- if ((rp = tbl_find(string)) == NULL) {
- rp = make_entry(string);
- }
- while (*cp != NULL) {
- cp = xfield(string,cp);
- cp = skpbt(cp);
- if (debug) {printf("do_flags: got flag \"%s\"\n",string);}
- stp = string;
- if (*stp == '-' || *stp == '+') {
- stp++;
- }
- for (flagp = flgwrds; flagp->word != NULL; flagp++) {
- if (strcmp(flagp->word,stp) == 0) {
- if (string[0] == '-') {
- rp->flags &= ~(flagp->flag);
- } else {
- rp->flags |= flagp->flag;
- }
- break;
- }
- }
- }
- }
- }
- }
-
- /*
- * FUNCTION
- *
- * file_out reconfigure for new output file
- *
- * KEY WORDS
- *
- * dynamic reconfiguration
- * output file
- *
- * SYNOPSIS
- *
- * file_out(file_line)
- * char *file_line;
- *
- * DESCRIPTION
- *
- * Saves file name for output collection when specified
- * section is processed. Note that the name must
- * be stuffed safely away in static memory since
- * it will go away when one of this routines ancestors
- * exits.
- *
- */
-
- /*
- * PSEUDO CODE
- *
- * Begin file_out
- * If passed pointer is not invalid then
- * If there is a line to use then
- * Extract name of section.
- * Skip to file name field.
- * If section is not in table
- * Create a new table entry.
- * End if
- * Extract name of file.
- * Allocate some static memory.
- * Save the name in static memory.
- * Remember where it is.
- * End if
- * End if
- * End file_out
- *
- */
-
- file_out(cp)
- char *cp;
- {
- char string[128];
- char *xfield(), *skpbt();
- struct tbl_data *rp, *make_entry(), *tbl_find();
- char *file_save;
-
- if (cp != NULL) {
- if (*cp != NULL) {
- cp = xfield(string,cp);
- cp = skpbt(cp);
- if ((rp = tbl_find(string)) == NULL) {
- rp = make_entry(string);
- }
- cp = xfield(string,cp);
- file_save = (char *) get_memory(strlen(string)+1);
- strcpy(file_save,string);
- rp->out = file_save;
- if (debug) {printf("file_out: out file \"%s\"\n",rp->out);}
- }
- }
- }
-