]>
git.cameronkatri.com Git - mandoc.git/blob - tag.c
1 /* $Id: tag.c,v 1.7 2015/08/29 15:28:13 schwarze Exp $ */
3 * Copyright (c) 2015 Ingo Schwarze <schwarze@openbsd.org>
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.
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.
19 #include <sys/types.h>
32 #include "compat_ohash.h"
35 #include "mandoc_aux.h"
44 static void tag_signal(int);
45 static void *tag_alloc(size_t, void *);
46 static void tag_free(void *, void *);
47 static void *tag_calloc(size_t, size_t, void *);
49 static struct ohash tag_data
;
50 static struct tag_files tag_files
;
54 * Prepare for using a pager.
55 * Not all pagers are capable of using a tag file,
56 * but for simplicity, create it anyway.
61 struct ohash_info tag_info
;
67 /* Save the original standard output for use by the pager. */
69 if ((tag_files
.ofd
= dup(STDOUT_FILENO
)) == -1)
72 /* Create both temporary output files. */
74 (void)strlcpy(tag_files
.ofn
, "/tmp/man.XXXXXXXXXX",
75 sizeof(tag_files
.ofn
));
76 (void)strlcpy(tag_files
.tfn
, "/tmp/man.XXXXXXXXXX",
77 sizeof(tag_files
.tfn
));
78 signal(SIGHUP
, tag_signal
);
79 signal(SIGINT
, tag_signal
);
80 signal(SIGTERM
, tag_signal
);
81 if ((ofd
= mkstemp(tag_files
.ofn
)) == -1)
83 if ((tag_files
.tfd
= mkstemp(tag_files
.tfn
)) == -1)
85 if (dup2(ofd
, STDOUT_FILENO
) == -1)
90 * Set up the ohash table to collect output line numbers
91 * where various marked-up terms are documented.
94 tag_info
.alloc
= tag_alloc
;
95 tag_info
.calloc
= tag_calloc
;
96 tag_info
.free
= tag_free
;
97 tag_info
.key_offset
= offsetof(struct tag_entry
, s
);
99 ohash_init(&tag_data
, 4, &tag_info
);
106 if (tag_files
.ofd
!= -1)
107 close(tag_files
.ofd
);
108 if (tag_files
.tfd
!= -1)
109 close(tag_files
.tfd
);
110 *tag_files
.ofn
= '\0';
111 *tag_files
.tfn
= '\0';
118 * Set the line number where a term is defined,
119 * unless it is already defined at a higher priority.
122 tag_put(const char *s
, int prio
, size_t line
)
124 struct tag_entry
*entry
;
128 if (tag_files
.tfd
<= 0)
130 slot
= ohash_qlookup(&tag_data
, s
);
131 entry
= ohash_find(&tag_data
, slot
);
134 entry
= mandoc_malloc(sizeof(*entry
) + len
);
135 memcpy(entry
->s
, s
, len
);
136 ohash_insert(&tag_data
, slot
, entry
);
137 } else if (entry
->prio
<= prio
)
144 * Write out the tags file using the previously collected
145 * information and clear the ohash table while going along.
151 struct tag_entry
*entry
;
154 if (tag_files
.tfd
<= 0)
156 stream
= fdopen(tag_files
.tfd
, "w");
157 entry
= ohash_first(&tag_data
, &slot
);
158 while (entry
!= NULL
) {
160 fprintf(stream
, "%s %s %zu\n",
161 entry
->s
, tag_files
.ofn
, entry
->line
);
163 entry
= ohash_next(&tag_data
, &slot
);
165 ohash_delete(&tag_data
);
174 if (*tag_files
.ofn
!= '\0')
175 unlink(tag_files
.ofn
);
176 if (*tag_files
.tfn
!= '\0')
177 unlink(tag_files
.tfn
);
181 tag_signal(int signum
)
185 signal(signum
, SIG_DFL
);
186 kill(getpid(), signum
);
192 * Memory management callback functions for ohash.
195 tag_alloc(size_t sz
, void *arg
)
198 return(mandoc_malloc(sz
));
202 tag_calloc(size_t nmemb
, size_t sz
, void *arg
)
205 return(mandoc_calloc(nmemb
, sz
));
209 tag_free(void *p
, void *arg
)