1*698f87a4SGarrett D'Amore /* $Id: mdoc_argv.c,v 1.89 2013/12/25 00:50:05 schwarze Exp $ */ 295c635efSGarrett D'Amore /* 395c635efSGarrett D'Amore * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> 4*698f87a4SGarrett D'Amore * Copyright (c) 2012 Ingo Schwarze <schwarze@openbsd.org> 595c635efSGarrett D'Amore * 695c635efSGarrett D'Amore * Permission to use, copy, modify, and distribute this software for any 795c635efSGarrett D'Amore * purpose with or without fee is hereby granted, provided that the above 895c635efSGarrett D'Amore * copyright notice and this permission notice appear in all copies. 995c635efSGarrett D'Amore * 1095c635efSGarrett D'Amore * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 1195c635efSGarrett D'Amore * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 1295c635efSGarrett D'Amore * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 1395c635efSGarrett D'Amore * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1495c635efSGarrett D'Amore * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 1595c635efSGarrett D'Amore * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 1695c635efSGarrett D'Amore * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 1795c635efSGarrett D'Amore */ 1895c635efSGarrett D'Amore #ifdef HAVE_CONFIG_H 1995c635efSGarrett D'Amore #include "config.h" 2095c635efSGarrett D'Amore #endif 2195c635efSGarrett D'Amore 2295c635efSGarrett D'Amore #include <sys/types.h> 2395c635efSGarrett D'Amore 2495c635efSGarrett D'Amore #include <assert.h> 2595c635efSGarrett D'Amore #include <stdlib.h> 2695c635efSGarrett D'Amore #include <stdio.h> 2795c635efSGarrett D'Amore #include <string.h> 2895c635efSGarrett D'Amore 2995c635efSGarrett D'Amore #include "mdoc.h" 3095c635efSGarrett D'Amore #include "mandoc.h" 3195c635efSGarrett D'Amore #include "libmdoc.h" 3295c635efSGarrett D'Amore #include "libmandoc.h" 3395c635efSGarrett D'Amore 3495c635efSGarrett D'Amore #define MULTI_STEP 5 /* pre-allocate argument values */ 3595c635efSGarrett D'Amore #define DELIMSZ 6 /* max possible size of a delimiter */ 3695c635efSGarrett D'Amore 3795c635efSGarrett D'Amore enum argsflag { 3895c635efSGarrett D'Amore ARGSFL_NONE = 0, 3995c635efSGarrett D'Amore ARGSFL_DELIM, /* handle delimiters of [[::delim::][ ]+]+ */ 4095c635efSGarrett D'Amore ARGSFL_TABSEP /* handle tab/`Ta' separated phrases */ 4195c635efSGarrett D'Amore }; 4295c635efSGarrett D'Amore 4395c635efSGarrett D'Amore enum argvflag { 4495c635efSGarrett D'Amore ARGV_NONE, /* no args to flag (e.g., -split) */ 4595c635efSGarrett D'Amore ARGV_SINGLE, /* one arg to flag (e.g., -file xxx) */ 46*698f87a4SGarrett D'Amore ARGV_MULTI /* multiple args (e.g., -column xxx yyy) */ 4795c635efSGarrett D'Amore }; 4895c635efSGarrett D'Amore 4995c635efSGarrett D'Amore struct mdocarg { 5095c635efSGarrett D'Amore enum argsflag flags; 5195c635efSGarrett D'Amore const enum mdocargt *argvs; 5295c635efSGarrett D'Amore }; 5395c635efSGarrett D'Amore 5495c635efSGarrett D'Amore static void argn_free(struct mdoc_arg *, int); 5595c635efSGarrett D'Amore static enum margserr args(struct mdoc *, int, int *, 5695c635efSGarrett D'Amore char *, enum argsflag, char **); 5795c635efSGarrett D'Amore static int args_checkpunct(const char *, int); 5895c635efSGarrett D'Amore static int argv_multi(struct mdoc *, int, 5995c635efSGarrett D'Amore struct mdoc_argv *, int *, char *); 6095c635efSGarrett D'Amore static int argv_single(struct mdoc *, int, 6195c635efSGarrett D'Amore struct mdoc_argv *, int *, char *); 6295c635efSGarrett D'Amore 6395c635efSGarrett D'Amore static const enum argvflag argvflags[MDOC_ARG_MAX] = { 6495c635efSGarrett D'Amore ARGV_NONE, /* MDOC_Split */ 6595c635efSGarrett D'Amore ARGV_NONE, /* MDOC_Nosplit */ 6695c635efSGarrett D'Amore ARGV_NONE, /* MDOC_Ragged */ 6795c635efSGarrett D'Amore ARGV_NONE, /* MDOC_Unfilled */ 6895c635efSGarrett D'Amore ARGV_NONE, /* MDOC_Literal */ 6995c635efSGarrett D'Amore ARGV_SINGLE, /* MDOC_File */ 70*698f87a4SGarrett D'Amore ARGV_SINGLE, /* MDOC_Offset */ 7195c635efSGarrett D'Amore ARGV_NONE, /* MDOC_Bullet */ 7295c635efSGarrett D'Amore ARGV_NONE, /* MDOC_Dash */ 7395c635efSGarrett D'Amore ARGV_NONE, /* MDOC_Hyphen */ 7495c635efSGarrett D'Amore ARGV_NONE, /* MDOC_Item */ 7595c635efSGarrett D'Amore ARGV_NONE, /* MDOC_Enum */ 7695c635efSGarrett D'Amore ARGV_NONE, /* MDOC_Tag */ 7795c635efSGarrett D'Amore ARGV_NONE, /* MDOC_Diag */ 7895c635efSGarrett D'Amore ARGV_NONE, /* MDOC_Hang */ 7995c635efSGarrett D'Amore ARGV_NONE, /* MDOC_Ohang */ 8095c635efSGarrett D'Amore ARGV_NONE, /* MDOC_Inset */ 8195c635efSGarrett D'Amore ARGV_MULTI, /* MDOC_Column */ 82*698f87a4SGarrett D'Amore ARGV_SINGLE, /* MDOC_Width */ 8395c635efSGarrett D'Amore ARGV_NONE, /* MDOC_Compact */ 8495c635efSGarrett D'Amore ARGV_NONE, /* MDOC_Std */ 8595c635efSGarrett D'Amore ARGV_NONE, /* MDOC_Filled */ 8695c635efSGarrett D'Amore ARGV_NONE, /* MDOC_Words */ 8795c635efSGarrett D'Amore ARGV_NONE, /* MDOC_Emphasis */ 8895c635efSGarrett D'Amore ARGV_NONE, /* MDOC_Symbolic */ 8995c635efSGarrett D'Amore ARGV_NONE /* MDOC_Symbolic */ 9095c635efSGarrett D'Amore }; 9195c635efSGarrett D'Amore 9295c635efSGarrett D'Amore static const enum mdocargt args_Ex[] = { 9395c635efSGarrett D'Amore MDOC_Std, 9495c635efSGarrett D'Amore MDOC_ARG_MAX 9595c635efSGarrett D'Amore }; 9695c635efSGarrett D'Amore 9795c635efSGarrett D'Amore static const enum mdocargt args_An[] = { 9895c635efSGarrett D'Amore MDOC_Split, 9995c635efSGarrett D'Amore MDOC_Nosplit, 10095c635efSGarrett D'Amore MDOC_ARG_MAX 10195c635efSGarrett D'Amore }; 10295c635efSGarrett D'Amore 10395c635efSGarrett D'Amore static const enum mdocargt args_Bd[] = { 10495c635efSGarrett D'Amore MDOC_Ragged, 10595c635efSGarrett D'Amore MDOC_Unfilled, 10695c635efSGarrett D'Amore MDOC_Filled, 10795c635efSGarrett D'Amore MDOC_Literal, 10895c635efSGarrett D'Amore MDOC_File, 10995c635efSGarrett D'Amore MDOC_Offset, 11095c635efSGarrett D'Amore MDOC_Compact, 11195c635efSGarrett D'Amore MDOC_Centred, 11295c635efSGarrett D'Amore MDOC_ARG_MAX 11395c635efSGarrett D'Amore }; 11495c635efSGarrett D'Amore 11595c635efSGarrett D'Amore static const enum mdocargt args_Bf[] = { 11695c635efSGarrett D'Amore MDOC_Emphasis, 11795c635efSGarrett D'Amore MDOC_Literal, 11895c635efSGarrett D'Amore MDOC_Symbolic, 11995c635efSGarrett D'Amore MDOC_ARG_MAX 12095c635efSGarrett D'Amore }; 12195c635efSGarrett D'Amore 12295c635efSGarrett D'Amore static const enum mdocargt args_Bk[] = { 12395c635efSGarrett D'Amore MDOC_Words, 12495c635efSGarrett D'Amore MDOC_ARG_MAX 12595c635efSGarrett D'Amore }; 12695c635efSGarrett D'Amore 12795c635efSGarrett D'Amore static const enum mdocargt args_Bl[] = { 12895c635efSGarrett D'Amore MDOC_Bullet, 12995c635efSGarrett D'Amore MDOC_Dash, 13095c635efSGarrett D'Amore MDOC_Hyphen, 13195c635efSGarrett D'Amore MDOC_Item, 13295c635efSGarrett D'Amore MDOC_Enum, 13395c635efSGarrett D'Amore MDOC_Tag, 13495c635efSGarrett D'Amore MDOC_Diag, 13595c635efSGarrett D'Amore MDOC_Hang, 13695c635efSGarrett D'Amore MDOC_Ohang, 13795c635efSGarrett D'Amore MDOC_Inset, 13895c635efSGarrett D'Amore MDOC_Column, 13995c635efSGarrett D'Amore MDOC_Width, 14095c635efSGarrett D'Amore MDOC_Offset, 14195c635efSGarrett D'Amore MDOC_Compact, 14295c635efSGarrett D'Amore MDOC_Nested, 14395c635efSGarrett D'Amore MDOC_ARG_MAX 14495c635efSGarrett D'Amore }; 14595c635efSGarrett D'Amore 14695c635efSGarrett D'Amore static const struct mdocarg mdocargs[MDOC_MAX] = { 147*698f87a4SGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Ap */ 14895c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Dd */ 14995c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Dt */ 15095c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Os */ 15195c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Sh */ 15295c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Ss */ 15395c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Pp */ 15495c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* D1 */ 15595c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Dl */ 15695c635efSGarrett D'Amore { ARGSFL_NONE, args_Bd }, /* Bd */ 15795c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Ed */ 15895c635efSGarrett D'Amore { ARGSFL_NONE, args_Bl }, /* Bl */ 15995c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* El */ 16095c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* It */ 16195c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Ad */ 16295c635efSGarrett D'Amore { ARGSFL_DELIM, args_An }, /* An */ 16395c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Ar */ 164*698f87a4SGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Cd */ 16595c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Cm */ 16695c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Dv */ 16795c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Er */ 16895c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Ev */ 16995c635efSGarrett D'Amore { ARGSFL_NONE, args_Ex }, /* Ex */ 17095c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Fa */ 17195c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Fd */ 17295c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Fl */ 17395c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Fn */ 17495c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Ft */ 17595c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Ic */ 176*698f87a4SGarrett D'Amore { ARGSFL_DELIM, NULL }, /* In */ 17795c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Li */ 17895c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Nd */ 17995c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Nm */ 18095c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Op */ 18195c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Ot */ 18295c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Pa */ 18395c635efSGarrett D'Amore { ARGSFL_NONE, args_Ex }, /* Rv */ 18495c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* St */ 18595c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Va */ 18695c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Vt */ 18795c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Xr */ 18895c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* %A */ 18995c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* %B */ 19095c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* %D */ 19195c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* %I */ 19295c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* %J */ 19395c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* %N */ 19495c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* %O */ 19595c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* %P */ 19695c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* %R */ 19795c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* %T */ 19895c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* %V */ 19995c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Ac */ 20095c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Ao */ 20195c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Aq */ 20295c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* At */ 20395c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Bc */ 20495c635efSGarrett D'Amore { ARGSFL_NONE, args_Bf }, /* Bf */ 20595c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Bo */ 20695c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Bq */ 20795c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Bsx */ 20895c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Bx */ 20995c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Db */ 21095c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Dc */ 21195c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Do */ 21295c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Dq */ 21395c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Ec */ 21495c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Ef */ 21595c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Em */ 21695c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Eo */ 21795c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Fx */ 21895c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Ms */ 21995c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* No */ 22095c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Ns */ 22195c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Nx */ 22295c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Ox */ 22395c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Pc */ 22495c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Pf */ 22595c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Po */ 22695c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Pq */ 22795c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Qc */ 22895c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Ql */ 22995c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Qo */ 23095c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Qq */ 23195c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Re */ 23295c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Rs */ 23395c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Sc */ 23495c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* So */ 23595c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Sq */ 23695c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Sm */ 23795c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Sx */ 23895c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Sy */ 23995c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Tn */ 24095c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Ux */ 24195c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Xc */ 24295c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Xo */ 24395c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Fo */ 244*698f87a4SGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Fc */ 24595c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Oo */ 24695c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Oc */ 24795c635efSGarrett D'Amore { ARGSFL_NONE, args_Bk }, /* Bk */ 24895c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Ek */ 24995c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Bt */ 25095c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Hf */ 25195c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Fr */ 25295c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Ud */ 253*698f87a4SGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Lb */ 25495c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Lp */ 25595c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Lk */ 25695c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Mt */ 25795c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Brq */ 25895c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Bro */ 25995c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Brc */ 26095c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* %C */ 26195c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Es */ 26295c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* En */ 263*698f87a4SGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Dx */ 26495c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* %Q */ 26595c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* br */ 26695c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* sp */ 26795c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* %U */ 26895c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Ta */ 26995c635efSGarrett D'Amore }; 27095c635efSGarrett D'Amore 27195c635efSGarrett D'Amore 27295c635efSGarrett D'Amore /* 27395c635efSGarrett D'Amore * Parse an argument from line text. This comes in the form of -key 27495c635efSGarrett D'Amore * [value0...], which may either have a single mandatory value, at least 27595c635efSGarrett D'Amore * one mandatory value, an optional single value, or no value. 27695c635efSGarrett D'Amore */ 27795c635efSGarrett D'Amore enum margverr 278*698f87a4SGarrett D'Amore mdoc_argv(struct mdoc *mdoc, int line, enum mdoct tok, 27995c635efSGarrett D'Amore struct mdoc_arg **v, int *pos, char *buf) 28095c635efSGarrett D'Amore { 28195c635efSGarrett D'Amore char *p, sv; 28295c635efSGarrett D'Amore struct mdoc_argv tmp; 28395c635efSGarrett D'Amore struct mdoc_arg *arg; 28495c635efSGarrett D'Amore const enum mdocargt *ap; 28595c635efSGarrett D'Amore 28695c635efSGarrett D'Amore if ('\0' == buf[*pos]) 28795c635efSGarrett D'Amore return(ARGV_EOLN); 28895c635efSGarrett D'Amore else if (NULL == (ap = mdocargs[tok].argvs)) 28995c635efSGarrett D'Amore return(ARGV_WORD); 29095c635efSGarrett D'Amore else if ('-' != buf[*pos]) 29195c635efSGarrett D'Amore return(ARGV_WORD); 29295c635efSGarrett D'Amore 29395c635efSGarrett D'Amore /* Seek to the first unescaped space. */ 29495c635efSGarrett D'Amore 29595c635efSGarrett D'Amore p = &buf[++(*pos)]; 29695c635efSGarrett D'Amore 29795c635efSGarrett D'Amore assert(*pos > 0); 29895c635efSGarrett D'Amore 29995c635efSGarrett D'Amore for ( ; buf[*pos] ; (*pos)++) 30095c635efSGarrett D'Amore if (' ' == buf[*pos] && '\\' != buf[*pos - 1]) 30195c635efSGarrett D'Amore break; 30295c635efSGarrett D'Amore 30395c635efSGarrett D'Amore /* 30495c635efSGarrett D'Amore * We want to nil-terminate the word to look it up (it's easier 30595c635efSGarrett D'Amore * that way). But we may not have a flag, in which case we need 30695c635efSGarrett D'Amore * to restore the line as-is. So keep around the stray byte, 30795c635efSGarrett D'Amore * which we'll reset upon exiting (if necessary). 30895c635efSGarrett D'Amore */ 30995c635efSGarrett D'Amore 31095c635efSGarrett D'Amore if ('\0' != (sv = buf[*pos])) 31195c635efSGarrett D'Amore buf[(*pos)++] = '\0'; 31295c635efSGarrett D'Amore 31395c635efSGarrett D'Amore /* 31495c635efSGarrett D'Amore * Now look up the word as a flag. Use temporary storage that 31595c635efSGarrett D'Amore * we'll copy into the node's flags, if necessary. 31695c635efSGarrett D'Amore */ 31795c635efSGarrett D'Amore 31895c635efSGarrett D'Amore memset(&tmp, 0, sizeof(struct mdoc_argv)); 31995c635efSGarrett D'Amore 32095c635efSGarrett D'Amore tmp.line = line; 32195c635efSGarrett D'Amore tmp.pos = *pos; 32295c635efSGarrett D'Amore tmp.arg = MDOC_ARG_MAX; 32395c635efSGarrett D'Amore 32495c635efSGarrett D'Amore while (MDOC_ARG_MAX != (tmp.arg = *ap++)) 32595c635efSGarrett D'Amore if (0 == strcmp(p, mdoc_argnames[tmp.arg])) 32695c635efSGarrett D'Amore break; 32795c635efSGarrett D'Amore 32895c635efSGarrett D'Amore if (MDOC_ARG_MAX == tmp.arg) { 32995c635efSGarrett D'Amore /* 33095c635efSGarrett D'Amore * The flag was not found. 33195c635efSGarrett D'Amore * Restore saved zeroed byte and return as a word. 33295c635efSGarrett D'Amore */ 33395c635efSGarrett D'Amore if (sv) 33495c635efSGarrett D'Amore buf[*pos - 1] = sv; 33595c635efSGarrett D'Amore return(ARGV_WORD); 33695c635efSGarrett D'Amore } 33795c635efSGarrett D'Amore 33895c635efSGarrett D'Amore /* Read to the next word (the argument). */ 33995c635efSGarrett D'Amore 34095c635efSGarrett D'Amore while (buf[*pos] && ' ' == buf[*pos]) 34195c635efSGarrett D'Amore (*pos)++; 34295c635efSGarrett D'Amore 34395c635efSGarrett D'Amore switch (argvflags[tmp.arg]) { 34495c635efSGarrett D'Amore case (ARGV_SINGLE): 345*698f87a4SGarrett D'Amore if ( ! argv_single(mdoc, line, &tmp, pos, buf)) 34695c635efSGarrett D'Amore return(ARGV_ERROR); 34795c635efSGarrett D'Amore break; 34895c635efSGarrett D'Amore case (ARGV_MULTI): 349*698f87a4SGarrett D'Amore if ( ! argv_multi(mdoc, line, &tmp, pos, buf)) 35095c635efSGarrett D'Amore return(ARGV_ERROR); 35195c635efSGarrett D'Amore break; 35295c635efSGarrett D'Amore case (ARGV_NONE): 35395c635efSGarrett D'Amore break; 35495c635efSGarrett D'Amore } 35595c635efSGarrett D'Amore 35695c635efSGarrett D'Amore if (NULL == (arg = *v)) 35795c635efSGarrett D'Amore arg = *v = mandoc_calloc(1, sizeof(struct mdoc_arg)); 35895c635efSGarrett D'Amore 35995c635efSGarrett D'Amore arg->argc++; 36095c635efSGarrett D'Amore arg->argv = mandoc_realloc 36195c635efSGarrett D'Amore (arg->argv, arg->argc * sizeof(struct mdoc_argv)); 36295c635efSGarrett D'Amore 36395c635efSGarrett D'Amore memcpy(&arg->argv[(int)arg->argc - 1], 36495c635efSGarrett D'Amore &tmp, sizeof(struct mdoc_argv)); 36595c635efSGarrett D'Amore 36695c635efSGarrett D'Amore return(ARGV_ARG); 36795c635efSGarrett D'Amore } 36895c635efSGarrett D'Amore 36995c635efSGarrett D'Amore void 37095c635efSGarrett D'Amore mdoc_argv_free(struct mdoc_arg *p) 37195c635efSGarrett D'Amore { 37295c635efSGarrett D'Amore int i; 37395c635efSGarrett D'Amore 37495c635efSGarrett D'Amore if (NULL == p) 37595c635efSGarrett D'Amore return; 37695c635efSGarrett D'Amore 37795c635efSGarrett D'Amore if (p->refcnt) { 37895c635efSGarrett D'Amore --(p->refcnt); 37995c635efSGarrett D'Amore if (p->refcnt) 38095c635efSGarrett D'Amore return; 38195c635efSGarrett D'Amore } 38295c635efSGarrett D'Amore assert(p->argc); 38395c635efSGarrett D'Amore 38495c635efSGarrett D'Amore for (i = (int)p->argc - 1; i >= 0; i--) 38595c635efSGarrett D'Amore argn_free(p, i); 38695c635efSGarrett D'Amore 38795c635efSGarrett D'Amore free(p->argv); 38895c635efSGarrett D'Amore free(p); 38995c635efSGarrett D'Amore } 39095c635efSGarrett D'Amore 39195c635efSGarrett D'Amore static void 39295c635efSGarrett D'Amore argn_free(struct mdoc_arg *p, int iarg) 39395c635efSGarrett D'Amore { 39495c635efSGarrett D'Amore struct mdoc_argv *arg; 39595c635efSGarrett D'Amore int j; 39695c635efSGarrett D'Amore 39795c635efSGarrett D'Amore arg = &p->argv[iarg]; 39895c635efSGarrett D'Amore 39995c635efSGarrett D'Amore if (arg->sz && arg->value) { 40095c635efSGarrett D'Amore for (j = (int)arg->sz - 1; j >= 0; j--) 40195c635efSGarrett D'Amore free(arg->value[j]); 40295c635efSGarrett D'Amore free(arg->value); 40395c635efSGarrett D'Amore } 40495c635efSGarrett D'Amore 40595c635efSGarrett D'Amore for (--p->argc; iarg < (int)p->argc; iarg++) 40695c635efSGarrett D'Amore p->argv[iarg] = p->argv[iarg+1]; 40795c635efSGarrett D'Amore } 40895c635efSGarrett D'Amore 40995c635efSGarrett D'Amore enum margserr 410*698f87a4SGarrett D'Amore mdoc_zargs(struct mdoc *mdoc, int line, int *pos, char *buf, char **v) 41195c635efSGarrett D'Amore { 41295c635efSGarrett D'Amore 413*698f87a4SGarrett D'Amore return(args(mdoc, line, pos, buf, ARGSFL_NONE, v)); 41495c635efSGarrett D'Amore } 41595c635efSGarrett D'Amore 41695c635efSGarrett D'Amore enum margserr 417*698f87a4SGarrett D'Amore mdoc_args(struct mdoc *mdoc, int line, int *pos, 41895c635efSGarrett D'Amore char *buf, enum mdoct tok, char **v) 41995c635efSGarrett D'Amore { 42095c635efSGarrett D'Amore enum argsflag fl; 42195c635efSGarrett D'Amore struct mdoc_node *n; 42295c635efSGarrett D'Amore 42395c635efSGarrett D'Amore fl = mdocargs[tok].flags; 42495c635efSGarrett D'Amore 42595c635efSGarrett D'Amore if (MDOC_It != tok) 426*698f87a4SGarrett D'Amore return(args(mdoc, line, pos, buf, fl, v)); 42795c635efSGarrett D'Amore 42895c635efSGarrett D'Amore /* 42995c635efSGarrett D'Amore * We know that we're in an `It', so it's reasonable to expect 43095c635efSGarrett D'Amore * us to be sitting in a `Bl'. Someday this may not be the case 43195c635efSGarrett D'Amore * (if we allow random `It's sitting out there), so provide a 43295c635efSGarrett D'Amore * safe fall-back into the default behaviour. 43395c635efSGarrett D'Amore */ 43495c635efSGarrett D'Amore 435*698f87a4SGarrett D'Amore for (n = mdoc->last; n; n = n->parent) 43695c635efSGarrett D'Amore if (MDOC_Bl == n->tok) 43795c635efSGarrett D'Amore if (LIST_column == n->norm->Bl.type) { 43895c635efSGarrett D'Amore fl = ARGSFL_TABSEP; 43995c635efSGarrett D'Amore break; 44095c635efSGarrett D'Amore } 44195c635efSGarrett D'Amore 442*698f87a4SGarrett D'Amore return(args(mdoc, line, pos, buf, fl, v)); 44395c635efSGarrett D'Amore } 44495c635efSGarrett D'Amore 44595c635efSGarrett D'Amore static enum margserr 446*698f87a4SGarrett D'Amore args(struct mdoc *mdoc, int line, int *pos, 44795c635efSGarrett D'Amore char *buf, enum argsflag fl, char **v) 44895c635efSGarrett D'Amore { 44995c635efSGarrett D'Amore char *p, *pp; 450*698f87a4SGarrett D'Amore int pairs; 45195c635efSGarrett D'Amore enum margserr rc; 45295c635efSGarrett D'Amore 45395c635efSGarrett D'Amore if ('\0' == buf[*pos]) { 454*698f87a4SGarrett D'Amore if (MDOC_PPHRASE & mdoc->flags) 45595c635efSGarrett D'Amore return(ARGS_EOLN); 45695c635efSGarrett D'Amore /* 45795c635efSGarrett D'Amore * If we're not in a partial phrase and the flag for 45895c635efSGarrett D'Amore * being a phrase literal is still set, the punctuation 45995c635efSGarrett D'Amore * is unterminated. 46095c635efSGarrett D'Amore */ 461*698f87a4SGarrett D'Amore if (MDOC_PHRASELIT & mdoc->flags) 462*698f87a4SGarrett D'Amore mdoc_pmsg(mdoc, line, *pos, MANDOCERR_BADQUOTE); 46395c635efSGarrett D'Amore 464*698f87a4SGarrett D'Amore mdoc->flags &= ~MDOC_PHRASELIT; 46595c635efSGarrett D'Amore return(ARGS_EOLN); 46695c635efSGarrett D'Amore } 46795c635efSGarrett D'Amore 46895c635efSGarrett D'Amore *v = &buf[*pos]; 46995c635efSGarrett D'Amore 47095c635efSGarrett D'Amore if (ARGSFL_DELIM == fl) 47195c635efSGarrett D'Amore if (args_checkpunct(buf, *pos)) 47295c635efSGarrett D'Amore return(ARGS_PUNCT); 47395c635efSGarrett D'Amore 47495c635efSGarrett D'Amore /* 47595c635efSGarrett D'Amore * First handle TABSEP items, restricted to `Bl -column'. This 47695c635efSGarrett D'Amore * ignores conventional token parsing and instead uses tabs or 47795c635efSGarrett D'Amore * `Ta' macros to separate phrases. Phrases are parsed again 47895c635efSGarrett D'Amore * for arguments at a later phase. 47995c635efSGarrett D'Amore */ 48095c635efSGarrett D'Amore 48195c635efSGarrett D'Amore if (ARGSFL_TABSEP == fl) { 48295c635efSGarrett D'Amore /* Scan ahead to tab (can't be escaped). */ 48395c635efSGarrett D'Amore p = strchr(*v, '\t'); 48495c635efSGarrett D'Amore pp = NULL; 48595c635efSGarrett D'Amore 48695c635efSGarrett D'Amore /* Scan ahead to unescaped `Ta'. */ 487*698f87a4SGarrett D'Amore if ( ! (MDOC_PHRASELIT & mdoc->flags)) 48895c635efSGarrett D'Amore for (pp = *v; ; pp++) { 48995c635efSGarrett D'Amore if (NULL == (pp = strstr(pp, "Ta"))) 49095c635efSGarrett D'Amore break; 49195c635efSGarrett D'Amore if (pp > *v && ' ' != *(pp - 1)) 49295c635efSGarrett D'Amore continue; 49395c635efSGarrett D'Amore if (' ' == *(pp + 2) || '\0' == *(pp + 2)) 49495c635efSGarrett D'Amore break; 49595c635efSGarrett D'Amore } 49695c635efSGarrett D'Amore 49795c635efSGarrett D'Amore /* By default, assume a phrase. */ 49895c635efSGarrett D'Amore rc = ARGS_PHRASE; 49995c635efSGarrett D'Amore 50095c635efSGarrett D'Amore /* 50195c635efSGarrett D'Amore * Adjust new-buffer position to be beyond delimiter 50295c635efSGarrett D'Amore * mark (e.g., Ta -> end + 2). 50395c635efSGarrett D'Amore */ 50495c635efSGarrett D'Amore if (p && pp) { 50595c635efSGarrett D'Amore *pos += pp < p ? 2 : 1; 50695c635efSGarrett D'Amore rc = pp < p ? ARGS_PHRASE : ARGS_PPHRASE; 50795c635efSGarrett D'Amore p = pp < p ? pp : p; 50895c635efSGarrett D'Amore } else if (p && ! pp) { 50995c635efSGarrett D'Amore rc = ARGS_PPHRASE; 51095c635efSGarrett D'Amore *pos += 1; 51195c635efSGarrett D'Amore } else if (pp && ! p) { 51295c635efSGarrett D'Amore p = pp; 51395c635efSGarrett D'Amore *pos += 2; 51495c635efSGarrett D'Amore } else { 51595c635efSGarrett D'Amore rc = ARGS_PEND; 51695c635efSGarrett D'Amore p = strchr(*v, 0); 51795c635efSGarrett D'Amore } 51895c635efSGarrett D'Amore 51995c635efSGarrett D'Amore /* Whitespace check for eoln case... */ 52095c635efSGarrett D'Amore if ('\0' == *p && ' ' == *(p - 1)) 521*698f87a4SGarrett D'Amore mdoc_pmsg(mdoc, line, *pos, MANDOCERR_EOLNSPACE); 52295c635efSGarrett D'Amore 52395c635efSGarrett D'Amore *pos += (int)(p - *v); 52495c635efSGarrett D'Amore 52595c635efSGarrett D'Amore /* Strip delimiter's preceding whitespace. */ 52695c635efSGarrett D'Amore pp = p - 1; 52795c635efSGarrett D'Amore while (pp > *v && ' ' == *pp) { 52895c635efSGarrett D'Amore if (pp > *v && '\\' == *(pp - 1)) 52995c635efSGarrett D'Amore break; 53095c635efSGarrett D'Amore pp--; 53195c635efSGarrett D'Amore } 53295c635efSGarrett D'Amore *(pp + 1) = 0; 53395c635efSGarrett D'Amore 53495c635efSGarrett D'Amore /* Strip delimiter's proceeding whitespace. */ 53595c635efSGarrett D'Amore for (pp = &buf[*pos]; ' ' == *pp; pp++, (*pos)++) 53695c635efSGarrett D'Amore /* Skip ahead. */ ; 53795c635efSGarrett D'Amore 53895c635efSGarrett D'Amore return(rc); 53995c635efSGarrett D'Amore } 54095c635efSGarrett D'Amore 54195c635efSGarrett D'Amore /* 54295c635efSGarrett D'Amore * Process a quoted literal. A quote begins with a double-quote 54395c635efSGarrett D'Amore * and ends with a double-quote NOT preceded by a double-quote. 544*698f87a4SGarrett D'Amore * NUL-terminate the literal in place. 545*698f87a4SGarrett D'Amore * Collapse pairs of quotes inside quoted literals. 54695c635efSGarrett D'Amore * Whitespace is NOT involved in literal termination. 54795c635efSGarrett D'Amore */ 54895c635efSGarrett D'Amore 549*698f87a4SGarrett D'Amore if (MDOC_PHRASELIT & mdoc->flags || '\"' == buf[*pos]) { 550*698f87a4SGarrett D'Amore if ( ! (MDOC_PHRASELIT & mdoc->flags)) 55195c635efSGarrett D'Amore *v = &buf[++(*pos)]; 55295c635efSGarrett D'Amore 553*698f87a4SGarrett D'Amore if (MDOC_PPHRASE & mdoc->flags) 554*698f87a4SGarrett D'Amore mdoc->flags |= MDOC_PHRASELIT; 55595c635efSGarrett D'Amore 556*698f87a4SGarrett D'Amore pairs = 0; 55795c635efSGarrett D'Amore for ( ; buf[*pos]; (*pos)++) { 558*698f87a4SGarrett D'Amore /* Move following text left after quoted quotes. */ 559*698f87a4SGarrett D'Amore if (pairs) 560*698f87a4SGarrett D'Amore buf[*pos - pairs] = buf[*pos]; 56195c635efSGarrett D'Amore if ('\"' != buf[*pos]) 56295c635efSGarrett D'Amore continue; 563*698f87a4SGarrett D'Amore /* Unquoted quotes end quoted args. */ 56495c635efSGarrett D'Amore if ('\"' != buf[*pos + 1]) 56595c635efSGarrett D'Amore break; 566*698f87a4SGarrett D'Amore /* Quoted quotes collapse. */ 567*698f87a4SGarrett D'Amore pairs++; 56895c635efSGarrett D'Amore (*pos)++; 56995c635efSGarrett D'Amore } 570*698f87a4SGarrett D'Amore if (pairs) 571*698f87a4SGarrett D'Amore buf[*pos - pairs] = '\0'; 57295c635efSGarrett D'Amore 57395c635efSGarrett D'Amore if ('\0' == buf[*pos]) { 574*698f87a4SGarrett D'Amore if (MDOC_PPHRASE & mdoc->flags) 57595c635efSGarrett D'Amore return(ARGS_QWORD); 576*698f87a4SGarrett D'Amore mdoc_pmsg(mdoc, line, *pos, MANDOCERR_BADQUOTE); 57795c635efSGarrett D'Amore return(ARGS_QWORD); 57895c635efSGarrett D'Amore } 57995c635efSGarrett D'Amore 580*698f87a4SGarrett D'Amore mdoc->flags &= ~MDOC_PHRASELIT; 58195c635efSGarrett D'Amore buf[(*pos)++] = '\0'; 58295c635efSGarrett D'Amore 58395c635efSGarrett D'Amore if ('\0' == buf[*pos]) 58495c635efSGarrett D'Amore return(ARGS_QWORD); 58595c635efSGarrett D'Amore 58695c635efSGarrett D'Amore while (' ' == buf[*pos]) 58795c635efSGarrett D'Amore (*pos)++; 58895c635efSGarrett D'Amore 58995c635efSGarrett D'Amore if ('\0' == buf[*pos]) 590*698f87a4SGarrett D'Amore mdoc_pmsg(mdoc, line, *pos, MANDOCERR_EOLNSPACE); 59195c635efSGarrett D'Amore 59295c635efSGarrett D'Amore return(ARGS_QWORD); 59395c635efSGarrett D'Amore } 59495c635efSGarrett D'Amore 59595c635efSGarrett D'Amore p = &buf[*pos]; 596*698f87a4SGarrett D'Amore *v = mandoc_getarg(mdoc->parse, &p, line, pos); 59795c635efSGarrett D'Amore 59895c635efSGarrett D'Amore return(ARGS_WORD); 59995c635efSGarrett D'Amore } 60095c635efSGarrett D'Amore 60195c635efSGarrett D'Amore /* 60295c635efSGarrett D'Amore * Check if the string consists only of space-separated closing 60395c635efSGarrett D'Amore * delimiters. This is a bit of a dance: the first must be a close 60495c635efSGarrett D'Amore * delimiter, but it may be followed by middle delimiters. Arbitrary 60595c635efSGarrett D'Amore * whitespace may separate these tokens. 60695c635efSGarrett D'Amore */ 60795c635efSGarrett D'Amore static int 60895c635efSGarrett D'Amore args_checkpunct(const char *buf, int i) 60995c635efSGarrett D'Amore { 61095c635efSGarrett D'Amore int j; 61195c635efSGarrett D'Amore char dbuf[DELIMSZ]; 61295c635efSGarrett D'Amore enum mdelim d; 61395c635efSGarrett D'Amore 61495c635efSGarrett D'Amore /* First token must be a close-delimiter. */ 61595c635efSGarrett D'Amore 61695c635efSGarrett D'Amore for (j = 0; buf[i] && ' ' != buf[i] && j < DELIMSZ; j++, i++) 61795c635efSGarrett D'Amore dbuf[j] = buf[i]; 61895c635efSGarrett D'Amore 61995c635efSGarrett D'Amore if (DELIMSZ == j) 62095c635efSGarrett D'Amore return(0); 62195c635efSGarrett D'Amore 62295c635efSGarrett D'Amore dbuf[j] = '\0'; 62395c635efSGarrett D'Amore if (DELIM_CLOSE != mdoc_isdelim(dbuf)) 62495c635efSGarrett D'Amore return(0); 62595c635efSGarrett D'Amore 62695c635efSGarrett D'Amore while (' ' == buf[i]) 62795c635efSGarrett D'Amore i++; 62895c635efSGarrett D'Amore 62995c635efSGarrett D'Amore /* Remaining must NOT be open/none. */ 63095c635efSGarrett D'Amore 63195c635efSGarrett D'Amore while (buf[i]) { 63295c635efSGarrett D'Amore j = 0; 63395c635efSGarrett D'Amore while (buf[i] && ' ' != buf[i] && j < DELIMSZ) 63495c635efSGarrett D'Amore dbuf[j++] = buf[i++]; 63595c635efSGarrett D'Amore 63695c635efSGarrett D'Amore if (DELIMSZ == j) 63795c635efSGarrett D'Amore return(0); 63895c635efSGarrett D'Amore 63995c635efSGarrett D'Amore dbuf[j] = '\0'; 64095c635efSGarrett D'Amore d = mdoc_isdelim(dbuf); 64195c635efSGarrett D'Amore if (DELIM_NONE == d || DELIM_OPEN == d) 64295c635efSGarrett D'Amore return(0); 64395c635efSGarrett D'Amore 64495c635efSGarrett D'Amore while (' ' == buf[i]) 64595c635efSGarrett D'Amore i++; 64695c635efSGarrett D'Amore } 64795c635efSGarrett D'Amore 64895c635efSGarrett D'Amore return('\0' == buf[i]); 64995c635efSGarrett D'Amore } 65095c635efSGarrett D'Amore 65195c635efSGarrett D'Amore static int 652*698f87a4SGarrett D'Amore argv_multi(struct mdoc *mdoc, int line, 65395c635efSGarrett D'Amore struct mdoc_argv *v, int *pos, char *buf) 65495c635efSGarrett D'Amore { 65595c635efSGarrett D'Amore enum margserr ac; 65695c635efSGarrett D'Amore char *p; 65795c635efSGarrett D'Amore 65895c635efSGarrett D'Amore for (v->sz = 0; ; v->sz++) { 65995c635efSGarrett D'Amore if ('-' == buf[*pos]) 66095c635efSGarrett D'Amore break; 661*698f87a4SGarrett D'Amore ac = args(mdoc, line, pos, buf, ARGSFL_NONE, &p); 66295c635efSGarrett D'Amore if (ARGS_ERROR == ac) 66395c635efSGarrett D'Amore return(0); 66495c635efSGarrett D'Amore else if (ARGS_EOLN == ac) 66595c635efSGarrett D'Amore break; 66695c635efSGarrett D'Amore 66795c635efSGarrett D'Amore if (0 == v->sz % MULTI_STEP) 66895c635efSGarrett D'Amore v->value = mandoc_realloc(v->value, 66995c635efSGarrett D'Amore (v->sz + MULTI_STEP) * sizeof(char *)); 67095c635efSGarrett D'Amore 67195c635efSGarrett D'Amore v->value[(int)v->sz] = mandoc_strdup(p); 67295c635efSGarrett D'Amore } 67395c635efSGarrett D'Amore 67495c635efSGarrett D'Amore return(1); 67595c635efSGarrett D'Amore } 67695c635efSGarrett D'Amore 67795c635efSGarrett D'Amore static int 678*698f87a4SGarrett D'Amore argv_single(struct mdoc *mdoc, int line, 67995c635efSGarrett D'Amore struct mdoc_argv *v, int *pos, char *buf) 68095c635efSGarrett D'Amore { 68195c635efSGarrett D'Amore enum margserr ac; 68295c635efSGarrett D'Amore char *p; 68395c635efSGarrett D'Amore 684*698f87a4SGarrett D'Amore ac = args(mdoc, line, pos, buf, ARGSFL_NONE, &p); 68595c635efSGarrett D'Amore if (ARGS_ERROR == ac) 68695c635efSGarrett D'Amore return(0); 68795c635efSGarrett D'Amore if (ARGS_EOLN == ac) 68895c635efSGarrett D'Amore return(1); 68995c635efSGarrett D'Amore 69095c635efSGarrett D'Amore v->sz = 1; 69195c635efSGarrett D'Amore v->value = mandoc_malloc(sizeof(char *)); 69295c635efSGarrett D'Amore v->value[0] = mandoc_strdup(p); 69395c635efSGarrett D'Amore 69495c635efSGarrett D'Amore return(1); 69595c635efSGarrett D'Amore } 696