mandoc 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +7 -0
  3. data/COPYING +674 -0
  4. data/README.md +117 -0
  5. data/ext/mandoc/extconf.rb +59 -0
  6. data/ext/mandoc/rb_mandoc.c +548 -0
  7. data/ext/mandoc/rb_mandoc.h +22 -0
  8. data/lib/mandoc/version.rb +19 -0
  9. data/lib/mandoc.rb +26 -0
  10. data/mandoc-1.14.6/LICENSE +55 -0
  11. data/mandoc-1.14.6/arch.c +54 -0
  12. data/mandoc-1.14.6/att.c +49 -0
  13. data/mandoc-1.14.6/catman.c +260 -0
  14. data/mandoc-1.14.6/cgi.c +1279 -0
  15. data/mandoc-1.14.6/chars.c +507 -0
  16. data/mandoc-1.14.6/compat_err.c +103 -0
  17. data/mandoc-1.14.6/compat_fts.c +696 -0
  18. data/mandoc-1.14.6/compat_fts.h +106 -0
  19. data/mandoc-1.14.6/compat_getline.c +59 -0
  20. data/mandoc-1.14.6/compat_getsubopt.c +87 -0
  21. data/mandoc-1.14.6/compat_isblank.c +23 -0
  22. data/mandoc-1.14.6/compat_mkdtemp.c +50 -0
  23. data/mandoc-1.14.6/compat_mkstemps.c +63 -0
  24. data/mandoc-1.14.6/compat_ohash.c +330 -0
  25. data/mandoc-1.14.6/compat_ohash.h +72 -0
  26. data/mandoc-1.14.6/compat_progname.c +31 -0
  27. data/mandoc-1.14.6/compat_reallocarray.c +40 -0
  28. data/mandoc-1.14.6/compat_recallocarray.c +99 -0
  29. data/mandoc-1.14.6/compat_strcasestr.c +64 -0
  30. data/mandoc-1.14.6/compat_stringlist.c +135 -0
  31. data/mandoc-1.14.6/compat_stringlist.h +48 -0
  32. data/mandoc-1.14.6/compat_strlcat.c +57 -0
  33. data/mandoc-1.14.6/compat_strlcpy.c +52 -0
  34. data/mandoc-1.14.6/compat_strndup.c +42 -0
  35. data/mandoc-1.14.6/compat_strsep.c +70 -0
  36. data/mandoc-1.14.6/compat_strtonum.c +67 -0
  37. data/mandoc-1.14.6/compat_vasprintf.c +47 -0
  38. data/mandoc-1.14.6/config.h +52 -0
  39. data/mandoc-1.14.6/dba.c +508 -0
  40. data/mandoc-1.14.6/dba.h +50 -0
  41. data/mandoc-1.14.6/dba_array.c +190 -0
  42. data/mandoc-1.14.6/dba_array.h +47 -0
  43. data/mandoc-1.14.6/dba_read.c +74 -0
  44. data/mandoc-1.14.6/dba_write.c +127 -0
  45. data/mandoc-1.14.6/dba_write.h +30 -0
  46. data/mandoc-1.14.6/dbm.c +480 -0
  47. data/mandoc-1.14.6/dbm.h +68 -0
  48. data/mandoc-1.14.6/dbm_map.c +194 -0
  49. data/mandoc-1.14.6/dbm_map.h +29 -0
  50. data/mandoc-1.14.6/demandoc.c +260 -0
  51. data/mandoc-1.14.6/eqn.c +1132 -0
  52. data/mandoc-1.14.6/eqn.h +72 -0
  53. data/mandoc-1.14.6/eqn_html.c +246 -0
  54. data/mandoc-1.14.6/eqn_parse.h +48 -0
  55. data/mandoc-1.14.6/eqn_term.c +174 -0
  56. data/mandoc-1.14.6/html.c +1102 -0
  57. data/mandoc-1.14.6/html.h +142 -0
  58. data/mandoc-1.14.6/lib.c +35 -0
  59. data/mandoc-1.14.6/libman.h +42 -0
  60. data/mandoc-1.14.6/libmandoc.h +85 -0
  61. data/mandoc-1.14.6/libmdoc.h +87 -0
  62. data/mandoc-1.14.6/main.c +1375 -0
  63. data/mandoc-1.14.6/main.h +53 -0
  64. data/mandoc-1.14.6/man.c +345 -0
  65. data/mandoc-1.14.6/man.h +21 -0
  66. data/mandoc-1.14.6/man_html.c +640 -0
  67. data/mandoc-1.14.6/man_macro.c +470 -0
  68. data/mandoc-1.14.6/man_term.c +1143 -0
  69. data/mandoc-1.14.6/man_validate.c +660 -0
  70. data/mandoc-1.14.6/manconf.h +58 -0
  71. data/mandoc-1.14.6/mandoc.c +669 -0
  72. data/mandoc-1.14.6/mandoc.h +329 -0
  73. data/mandoc-1.14.6/mandoc_aux.c +118 -0
  74. data/mandoc-1.14.6/mandoc_aux.h +27 -0
  75. data/mandoc-1.14.6/mandoc_msg.c +375 -0
  76. data/mandoc-1.14.6/mandoc_ohash.c +65 -0
  77. data/mandoc-1.14.6/mandoc_ohash.h +23 -0
  78. data/mandoc-1.14.6/mandoc_parse.h +44 -0
  79. data/mandoc-1.14.6/mandoc_xr.c +123 -0
  80. data/mandoc-1.14.6/mandoc_xr.h +31 -0
  81. data/mandoc-1.14.6/mandocd.c +282 -0
  82. data/mandoc-1.14.6/mandocdb.c +2448 -0
  83. data/mandoc-1.14.6/manpath.c +363 -0
  84. data/mandoc-1.14.6/mansearch.c +851 -0
  85. data/mandoc-1.14.6/mansearch.h +118 -0
  86. data/mandoc-1.14.6/mdoc.c +433 -0
  87. data/mandoc-1.14.6/mdoc.h +158 -0
  88. data/mandoc-1.14.6/mdoc_argv.c +682 -0
  89. data/mandoc-1.14.6/mdoc_html.c +1762 -0
  90. data/mandoc-1.14.6/mdoc_macro.c +1600 -0
  91. data/mandoc-1.14.6/mdoc_man.c +1850 -0
  92. data/mandoc-1.14.6/mdoc_markdown.c +1610 -0
  93. data/mandoc-1.14.6/mdoc_state.c +256 -0
  94. data/mandoc-1.14.6/mdoc_term.c +1964 -0
  95. data/mandoc-1.14.6/mdoc_validate.c +3062 -0
  96. data/mandoc-1.14.6/msec.c +37 -0
  97. data/mandoc-1.14.6/out.c +544 -0
  98. data/mandoc-1.14.6/out.h +70 -0
  99. data/mandoc-1.14.6/preconv.c +179 -0
  100. data/mandoc-1.14.6/read.c +732 -0
  101. data/mandoc-1.14.6/roff.c +4390 -0
  102. data/mandoc-1.14.6/roff.h +561 -0
  103. data/mandoc-1.14.6/roff_html.c +119 -0
  104. data/mandoc-1.14.6/roff_int.h +94 -0
  105. data/mandoc-1.14.6/roff_term.c +266 -0
  106. data/mandoc-1.14.6/roff_validate.c +151 -0
  107. data/mandoc-1.14.6/soelim.c +182 -0
  108. data/mandoc-1.14.6/st.c +82 -0
  109. data/mandoc-1.14.6/tag.c +327 -0
  110. data/mandoc-1.14.6/tag.h +35 -0
  111. data/mandoc-1.14.6/tbl.c +183 -0
  112. data/mandoc-1.14.6/tbl.h +121 -0
  113. data/mandoc-1.14.6/tbl_data.c +323 -0
  114. data/mandoc-1.14.6/tbl_html.c +293 -0
  115. data/mandoc-1.14.6/tbl_int.h +47 -0
  116. data/mandoc-1.14.6/tbl_layout.c +376 -0
  117. data/mandoc-1.14.6/tbl_opts.c +173 -0
  118. data/mandoc-1.14.6/tbl_parse.h +30 -0
  119. data/mandoc-1.14.6/tbl_term.c +948 -0
  120. data/mandoc-1.14.6/term.c +1113 -0
  121. data/mandoc-1.14.6/term.h +158 -0
  122. data/mandoc-1.14.6/term_ascii.c +424 -0
  123. data/mandoc-1.14.6/term_ps.c +1362 -0
  124. data/mandoc-1.14.6/term_tab.c +130 -0
  125. data/mandoc-1.14.6/term_tag.c +227 -0
  126. data/mandoc-1.14.6/term_tag.h +34 -0
  127. data/mandoc-1.14.6/tree.c +536 -0
  128. metadata +170 -0
