]>
git.cameronkatri.com Git - mandoc.git/blob - macro.c
68a8cc920fe9c190eca3529e474d028fcf4de935
1 /* $Id: macro.c,v 1.2 2008/12/15 01:54:58 kristaps Exp $ */
3 * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the
7 * above copyright notice and this permission notice appear in all
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
26 #define _C(p) ((const char **)p)
28 static int isdelim(const char *);
29 static int args_next(struct mdoc
*, int, int *, char *, char **);
30 static int append_text(struct mdoc
*, int, int, int, char *[]);
31 static int append_scoped(struct mdoc
*, int, int, int, char *[]);
35 isdelim(const char *p
)
77 args_next(struct mdoc
*mdoc
, int tok
,
78 int *pos
, char *buf
, char **v
)
84 assert( ! isspace(buf
[*pos
]));
86 if ('\"' == buf
[*pos
]) {
87 (void)mdoc_err(mdoc
, tok
, *pos
, ERR_SYNTAX_QUOTE
);
93 /* Scan ahead to end of token. */
95 while (buf
[*pos
] && ! isspace(buf
[*pos
]))
98 if (buf
[*pos
] && buf
[*pos
+ 1] && '\\' == buf
[*pos
]) {
99 (void)mdoc_err(mdoc
, tok
, *pos
, ERR_SYNTAX_WS
);
106 /* Scan ahead over trailing whitespace. */
109 while (buf
[*pos
] && isspace(buf
[*pos
]))
113 if ( ! mdoc_warn(mdoc
, tok
, *pos
, WARN_SYNTAX_WS_EOLN
))
121 append_scoped(struct mdoc
*mdoc
, int tok
, int pos
, int sz
, char *args
[])
125 mdoc_block_alloc(mdoc
, pos
, tok
, 0, NULL
);
126 mdoc_head_alloc(mdoc
, pos
, tok
, sz
, _C(args
));
127 mdoc_body_alloc(mdoc
, pos
, tok
);
133 append_text(struct mdoc
*mdoc
, int tok
, int pos
, int sz
, char *args
[])
139 /* ======= ADD MORE MACRO ARGUMENT-LIMITS BELOW. ======= */
150 if (0 == sz
&& ! mdoc_warn(mdoc
, tok
, pos
, WARN_ARGS_GE1
))
152 mdoc_elem_alloc(mdoc
, pos
, tok
, 0, NULL
, sz
, _C(args
));
160 mdoc_elem_alloc(mdoc
, pos
, tok
, 0, NULL
, sz
, _C(args
));
181 return(mdoc_err(mdoc
, tok
, pos
, ERR_ARGS_GE1
));
182 mdoc_elem_alloc(mdoc
, pos
, tok
, 0, NULL
, sz
, _C(args
));
185 /* ======= ADD MORE MACRO ARGUMENT-LIMITS ABOVE. ======= */
196 macro_text(struct mdoc
*mdoc
, int tok
, int ppos
, int *pos
, char *buf
)
198 int lastarg
, j
, c
, lasttok
, lastpunct
;
199 char *args
[MDOC_LINEARG_MAX
], *p
;
208 c
= args_next(mdoc
, tok
, pos
, buf
, &args
[j
]);
212 if (0 == c
&& ! lastpunct
)
213 return(append_text(mdoc
, tok
, lasttok
, j
, args
));
219 if (MDOC_MAX
!= (c
= mdoc_find(mdoc
, args
[j
]))) {
221 if ( ! append_text(mdoc
, tok
, lasttok
, j
, args
))
223 return(mdoc_macro(mdoc
, c
, lastarg
, pos
, buf
));
228 if ( ! isdelim(args
[j
])) {
233 /* Punctuation found. */
235 p
= args
[j
]; /* Save argument (NULL-ified in append). */
238 if ( ! append_text(mdoc
, tok
, lasttok
, j
, args
))
243 mdoc_word_alloc(mdoc
, lastarg
, args
[j
]);
254 macro_scoped_implicit(struct mdoc
*mdoc
,
255 int tok
, int ppos
, int *pos
, char *buf
)
257 int j
, c
, lastarg
, t
;
258 char *args
[MDOC_LINEARG_MAX
];
262 * Look for an implicit parent.
265 assert( ! (MDOC_EXPLICIT
& mdoc_macros
[tok
].flags
));
267 for (n
= mdoc
->last
; n
; n
= n
->parent
) {
268 if (MDOC_BLOCK
!= n
->type
)
270 if (tok
== (t
= n
->data
.block
.tok
))
272 if ( ! (MDOC_EXPLICIT
& mdoc_macros
[t
].flags
))
274 return(mdoc_err(mdoc
, tok
, ppos
, ERR_SCOPE_BREAK
));
279 mdoc_msg(mdoc
, ppos
, "scope: rewound `%s'",
280 mdoc_macronames
[tok
]);
282 mdoc_msg(mdoc
, ppos
, "scope: new `%s'",
283 mdoc_macronames
[tok
]);
290 c
= args_next(mdoc
, tok
, pos
, buf
, &args
[j
]);
295 return(append_scoped(mdoc
, tok
, ppos
, j
, args
));
299 if (MDOC_MAX
!= (c
= mdoc_find(mdoc
, args
[j
])))
300 if ( ! mdoc_warn(mdoc
, tok
, *pos
, WARN_SYNTAX_MACLIKE
))