Annotation of coherent/g/usr/bin/me/helplib.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * This is a library module for help file subject lookup.  There are
                      3:  * three externally available functions and two externally available
                      4:  * pointers.
                      5:  *
                      6:  * The two externally available pointers must be defined and given a
                      7:  * value by the program that calls this module, and are
                      8:  *     char *helpfile;         The name of the help file
                      9:  *     char *helpindex;        The name of the help index file
                     10:  *
                     11:  * The functions that are available are:
                     12:  *
                     13:  *     char *name_gen(basename, pathvar, defpath) char *basename, *pathvar;
                     14:  *             Returns the full name (including path info) of the
                     15:  *             file "basename" looked up on pathvar, if found or
                     16:  *             defpath.  The name is returned in a malloc'ed chunk
                     17:  *             of memory which should be free'd when you are done
                     18:  *             with it.  Returns NULL on failure.
                     19:  *
                     20:  *     int help(topic, output) char *topic; int (*output)();
                     21:  *             Lookup the topic and call output with each line of it.
                     22:  *             Returns 1 if the topic could not be found, -1 if the
                     23:  *             file could not be accessed.
                     24:  *
                     25:  *     int helpclose();
                     26:  *             Close help files and clean up the rest of the world.
                     27:  *
                     28:  */
                     29: #include <stdio.h>
                     30: #include <sys/stat.h>
                     31: #include <path.h>
                     32: #include "ed.h"
                     33: 
                     34: #define PATHSIZE 64                    /* Longest path name    */
                     35: 
                     36: #if    GEMDOS
                     37: #define        DEFHELPATH      DEFLIBPATH
                     38: #endif
                     39: 
                     40: #if    MSDOS
                     41: #define        DEFHELPATH      DEFLIBPATH
                     42: #endif
                     43: 
                     44: #ifdef COHERENT
                     45: #define        DEFHELPATH      ".:/usr/lib:/etc:/lib:"
                     46: #endif
                     47: 
                     48: #ifndef        HELPSEP
                     49: #define        HELPSEP '@'                     /* marks a new help entry */
                     50: #endif
                     51: 
                     52: extern uchar   *helpfile;              /* Help file name       */
                     53: extern uchar   *helpindex;             /* Help file index      */
                     54: 
                     55: static FILE    *helpfp;                /* Our helpfile         */
                     56: static uchar   *helpline;              /* Our help buffer      */
                     57: 
                     58: /*
                     59:  * Structure to speed lookup time.
                     60:  */
                     61: struct look    {
                     62:        long    l_seek;
                     63:        uchar   *l_name;
                     64: };
                     65: 
                     66: struct look    *lread();
                     67: 
                     68: uchar  *getenv();
                     69: char   *path();
                     70: 
                     71: /*
                     72:  * Create a file name from a basename and an environment variable.
                     73:  */
                     74: uchar *
                     75: name_gen(name, pathvar, defpath)
                     76: register uchar *name;
                     77: uchar  *pathvar;
                     78: uchar  *defpath;
                     79: {
                     80:        register uchar *fullname;
                     81:        register uchar *libpath;
                     82: 
                     83:        if ((fullname = (char *)malloc(PATHSIZE)) == NULL)
                     84:                return NULL;
                     85:        if ((libpath = getenv(pathvar)) == NULL)
                     86:                libpath = defpath;
                     87:        if ((libpath = path(libpath, name, AREAD)) == NULL)
                     88:                strcpy(fullname, name);
                     89:        else
                     90:                strcpy(fullname, libpath);
                     91:        return fullname;
                     92: }
                     93: 
                     94: /*
                     95:  * Get name of flex bind file.
                     96:  */
                     97: uchar *
                     98: flexName()
                     99: {
                    100: #ifdef COHERENT
                    101:        return (name_gen(".emacs.rc", "HOME", DEFHELPATH));
                    102: #else
                    103:        return (name_gen("emacs.rc", "LIBPATH", DEFHELPATH));
                    104: #endif
                    105: }
                    106: 
                    107: /* Open the help file "name" with access "acs" along the current
                    108:  * libpath.
                    109:  */
                    110: static FILE *
                    111: hfopen(name, acs)
                    112: uchar *name;
                    113: uchar *acs;
                    114: {
                    115:        uchar *fullname;
                    116:        FILE *fp = NULL;
                    117: 
                    118:        if ((fullname = name_gen(name, "LIBPATH", DEFHELPATH)) == NULL)
                    119:                return NULL;            /* Can't get full name  */
                    120:        fp = fopen(fullname, acs);      /* Open the file.       */
                    121:        mlwrite(fullname);
                    122:        free(fullname);                 /* Free the namebuffer  */
                    123:        return fp;                      /* return the file ptr  */
                    124: }
                    125: 
                    126: /*
                    127:  * Get the "stat" of the help file...
                    128:  */
                    129: static hstat(name, sb)
                    130: uchar *name;
                    131: struct stat *sb;
                    132: {
                    133:        uchar *fullname;
                    134:        register int s;
                    135: 
                    136:        if ((fullname = name_gen(name, "LIBPATH", DEFHELPATH)) == NULL)
                    137:                return -1;      /* could not get the name       */
                    138:        s = stat(fullname, sb); /* stat the file.               */
                    139:        free(fullname);
                    140:        return s;
                    141: }
                    142: 
                    143: helpclose() {
                    144:        if (helpfp != NULL)
                    145:                fclose(helpfp);
                    146:        if (helpline != NULL)
                    147:                free(helpline);
                    148:        helpfp = helpline = NULL;
                    149: }
                    150: 
                    151: /*
                    152:  * program interface to the help file. open file(s) as needed.
                    153:  * subsequent calls will not need to search and open them
                    154:  * again -- output function takes a string arg and does something
                    155:  * with it.  Non-zero return means no help found.
                    156:  */
                    157: help(topic, output)
                    158: uchar *topic;
                    159: int (*output)();
                    160: {
                    161:        if (helpfp == NULL)
                    162:                if ((helpfp = hfopen(helpfile, "r")) == NULL)
                    163:                        return -1;
                    164:        if (helpline == NULL)
                    165:                if ((helpline = malloc(NLINE)) == NULL)
                    166:                        return -1;
                    167:        return (lookup(topic, helpfp, helpindex, output));
                    168: }
                    169: 
                    170: /*
                    171:  * Make an index of help for a given topic.
                    172:  * Non-zero return means no topics found.
                    173:  */
                    174: indexhelp(topic, output)
                    175: uchar *topic;
                    176: int (*output)();
                    177: {
                    178:        if (helpfp == NULL)
                    179:                if ((helpfp = hfopen(helpfile, "r")) == NULL)
                    180:                        return -1;
                    181:        if (helpline == NULL)
                    182:                if ((helpline = malloc(NLINE)) == NULL)
                    183:                        return -1;
                    184:        return (doindex(topic, helpfp, output));
                    185: }
                    186: 
                    187: /*
                    188:  * Lookup a command in the given file.
                    189:  * The format is to look for HELPSEP (@) lines.
                    190:  * The optional index-file is provided to speed up
                    191:  * the lookup in situations where there is a very
                    192:  * large system help file.
                    193:  */
                    194: static lookup(com, fp, ind, output)
                    195: register uchar *com;
                    196: FILE *fp;
                    197: uchar *ind;
                    198: int (*output)();
                    199: {
                    200:        if (fp == NULL)
                    201:                return (1);
                    202:        fseek(fp, 0L, 0);
                    203:        fastlook(com, fp, ind);
                    204:        while (fgets(helpline, NLINE, fp) != NULL)
                    205:                if (helpline[0] == HELPSEP) {
                    206:                        helpline[strlen(helpline)-1] = '\0';
                    207:                        if (strcmp(com, helpline+1) == 0) {
                    208:                                while (fgets(helpline, NLINE, fp) != NULL) {
                    209:                                        if (helpline[0] == HELPSEP)
                    210:                                                break;
                    211:                                        helpline[strlen(helpline)-1] = '\0';
                    212:                                        (*output)(helpline);
                    213:                                }
                    214:                                return (0);
                    215:                        }
                    216:                }
                    217:        return (1);
                    218: }
                    219: 
                    220: /*
                    221:  * Possibly seek the helpfile to the right place based on an index file.
                    222:  * Return non-zero only when it is impossible to find it.
                    223:  */
                    224: static fastlook(com, fp, ind)
                    225: uchar *com;
                    226: FILE *fp;
                    227: uchar *ind;
                    228: {
                    229:        register struct look *lp;
                    230:        FILE *ifp;
                    231:        static struct stat sb;
                    232: #if !MSDOS
                    233:        long htime;
                    234: 
                    235:        fstat(fileno(fp), &sb);
                    236:        htime = sb.st_mtime;
                    237: #endif
                    238:        if (ind == NULL)                        /* No index file?       */
                    239:                return;
                    240:        if (hstat(ind, &sb) < 0)                /* not found ? */
                    241:                return;
                    242: #if !MSDOS
                    243:        if (htime < sb.st_mtime) {
                    244: #endif
                    245:                if ((ifp = hfopen(ind, "rb")) == NULL)
                    246:                        return;
                    247:                while ((lp = lread(ifp)) != NULL)
                    248:                        if (strcmp(com, lp->l_name) == 0) {
                    249:                                fseek(fp, lp->l_seek, 0);
                    250:                                break;
                    251:                        }
                    252:                fclose(ifp);
                    253: #if !MSDOS
                    254:        }
                    255: #endif
                    256:        return;
                    257: }
                    258: 
                    259: /*
                    260:  * Read in a look structure.  Return NULL
                    261:  * on end of file or error.
                    262:  */
                    263: static struct look *
                    264: lread(fp)
                    265: register FILE *fp;
                    266: {
                    267:        register uchar *cp;
                    268:        register int c;
                    269:        static struct look look;
                    270:        static uchar name[50];
                    271: 
                    272:        look.l_name = name;
                    273:        if (fread(&look.l_seek, sizeof look.l_seek, 1, fp) != 1)
                    274:                return (NULL);
                    275:        for (cp = name; cp<&name[49]; cp++) {
                    276:                if ((c = getc(fp)) == EOF)
                    277:                        return (NULL);
                    278:                *cp = c;
                    279:                if (c == '\0')
                    280:                        break;
                    281:        }
                    282:        return (&look);
                    283: }
                    284: 
                    285: /* Return 0 if s1 found in s2 */
                    286: static subcmp(s1, s2)
                    287: uchar *s1;
                    288: register uchar *s2;
                    289: {
                    290:        register uchar *st;
                    291:        register uchar *se;
                    292: 
                    293:        st = s1;
                    294:        for (;;) {
                    295:                while (*st != *s2++)
                    296:                        if (*s2 == '\0')
                    297:                                return 1;
                    298:                if (*st++ == '\0')
                    299:                        return 0;
                    300:                se = s2;
                    301:                while (*st++ == *se++) {
                    302:                        if (*st == '\0')
                    303:                                return 0;
                    304:                        if (*se == '\0')
                    305:                                return 1;
                    306:                }
                    307:                st = s1;
                    308:        }
                    309: }
                    310: 
                    311: static int doindex(com, fp, output)
                    312: register uchar *com;
                    313: FILE *fp;
                    314: int (*output)();
                    315: {
                    316:        register int t = 0;
                    317: 
                    318:        if (fp == NULL)
                    319:                return (1);
                    320:        fseek(fp, 0L, 0);
                    321:        while (fgets(helpline, NLINE, fp) != NULL) {
                    322:                if (helpline[0] == HELPSEP) {
                    323:                        helpline[strlen(helpline)-1] = '\0';
                    324:                        if (subcmp(com, helpline+1) == 0) {
                    325:                                if (fgets(helpline, NLINE, fp) == NULL)
                    326:                                        return t == 0;
                    327:                                helpline[strlen(helpline)-1] = '\0';
                    328:                                (*output)(helpline);
                    329:                                t++;
                    330:                        }
                    331:                }
                    332:        }
                    333:        if (t == 0)
                    334:                return 1;
                    335:        return 0;
                    336: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.