@@ -0,0 +1,682 @@
1
+ /* $Id: mdoc_argv.c,v 1.120 2019/07/11 17:06:17 schwarze Exp $ */
2
+ /*
3
+ * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
4
+ * Copyright (c) 2012, 2014-2019 Ingo Schwarze <schwarze@openbsd.org>
5
+ *
6
+ * Permission to use, copy, modify, and distribute this software for any
7
+ * purpose with or without fee is hereby granted, provided that the above
8
+ * copyright notice and this permission notice appear in all copies.
9
+ *
10
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
11
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
13
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
+ */
18
+ #include "config.h"
19
+
20
+ #include <sys/types.h>
21
+
22
+ #include <assert.h>
23
+ #include <stdlib.h>
24
+ #include <stdio.h>
25
+ #include <string.h>
26
+
27
+ #include "mandoc_aux.h"
28
+ #include "mandoc.h"
29
+ #include "roff.h"
30
+ #include "mdoc.h"
31
+ #include "libmandoc.h"
32
+ #include "roff_int.h"
33
+ #include "libmdoc.h"
34
+
35
+ #define MULTI_STEP 5 /* pre-allocate argument values */
36
+ #define DELIMSZ 6 /* max possible size of a delimiter */
37
+
38
+ enum argsflag {
39
+ ARGSFL_NONE = 0,
40
+ ARGSFL_DELIM, /* handle delimiters of [[::delim::][ ]+]+ */
41
+ ARGSFL_TABSEP /* handle tab/`Ta' separated phrases */
42
+ };
43
+
44
+ enum argvflag {
45
+ ARGV_NONE, /* no args to flag (e.g., -split) */
46
+ ARGV_SINGLE, /* one arg to flag (e.g., -file xxx) */
47
+ ARGV_MULTI /* multiple args (e.g., -column xxx yyy) */
48
+ };
49
+
50
+ struct mdocarg {
51
+ enum argsflag flags;
52
+ const enum mdocargt *argvs;
53
+ };
54
+
55
+ static void argn_free(struct mdoc_arg *, int);
56
+ static enum margserr args(struct roff_man *, int, int *,
57
+ char *, enum argsflag, char **);
58
+ static int args_checkpunct(const char *, int);
59
+ static void argv_multi(struct roff_man *, int,
60
+ struct mdoc_argv *, int *, char *);
61
+ static void argv_single(struct roff_man *, int,
62
+ struct mdoc_argv *, int *, char *);
63
+
64
+ static const enum argvflag argvflags[MDOC_ARG_MAX] = {
65
+ ARGV_NONE, /* MDOC_Split */
66
+ ARGV_NONE, /* MDOC_Nosplit */
67
+ ARGV_NONE, /* MDOC_Ragged */
68
+ ARGV_NONE, /* MDOC_Unfilled */
69
+ ARGV_NONE, /* MDOC_Literal */
70
+ ARGV_SINGLE, /* MDOC_File */
71
+ ARGV_SINGLE, /* MDOC_Offset */
72
+ ARGV_NONE, /* MDOC_Bullet */
73
+ ARGV_NONE, /* MDOC_Dash */
74
+ ARGV_NONE, /* MDOC_Hyphen */
75
+ ARGV_NONE, /* MDOC_Item */
76
+ ARGV_NONE, /* MDOC_Enum */
77
+ ARGV_NONE, /* MDOC_Tag */
78
+ ARGV_NONE, /* MDOC_Diag */
79
+ ARGV_NONE, /* MDOC_Hang */
80
+ ARGV_NONE, /* MDOC_Ohang */
81
+ ARGV_NONE, /* MDOC_Inset */
82
+ ARGV_MULTI, /* MDOC_Column */
83
+ ARGV_SINGLE, /* MDOC_Width */
84
+ ARGV_NONE, /* MDOC_Compact */
85
+ ARGV_NONE, /* MDOC_Std */
86
+ ARGV_NONE, /* MDOC_Filled */
87
+ ARGV_NONE, /* MDOC_Words */
88
+ ARGV_NONE, /* MDOC_Emphasis */
89
+ ARGV_NONE, /* MDOC_Symbolic */
90
+ ARGV_NONE /* MDOC_Symbolic */
91
+ };
92
+
93
+ static const enum mdocargt args_Ex[] = {
94
+ MDOC_Std,
95
+ MDOC_ARG_MAX
96
+ };
97
+
98
+ static const enum mdocargt args_An[] = {
99
+ MDOC_Split,
100
+ MDOC_Nosplit,
101
+ MDOC_ARG_MAX
102
+ };
103
+
104
+ static const enum mdocargt args_Bd[] = {
105
+ MDOC_Ragged,
106
+ MDOC_Unfilled,
107
+ MDOC_Filled,
108
+ MDOC_Literal,
109
+ MDOC_File,
110
+ MDOC_Offset,
111
+ MDOC_Compact,
112
+ MDOC_Centred,
113
+ MDOC_ARG_MAX
114
+ };
115
+
116
+ static const enum mdocargt args_Bf[] = {
117
+ MDOC_Emphasis,
118
+ MDOC_Literal,
119
+ MDOC_Symbolic,
120
+ MDOC_ARG_MAX
121
+ };
122
+
123
+ static const enum mdocargt args_Bk[] = {
124
+ MDOC_Words,
125
+ MDOC_ARG_MAX
126
+ };
127
+
128
+ static const enum mdocargt args_Bl[] = {
129
+ MDOC_Bullet,
130
+ MDOC_Dash,
131
+ MDOC_Hyphen,
132
+ MDOC_Item,
133
+ MDOC_Enum,
134
+ MDOC_Tag,
135
+ MDOC_Diag,
136
+ MDOC_Hang,
137
+ MDOC_Ohang,
138
+ MDOC_Inset,
139
+ MDOC_Column,
140
+ MDOC_Width,
141
+ MDOC_Offset,
142
+ MDOC_Compact,
143
+ MDOC_Nested,
144
+ MDOC_ARG_MAX
145
+ };
146
+
147
+ static const struct mdocarg mdocargs[MDOC_MAX - MDOC_Dd] = {
148
+ { ARGSFL_NONE, NULL }, /* Dd */
149
+ { ARGSFL_NONE, NULL }, /* Dt */
150
+ { ARGSFL_NONE, NULL }, /* Os */
151
+ { ARGSFL_NONE, NULL }, /* Sh */
152
+ { ARGSFL_NONE, NULL }, /* Ss */
153
+ { ARGSFL_NONE, NULL }, /* Pp */
154
+ { ARGSFL_DELIM, NULL }, /* D1 */
155
+ { ARGSFL_DELIM, NULL }, /* Dl */
156
+ { ARGSFL_NONE, args_Bd }, /* Bd */
157
+ { ARGSFL_NONE, NULL }, /* Ed */
158
+ { ARGSFL_NONE, args_Bl }, /* Bl */
159
+ { ARGSFL_NONE, NULL }, /* El */
160
+ { ARGSFL_NONE, NULL }, /* It */
161
+ { ARGSFL_DELIM, NULL }, /* Ad */
162
+ { ARGSFL_DELIM, args_An }, /* An */
163
+ { ARGSFL_DELIM, NULL }, /* Ap */
164
+ { ARGSFL_DELIM, NULL }, /* Ar */
165
+ { ARGSFL_DELIM, NULL }, /* Cd */
166
+ { ARGSFL_DELIM, NULL }, /* Cm */
167
+ { ARGSFL_DELIM, NULL }, /* Dv */
168
+ { ARGSFL_DELIM, NULL }, /* Er */
169
+ { ARGSFL_DELIM, NULL }, /* Ev */
170
+ { ARGSFL_NONE, args_Ex }, /* Ex */
171
+ { ARGSFL_DELIM, NULL }, /* Fa */
172
+ { ARGSFL_NONE, NULL }, /* Fd */
173
+ { ARGSFL_DELIM, NULL }, /* Fl */
174
+ { ARGSFL_DELIM, NULL }, /* Fn */
175
+ { ARGSFL_DELIM, NULL }, /* Ft */
176
+ { ARGSFL_DELIM, NULL }, /* Ic */
177
+ { ARGSFL_DELIM, NULL }, /* In */
178
+ { ARGSFL_DELIM, NULL }, /* Li */
179
+ { ARGSFL_NONE, NULL }, /* Nd */
180
+ { ARGSFL_DELIM, NULL }, /* Nm */
181
+ { ARGSFL_DELIM, NULL }, /* Op */
182
+ { ARGSFL_DELIM, NULL }, /* Ot */
183
+ { ARGSFL_DELIM, NULL }, /* Pa */
184
+ { ARGSFL_NONE, args_Ex }, /* Rv */
185
+ { ARGSFL_DELIM, NULL }, /* St */
186
+ { ARGSFL_DELIM, NULL }, /* Va */
187
+ { ARGSFL_DELIM, NULL }, /* Vt */
188
+ { ARGSFL_DELIM, NULL }, /* Xr */
189
+ { ARGSFL_NONE, NULL }, /* %A */
190
+ { ARGSFL_NONE, NULL }, /* %B */
191
+ { ARGSFL_NONE, NULL }, /* %D */
192
+ { ARGSFL_NONE, NULL }, /* %I */
193
+ { ARGSFL_NONE, NULL }, /* %J */
194
+ { ARGSFL_NONE, NULL }, /* %N */
195
+ { ARGSFL_NONE, NULL }, /* %O */
196
+ { ARGSFL_NONE, NULL }, /* %P */
197
+ { ARGSFL_NONE, NULL }, /* %R */
198
+ { ARGSFL_NONE, NULL }, /* %T */
199
+ { ARGSFL_NONE, NULL }, /* %V */
200
+ { ARGSFL_DELIM, NULL }, /* Ac */
201
+ { ARGSFL_NONE, NULL }, /* Ao */
202
+ { ARGSFL_DELIM, NULL }, /* Aq */
203
+ { ARGSFL_DELIM, NULL }, /* At */
204
+ { ARGSFL_DELIM, NULL }, /* Bc */
205
+ { ARGSFL_NONE, args_Bf }, /* Bf */
206
+ { ARGSFL_NONE, NULL }, /* Bo */
207
+ { ARGSFL_DELIM, NULL }, /* Bq */
208
+ { ARGSFL_DELIM, NULL }, /* Bsx */
209
+ { ARGSFL_DELIM, NULL }, /* Bx */
210
+ { ARGSFL_NONE, NULL }, /* Db */
211
+ { ARGSFL_DELIM, NULL }, /* Dc */
212
+ { ARGSFL_NONE, NULL }, /* Do */
213
+ { ARGSFL_DELIM, NULL }, /* Dq */
214
+ { ARGSFL_DELIM, NULL }, /* Ec */
215
+ { ARGSFL_NONE, NULL }, /* Ef */
216
+ { ARGSFL_DELIM, NULL }, /* Em */
217
+ { ARGSFL_NONE, NULL }, /* Eo */
218
+ { ARGSFL_DELIM, NULL }, /* Fx */
219
+ { ARGSFL_DELIM, NULL }, /* Ms */
220
+ { ARGSFL_DELIM, NULL }, /* No */
221
+ { ARGSFL_DELIM, NULL }, /* Ns */
222
+ { ARGSFL_DELIM, NULL }, /* Nx */
223
+ { ARGSFL_DELIM, NULL }, /* Ox */
224
+ { ARGSFL_DELIM, NULL }, /* Pc */
225
+ { ARGSFL_DELIM, NULL }, /* Pf */
226
+ { ARGSFL_NONE, NULL }, /* Po */
227
+ { ARGSFL_DELIM, NULL }, /* Pq */
228
+ { ARGSFL_DELIM, NULL }, /* Qc */
229
+ { ARGSFL_DELIM, NULL }, /* Ql */
230
+ { ARGSFL_NONE, NULL }, /* Qo */
231
+ { ARGSFL_DELIM, NULL }, /* Qq */
232
+ { ARGSFL_NONE, NULL }, /* Re */
233
+ { ARGSFL_NONE, NULL }, /* Rs */
234
+ { ARGSFL_DELIM, NULL }, /* Sc */
235
+ { ARGSFL_NONE, NULL }, /* So */
236
+ { ARGSFL_DELIM, NULL }, /* Sq */
237
+ { ARGSFL_NONE, NULL }, /* Sm */
238
+ { ARGSFL_DELIM, NULL }, /* Sx */
239
+ { ARGSFL_DELIM, NULL }, /* Sy */
240
+ { ARGSFL_DELIM, NULL }, /* Tn */
241
+ { ARGSFL_DELIM, NULL }, /* Ux */
242
+ { ARGSFL_DELIM, NULL }, /* Xc */
243
+ { ARGSFL_NONE, NULL }, /* Xo */
244
+ { ARGSFL_NONE, NULL }, /* Fo */
245
+ { ARGSFL_DELIM, NULL }, /* Fc */
246
+ { ARGSFL_NONE, NULL }, /* Oo */
247
+ { ARGSFL_DELIM, NULL }, /* Oc */
248
+ { ARGSFL_NONE, args_Bk }, /* Bk */
249
+ { ARGSFL_NONE, NULL }, /* Ek */
250
+ { ARGSFL_NONE, NULL }, /* Bt */
251
+ { ARGSFL_NONE, NULL }, /* Hf */
252
+ { ARGSFL_DELIM, NULL }, /* Fr */
253
+ { ARGSFL_NONE, NULL }, /* Ud */
254
+ { ARGSFL_DELIM, NULL }, /* Lb */
255
+ { ARGSFL_NONE, NULL }, /* Lp */
256
+ { ARGSFL_DELIM, NULL }, /* Lk */
257
+ { ARGSFL_DELIM, NULL }, /* Mt */
258
+ { ARGSFL_DELIM, NULL }, /* Brq */
259
+ { ARGSFL_NONE, NULL }, /* Bro */
260
+ { ARGSFL_DELIM, NULL }, /* Brc */
261
+ { ARGSFL_NONE, NULL }, /* %C */
262
+ { ARGSFL_NONE, NULL }, /* Es */
263
+ { ARGSFL_DELIM, NULL }, /* En */
264
+ { ARGSFL_DELIM, NULL }, /* Dx */
265
+ { ARGSFL_NONE, NULL }, /* %Q */
266
+ { ARGSFL_NONE, NULL }, /* %U */
267
+ { ARGSFL_NONE, NULL }, /* Ta */
268
+ };
269
+
270
+
271
+ /*
272
+ * Parse flags and their arguments from the input line.
273
+ * These come in the form -flag [argument ...].
274
+ * Some flags take no argument, some one, some multiple.
275
+ */
276
+ void
277
+ mdoc_argv(struct roff_man *mdoc, int line, enum roff_tok tok,
278
+ struct mdoc_arg **reta, int *pos, char *buf)
279
+ {
280
+ struct mdoc_argv tmpv;
281
+ struct mdoc_argv **retv;
282
+ const enum mdocargt *argtable;
283
+ char *argname;
284
+ int ipos, retc;
285
+ char savechar;
286
+
287
+ *reta = NULL;
288
+
289
+ /* Which flags does this macro support? */
290
+
291
+ assert(tok >= MDOC_Dd && tok < MDOC_MAX);
292
+ argtable = mdocargs[tok - MDOC_Dd].argvs;
293
+ if (argtable == NULL)
294
+ return;
295
+
296
+ /* Loop over the flags on the input line. */
297
+
298
+ ipos = *pos;
299
+ while (buf[ipos] == '-') {
300
+
301
+ /* Seek to the first unescaped space. */
302
+
303
+ for (argname = buf + ++ipos; buf[ipos] != '\0'; ipos++)
304
+ if (buf[ipos] == ' ' && buf[ipos - 1] != '\\')
305
+ break;
306
+
307
+ /*
308
+ * We want to nil-terminate the word to look it up.
309
+ * But we may not have a flag, in which case we need
310
+ * to restore the line as-is. So keep around the
311
+ * stray byte, which we'll reset upon exiting.
312
+ */
313
+
314
+ if ((savechar = buf[ipos]) != '\0')
315
+ buf[ipos++] = '\0';
316
+
317
+ /*
318
+ * Now look up the word as a flag. Use temporary
319
+ * storage that we'll copy into the node's flags.
320
+ */
321
+
322
+ while ((tmpv.arg = *argtable++) != MDOC_ARG_MAX)
323
+ if ( ! strcmp(argname, mdoc_argnames[tmpv.arg]))
324
+ break;
325
+
326
+ /* If it isn't a flag, restore the saved byte. */
327
+
328
+ if (tmpv.arg == MDOC_ARG_MAX) {
329
+ if (savechar != '\0')
330
+ buf[ipos - 1] = savechar;
331
+ break;
332
+ }
333
+
334
+ /* Read to the next word (the first argument). */
335
+
336
+ while (buf[ipos] == ' ')
337
+ ipos++;
338
+
339
+ /* Parse the arguments of the flag. */
340
+
341
+ tmpv.line = line;
342
+ tmpv.pos = *pos;
343
+ tmpv.sz = 0;
344
+ tmpv.value = NULL;
345
+
346
+ switch (argvflags[tmpv.arg]) {
347
+ case ARGV_SINGLE:
348
+ argv_single(mdoc, line, &tmpv, &ipos, buf);
349
+ break;
350
+ case ARGV_MULTI:
351
+ argv_multi(mdoc, line, &tmpv, &ipos, buf);
352
+ break;
353
+ case ARGV_NONE:
354
+ break;
355
+ }
356
+
357
+ /* Append to the return values. */
358
+
359
+ if (*reta == NULL)
360
+ *reta = mandoc_calloc(1, sizeof(**reta));
361
+
362
+ retc = ++(*reta)->argc;
363
+ retv = &(*reta)->argv;
364
+ *retv = mandoc_reallocarray(*retv, retc, sizeof(**retv));
365
+ memcpy(*retv + retc - 1, &tmpv, sizeof(**retv));
366
+
367
+ /* Prepare for parsing the next flag. */
368
+
369
+ *pos = ipos;
370
+ argtable = mdocargs[tok - MDOC_Dd].argvs;
371
+ }
372
+ }
373
+
374
+ void
375
+ mdoc_argv_free(struct mdoc_arg *p)
376
+ {
377
+ int i;
378
+
379
+ if (NULL == p)
380
+ return;
381
+
382
+ if (p->refcnt) {
383
+ --(p->refcnt);
384
+ if (p->refcnt)
385
+ return;
386
+ }
387
+ assert(p->argc);
388
+
389
+ for (i = (int)p->argc - 1; i >= 0; i--)
390
+ argn_free(p, i);
391
+
392
+ free(p->argv);
393
+ free(p);
394
+ }
395
+
396
+ static void
397
+ argn_free(struct mdoc_arg *p, int iarg)
398
+ {
399
+ struct mdoc_argv *arg;
400
+ int j;
401
+
402
+ arg = &p->argv[iarg];
403
+
404
+ if (arg->sz && arg->value) {
405
+ for (j = (int)arg->sz - 1; j >= 0; j--)
406
+ free(arg->value[j]);
407
+ free(arg->value);
408
+ }
409
+
410
+ for (--p->argc; iarg < (int)p->argc; iarg++)
411
+ p->argv[iarg] = p->argv[iarg+1];
412
+ }
413
+
414
+ enum margserr
415
+ mdoc_args(struct roff_man *mdoc, int line, int *pos,
416
+ char *buf, enum roff_tok tok, char **v)
417
+ {
418
+ struct roff_node *n;
419
+ enum argsflag fl;
420
+
421
+ fl = tok == TOKEN_NONE ? ARGSFL_NONE : mdocargs[tok - MDOC_Dd].flags;
422
+
423
+ /*
424
+ * We know that we're in an `It', so it's reasonable to expect
425
+ * us to be sitting in a `Bl'. Someday this may not be the case
426
+ * (if we allow random `It's sitting out there), so provide a
427
+ * safe fall-back into the default behaviour.
428
+ */
429
+
430
+ if (tok == MDOC_It) {
431
+ for (n = mdoc->last; n != NULL; n = n->parent) {
432
+ if (n->tok != MDOC_Bl)
433
+ continue;
434
+ if (n->norm->Bl.type == LIST_column)
435
+ fl = ARGSFL_TABSEP;
436
+ break;
437
+ }
438
+ }
439
+
440
+ return args(mdoc, line, pos, buf, fl, v);
441
+ }
442
+
443
+ static enum margserr
444
+ args(struct roff_man *mdoc, int line, int *pos,
445
+ char *buf, enum argsflag fl, char **v)
446
+ {
447
+ char *p;
448
+ char *v_local;
449
+ int pairs;
450
+
451
+ if (buf[*pos] == '\0') {
452
+ if (mdoc->flags & MDOC_PHRASELIT &&
453
+ ! (mdoc->flags & MDOC_PHRASE)) {
454
+ mandoc_msg(MANDOCERR_ARG_QUOTE, line, *pos, NULL);
455
+ mdoc->flags &= ~MDOC_PHRASELIT;
456
+ }
457
+ mdoc->flags &= ~MDOC_PHRASEQL;
458
+ return ARGS_EOLN;
459
+ }
460
+
461
+ if (v == NULL)
462
+ v = &v_local;
463
+ *v = buf + *pos;
464
+
465
+ if (fl == ARGSFL_DELIM && args_checkpunct(buf, *pos))
466
+ return ARGS_PUNCT;
467
+
468
+ /*
469
+ * Tabs in `It' lines in `Bl -column' can't be escaped.
470
+ * Phrases are reparsed for `Ta' and other macros later.
471
+ */
472
+
473
+ if (fl == ARGSFL_TABSEP) {
474
+ if ((p = strchr(*v, '\t')) != NULL) {
475
+
476
+ /*
477
+ * Words right before and right after
478
+ * tab characters are not parsed,
479
+ * unless there is a blank in between.
480
+ */
481
+
482
+ if (p > buf && p[-1] != ' ')
483
+ mdoc->flags |= MDOC_PHRASEQL;
484
+ if (p[1] != ' ')
485
+ mdoc->flags |= MDOC_PHRASEQN;
486
+
487
+ /*
488
+ * One or more blanks after a tab cause
489
+ * one leading blank in the next column.
490
+ * So skip all but one of them.
491
+ */
492
+
493
+ *pos += (int)(p - *v) + 1;
494
+ while (buf[*pos] == ' ' && buf[*pos + 1] == ' ')
495
+ (*pos)++;
496
+
497
+ /*
498
+ * A tab at the end of an input line
499
+ * switches to the next column.
500
+ */
501
+
502
+ if (buf[*pos] == '\0' || buf[*pos + 1] == '\0')
503
+ mdoc->flags |= MDOC_PHRASEQN;
504
+ } else {
505
+ p = strchr(*v, '\0');
506
+ if (p[-1] == ' ')
507
+ mandoc_msg(MANDOCERR_SPACE_EOL,
508
+ line, *pos, NULL);
509
+ *pos += (int)(p - *v);
510
+ }
511
+
512
+ /* Skip any trailing blank characters. */
513
+ while (p > *v && p[-1] == ' ' &&
514
+ (p - 1 == *v || p[-2] != '\\'))
515
+ p--;
516
+ *p = '\0';
517
+
518
+ return ARGS_PHRASE;
519
+ }
520
+
521
+ /*
522
+ * Process a quoted literal. A quote begins with a double-quote
523
+ * and ends with a double-quote NOT preceded by a double-quote.
524
+ * NUL-terminate the literal in place.
525
+ * Collapse pairs of quotes inside quoted literals.
526
+ * Whitespace is NOT involved in literal termination.
527
+ */
528
+
529
+ if (mdoc->flags & MDOC_PHRASELIT ||
530
+ (mdoc->flags & MDOC_PHRASE && buf[*pos] == '\"')) {
531
+ if ((mdoc->flags & MDOC_PHRASELIT) == 0) {
532
+ *v = &buf[++(*pos)];
533
+ mdoc->flags |= MDOC_PHRASELIT;
534
+ }
535
+ pairs = 0;
536
+ for ( ; buf[*pos]; (*pos)++) {
537
+ /* Move following text left after quoted quotes. */
538
+ if (pairs)
539
+ buf[*pos - pairs] = buf[*pos];
540
+ if ('\"' != buf[*pos])
541
+ continue;
542
+ /* Unquoted quotes end quoted args. */
543
+ if ('\"' != buf[*pos + 1])
544
+ break;
545
+ /* Quoted quotes collapse. */
546
+ pairs++;
547
+ (*pos)++;
548
+ }
549
+ if (pairs)
550
+ buf[*pos - pairs] = '\0';
551
+
552
+ if (buf[*pos] == '\0') {
553
+ if ( ! (mdoc->flags & MDOC_PHRASE))
554
+ mandoc_msg(MANDOCERR_ARG_QUOTE,
555
+ line, *pos, NULL);
556
+ return ARGS_WORD;
557
+ }
558
+
559
+ mdoc->flags &= ~MDOC_PHRASELIT;
560
+ buf[(*pos)++] = '\0';
561
+
562
+ if ('\0' == buf[*pos])
563
+ return ARGS_WORD;
564
+
565
+ while (' ' == buf[*pos])
566
+ (*pos)++;
567
+
568
+ if ('\0' == buf[*pos])
569
+ mandoc_msg(MANDOCERR_SPACE_EOL, line, *pos, NULL);
570
+
571
+ return ARGS_WORD;
572
+ }
573
+
574
+ p = &buf[*pos];
575
+ *v = roff_getarg(mdoc->roff, &p, line, pos);
576
+ if (v == &v_local)
577
+ free(*v);
578
+
579
+ /*
580
+ * After parsing the last word in this phrase,
581
+ * tell lookup() whether or not to interpret it.
582
+ */
583
+
584
+ if (*p == '\0' && mdoc->flags & MDOC_PHRASEQL) {
585
+ mdoc->flags &= ~MDOC_PHRASEQL;
586
+ mdoc->flags |= MDOC_PHRASEQF;
587
+ }
588
+ return ARGS_ALLOC;
589
+ }
590
+
591
+ /*
592
+ * Check if the string consists only of space-separated closing
593
+ * delimiters. This is a bit of a dance: the first must be a close
594
+ * delimiter, but it may be followed by middle delimiters. Arbitrary
595
+ * whitespace may separate these tokens.
596
+ */
597
+ static int
598
+ args_checkpunct(const char *buf, int i)
599
+ {
600
+ int j;
601
+ char dbuf[DELIMSZ];
602
+ enum mdelim d;
603
+
604
+ /* First token must be a close-delimiter. */
605
+
606
+ for (j = 0; buf[i] && ' ' != buf[i] && j < DELIMSZ; j++, i++)
607
+ dbuf[j] = buf[i];
608
+
609
+ if (DELIMSZ == j)
610
+ return 0;
611
+
612
+ dbuf[j] = '\0';
613
+ if (DELIM_CLOSE != mdoc_isdelim(dbuf))
614
+ return 0;
615
+
616
+ while (' ' == buf[i])
617
+ i++;
618
+
619
+ /* Remaining must NOT be open/none. */
620
+
621
+ while (buf[i]) {
622
+ j = 0;
623
+ while (buf[i] && ' ' != buf[i] && j < DELIMSZ)
624
+ dbuf[j++] = buf[i++];
625
+
626
+ if (DELIMSZ == j)
627
+ return 0;
628
+
629
+ dbuf[j] = '\0';
630
+ d = mdoc_isdelim(dbuf);
631
+ if (DELIM_NONE == d || DELIM_OPEN == d)
632
+ return 0;
633
+
634
+ while (' ' == buf[i])
635
+ i++;
636
+ }
637
+
638
+ return '\0' == buf[i];
639
+ }
640
+
641
+ static void
642
+ argv_multi(struct roff_man *mdoc, int line,
643
+ struct mdoc_argv *v, int *pos, char *buf)
644
+ {
645
+ enum margserr ac;
646
+ char *p;
647
+
648
+ for (v->sz = 0; ; v->sz++) {
649
+ if (buf[*pos] == '-')
650
+ break;
651
+ ac = args(mdoc, line, pos, buf, ARGSFL_NONE, &p);
652
+ if (ac == ARGS_EOLN)
653
+ break;
654
+
655
+ if (v->sz % MULTI_STEP == 0)
656
+ v->value = mandoc_reallocarray(v->value,
657
+ v->sz + MULTI_STEP, sizeof(char *));
658
+
659
+ if (ac != ARGS_ALLOC)
660
+ p = mandoc_strdup(p);
661
+ v->value[(int)v->sz] = p;
662
+ }
663
+ }
664
+
665
+ static void
666
+ argv_single(struct roff_man *mdoc, int line,
667
+ struct mdoc_argv *v, int *pos, char *buf)
668
+ {
669
+ enum margserr ac;
670
+ char *p;
671
+
672
+ ac = args(mdoc, line, pos, buf, ARGSFL_NONE, &p);
673
+ if (ac == ARGS_EOLN)
674
+ return;
675
+
676
+ if (ac != ARGS_ALLOC)
677
+ p = mandoc_strdup(p);
678
+
679
+ v->sz = 1;
680
+ v->value = mandoc_malloc(sizeof(char *));
681
+ v->value[0] = p;
682
+ }