[BACK]Return to tag.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / mandoc

Annotation of src/usr.bin/mandoc/tag.c, Revision 1.1

1.1     ! schwarze    1: /*      $OpenBSD$    */
        !             2: /*
        !             3:  * Copyright (c) 2015 Ingo Schwarze <schwarze@openbsd.org>
        !             4:  *
        !             5:  * Permission to use, copy, modify, and distribute this software for any
        !             6:  * purpose with or without fee is hereby granted, provided that the above
        !             7:  * copyright notice and this permission notice appear in all copies.
        !             8:  *
        !             9:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
        !            10:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
        !            11:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
        !            12:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
        !            13:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
        !            14:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
        !            15:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
        !            16:  */
        !            17: #include <sys/types.h>
        !            18:
        !            19: #include <stddef.h>
        !            20: #include <stdio.h>
        !            21: #include <stdlib.h>
        !            22: #include <string.h>
        !            23: #include <unistd.h>
        !            24:
        !            25: #include <ohash.h>
        !            26:
        !            27: #include "mandoc_aux.h"
        !            28: #include "tag.h"
        !            29:
        !            30: struct tag_entry {
        !            31:        size_t   line;
        !            32:        char     s[];
        !            33: };
        !            34:
        !            35: static void    *tag_alloc(size_t, void *);
        !            36: static void     tag_free(void *, void *);
        !            37: static void    *tag_calloc(size_t, size_t, void *);
        !            38:
        !            39: static struct ohash     tag_data;
        !            40: static char            *tag_fn = NULL;
        !            41: static int              tag_fd = -1;
        !            42:
        !            43:
        !            44: /*
        !            45:  * Set up the ohash table to collect output line numbers
        !            46:  * where various marked-up terms are documented and create
        !            47:  * the temporary tags file, saving the name for the pager.
        !            48:  */
        !            49: void
        !            50: tag_init(void)
        !            51: {
        !            52:        struct ohash_info        tag_info;
        !            53:
        !            54:        tag_fn = mandoc_strdup("/tmp/man.XXXXXXXXXX");
        !            55:        if ((tag_fd = mkstemp(tag_fn)) == -1) {
        !            56:                free(tag_fn);
        !            57:                tag_fn = NULL;
        !            58:                return;
        !            59:        }
        !            60:
        !            61:        tag_info.alloc = tag_alloc;
        !            62:        tag_info.calloc = tag_calloc;
        !            63:        tag_info.free = tag_free;
        !            64:        tag_info.key_offset = offsetof(struct tag_entry, s);
        !            65:        tag_info.data = NULL;
        !            66:        ohash_init(&tag_data, 4, &tag_info);
        !            67: }
        !            68:
        !            69: char *
        !            70: tag_filename(void)
        !            71: {
        !            72:
        !            73:        return(tag_fn);
        !            74: }
        !            75:
        !            76: /*
        !            77:  * Return the line number where a term is defined,
        !            78:  * or 0 if the term is unknown.
        !            79:  */
        !            80: size_t
        !            81: tag_get(const char *s, size_t len)
        !            82: {
        !            83:        struct tag_entry        *entry;
        !            84:        const char              *end;
        !            85:        unsigned int             slot;
        !            86:
        !            87:        if (tag_fd == -1)
        !            88:                return(0);
        !            89:        if (len == 0)
        !            90:                len = strlen(s);
        !            91:        end = s + len;
        !            92:        slot = ohash_qlookupi(&tag_data, s, &end);
        !            93:        entry = ohash_find(&tag_data, slot);
        !            94:        return(entry == NULL ? 0 : entry->line);
        !            95: }
        !            96:
        !            97: /*
        !            98:  * Set the line number where a term is defined.
        !            99:  */
        !           100: void
        !           101: tag_put(const char *s, size_t len, size_t line)
        !           102: {
        !           103:        struct tag_entry        *entry;
        !           104:        const char              *end;
        !           105:        unsigned int             slot;
        !           106:
        !           107:        if (tag_fd == -1)
        !           108:                return;
        !           109:        if (len == 0)
        !           110:                len = strlen(s);
        !           111:        end = s + len;
        !           112:        slot = ohash_qlookupi(&tag_data, s, &end);
        !           113:        entry = ohash_find(&tag_data, slot);
        !           114:        if (entry == NULL) {
        !           115:                entry = mandoc_malloc(sizeof(*entry) + len + 1);
        !           116:                memcpy(entry->s, s, len);
        !           117:                entry->s[len] = '\0';
        !           118:                ohash_insert(&tag_data, slot, entry);
        !           119:        }
        !           120:        entry->line = line;
        !           121: }
        !           122:
        !           123: /*
        !           124:  * Write out the tags file using the previously collected
        !           125:  * information and clear the ohash table while going along.
        !           126:  */
        !           127: void
        !           128: tag_write(void)
        !           129: {
        !           130:        FILE                    *stream;
        !           131:        struct tag_entry        *entry;
        !           132:        unsigned int             slot;
        !           133:
        !           134:        if (tag_fd == -1)
        !           135:                return;
        !           136:        stream = fdopen(tag_fd, "w");
        !           137:        entry = ohash_first(&tag_data, &slot);
        !           138:        while (entry != NULL) {
        !           139:                if (stream != NULL)
        !           140:                        fprintf(stream, "%s - %zu\n", entry->s, entry->line);
        !           141:                free(entry);
        !           142:                entry = ohash_next(&tag_data, &slot);
        !           143:        }
        !           144:        ohash_delete(&tag_data);
        !           145:        if (stream != NULL)
        !           146:                fclose(stream);
        !           147: }
        !           148:
        !           149: void
        !           150: tag_unlink(void)
        !           151: {
        !           152:
        !           153:        if (tag_fn != NULL)
        !           154:                unlink(tag_fn);
        !           155: }
        !           156:
        !           157: /*
        !           158:  * Memory management callback functions for ohash.
        !           159:  */
        !           160: static void *
        !           161: tag_alloc(size_t sz, void *arg)
        !           162: {
        !           163:
        !           164:        return(mandoc_malloc(sz));
        !           165: }
        !           166:
        !           167: static void *
        !           168: tag_calloc(size_t nmemb, size_t sz, void *arg)
        !           169: {
        !           170:
        !           171:        return(mandoc_calloc(nmemb, sz));
        !           172: }
        !           173:
        !           174: static void
        !           175: tag_free(void *p, void *arg)
        !           176: {
        !           177:
        !           178:        free(p);
        !           179: }