Annotation of coherent/g/usr/bin/me/helplib.c, revision 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.