1*95c635efSGarrett D'Amore /* $Id: mdoc_argv.c,v 1.82 2012/03/23 05:50:24 kristaps Exp $ */ 2*95c635efSGarrett D'Amore /* 3*95c635efSGarrett D'Amore * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> 4*95c635efSGarrett D'Amore * 5*95c635efSGarrett D'Amore * Permission to use, copy, modify, and distribute this software for any 6*95c635efSGarrett D'Amore * purpose with or without fee is hereby granted, provided that the above 7*95c635efSGarrett D'Amore * copyright notice and this permission notice appear in all copies. 8*95c635efSGarrett D'Amore * 9*95c635efSGarrett D'Amore * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10*95c635efSGarrett D'Amore * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11*95c635efSGarrett D'Amore * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12*95c635efSGarrett D'Amore * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13*95c635efSGarrett D'Amore * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14*95c635efSGarrett D'Amore * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15*95c635efSGarrett D'Amore * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16*95c635efSGarrett D'Amore */ 17*95c635efSGarrett D'Amore #ifdef HAVE_CONFIG_H 18*95c635efSGarrett D'Amore #include "config.h" 19*95c635efSGarrett D'Amore #endif 20*95c635efSGarrett D'Amore 21*95c635efSGarrett D'Amore #include <sys/types.h> 22*95c635efSGarrett D'Amore 23*95c635efSGarrett D'Amore #include <assert.h> 24*95c635efSGarrett D'Amore #include <stdlib.h> 25*95c635efSGarrett D'Amore #include <stdio.h> 26*95c635efSGarrett D'Amore #include <string.h> 27*95c635efSGarrett D'Amore 28*95c635efSGarrett D'Amore #include "mdoc.h" 29*95c635efSGarrett D'Amore #include "mandoc.h" 30*95c635efSGarrett D'Amore #include "libmdoc.h" 31*95c635efSGarrett D'Amore #include "libmandoc.h" 32*95c635efSGarrett D'Amore 33*95c635efSGarrett D'Amore #define MULTI_STEP 5 /* pre-allocate argument values */ 34*95c635efSGarrett D'Amore #define DELIMSZ 6 /* max possible size of a delimiter */ 35*95c635efSGarrett D'Amore 36*95c635efSGarrett D'Amore enum argsflag { 37*95c635efSGarrett D'Amore ARGSFL_NONE = 0, 38*95c635efSGarrett D'Amore ARGSFL_DELIM, /* handle delimiters of [[::delim::][ ]+]+ */ 39*95c635efSGarrett D'Amore ARGSFL_TABSEP /* handle tab/`Ta' separated phrases */ 40*95c635efSGarrett D'Amore }; 41*95c635efSGarrett D'Amore 42*95c635efSGarrett D'Amore enum argvflag { 43*95c635efSGarrett D'Amore ARGV_NONE, /* no args to flag (e.g., -split) */ 44*95c635efSGarrett D'Amore ARGV_SINGLE, /* one arg to flag (e.g., -file xxx) */ 45*95c635efSGarrett D'Amore ARGV_MULTI, /* multiple args (e.g., -column xxx yyy) */ 46*95c635efSGarrett D'Amore ARGV_OPT_SINGLE /* optional arg (e.g., -offset [xxx]) */ 47*95c635efSGarrett D'Amore }; 48*95c635efSGarrett D'Amore 49*95c635efSGarrett D'Amore struct mdocarg { 50*95c635efSGarrett D'Amore enum argsflag flags; 51*95c635efSGarrett D'Amore const enum mdocargt *argvs; 52*95c635efSGarrett D'Amore }; 53*95c635efSGarrett D'Amore 54*95c635efSGarrett D'Amore static void argn_free(struct mdoc_arg *, int); 55*95c635efSGarrett D'Amore static enum margserr args(struct mdoc *, int, int *, 56*95c635efSGarrett D'Amore char *, enum argsflag, char **); 57*95c635efSGarrett D'Amore static int args_checkpunct(const char *, int); 58*95c635efSGarrett D'Amore static int argv_multi(struct mdoc *, int, 59*95c635efSGarrett D'Amore struct mdoc_argv *, int *, char *); 60*95c635efSGarrett D'Amore static int argv_opt_single(struct mdoc *, int, 61*95c635efSGarrett D'Amore struct mdoc_argv *, int *, char *); 62*95c635efSGarrett D'Amore static int argv_single(struct mdoc *, int, 63*95c635efSGarrett D'Amore struct mdoc_argv *, int *, char *); 64*95c635efSGarrett D'Amore 65*95c635efSGarrett D'Amore static const enum argvflag argvflags[MDOC_ARG_MAX] = { 66*95c635efSGarrett D'Amore ARGV_NONE, /* MDOC_Split */ 67*95c635efSGarrett D'Amore ARGV_NONE, /* MDOC_Nosplit */ 68*95c635efSGarrett D'Amore ARGV_NONE, /* MDOC_Ragged */ 69*95c635efSGarrett D'Amore ARGV_NONE, /* MDOC_Unfilled */ 70*95c635efSGarrett D'Amore ARGV_NONE, /* MDOC_Literal */ 71*95c635efSGarrett D'Amore ARGV_SINGLE, /* MDOC_File */ 72*95c635efSGarrett D'Amore ARGV_OPT_SINGLE, /* MDOC_Offset */ 73*95c635efSGarrett D'Amore ARGV_NONE, /* MDOC_Bullet */ 74*95c635efSGarrett D'Amore ARGV_NONE, /* MDOC_Dash */ 75*95c635efSGarrett D'Amore ARGV_NONE, /* MDOC_Hyphen */ 76*95c635efSGarrett D'Amore ARGV_NONE, /* MDOC_Item */ 77*95c635efSGarrett D'Amore ARGV_NONE, /* MDOC_Enum */ 78*95c635efSGarrett D'Amore ARGV_NONE, /* MDOC_Tag */ 79*95c635efSGarrett D'Amore ARGV_NONE, /* MDOC_Diag */ 80*95c635efSGarrett D'Amore ARGV_NONE, /* MDOC_Hang */ 81*95c635efSGarrett D'Amore ARGV_NONE, /* MDOC_Ohang */ 82*95c635efSGarrett D'Amore ARGV_NONE, /* MDOC_Inset */ 83*95c635efSGarrett D'Amore ARGV_MULTI, /* MDOC_Column */ 84*95c635efSGarrett D'Amore ARGV_OPT_SINGLE, /* MDOC_Width */ 85*95c635efSGarrett D'Amore ARGV_NONE, /* MDOC_Compact */ 86*95c635efSGarrett D'Amore ARGV_NONE, /* MDOC_Std */ 87*95c635efSGarrett D'Amore ARGV_NONE, /* MDOC_Filled */ 88*95c635efSGarrett D'Amore ARGV_NONE, /* MDOC_Words */ 89*95c635efSGarrett D'Amore ARGV_NONE, /* MDOC_Emphasis */ 90*95c635efSGarrett D'Amore ARGV_NONE, /* MDOC_Symbolic */ 91*95c635efSGarrett D'Amore ARGV_NONE /* MDOC_Symbolic */ 92*95c635efSGarrett D'Amore }; 93*95c635efSGarrett D'Amore 94*95c635efSGarrett D'Amore static const enum mdocargt args_Ex[] = { 95*95c635efSGarrett D'Amore MDOC_Std, 96*95c635efSGarrett D'Amore MDOC_ARG_MAX 97*95c635efSGarrett D'Amore }; 98*95c635efSGarrett D'Amore 99*95c635efSGarrett D'Amore static const enum mdocargt args_An[] = { 100*95c635efSGarrett D'Amore MDOC_Split, 101*95c635efSGarrett D'Amore MDOC_Nosplit, 102*95c635efSGarrett D'Amore MDOC_ARG_MAX 103*95c635efSGarrett D'Amore }; 104*95c635efSGarrett D'Amore 105*95c635efSGarrett D'Amore static const enum mdocargt args_Bd[] = { 106*95c635efSGarrett D'Amore MDOC_Ragged, 107*95c635efSGarrett D'Amore MDOC_Unfilled, 108*95c635efSGarrett D'Amore MDOC_Filled, 109*95c635efSGarrett D'Amore MDOC_Literal, 110*95c635efSGarrett D'Amore MDOC_File, 111*95c635efSGarrett D'Amore MDOC_Offset, 112*95c635efSGarrett D'Amore MDOC_Compact, 113*95c635efSGarrett D'Amore MDOC_Centred, 114*95c635efSGarrett D'Amore MDOC_ARG_MAX 115*95c635efSGarrett D'Amore }; 116*95c635efSGarrett D'Amore 117*95c635efSGarrett D'Amore static const enum mdocargt args_Bf[] = { 118*95c635efSGarrett D'Amore MDOC_Emphasis, 119*95c635efSGarrett D'Amore MDOC_Literal, 120*95c635efSGarrett D'Amore MDOC_Symbolic, 121*95c635efSGarrett D'Amore MDOC_ARG_MAX 122*95c635efSGarrett D'Amore }; 123*95c635efSGarrett D'Amore 124*95c635efSGarrett D'Amore static const enum mdocargt args_Bk[] = { 125*95c635efSGarrett D'Amore MDOC_Words, 126*95c635efSGarrett D'Amore MDOC_ARG_MAX 127*95c635efSGarrett D'Amore }; 128*95c635efSGarrett D'Amore 129*95c635efSGarrett D'Amore static const enum mdocargt args_Bl[] = { 130*95c635efSGarrett D'Amore MDOC_Bullet, 131*95c635efSGarrett D'Amore MDOC_Dash, 132*95c635efSGarrett D'Amore MDOC_Hyphen, 133*95c635efSGarrett D'Amore MDOC_Item, 134*95c635efSGarrett D'Amore MDOC_Enum, 135*95c635efSGarrett D'Amore MDOC_Tag, 136*95c635efSGarrett D'Amore MDOC_Diag, 137*95c635efSGarrett D'Amore MDOC_Hang, 138*95c635efSGarrett D'Amore MDOC_Ohang, 139*95c635efSGarrett D'Amore MDOC_Inset, 140*95c635efSGarrett D'Amore MDOC_Column, 141*95c635efSGarrett D'Amore MDOC_Width, 142*95c635efSGarrett D'Amore MDOC_Offset, 143*95c635efSGarrett D'Amore MDOC_Compact, 144*95c635efSGarrett D'Amore MDOC_Nested, 145*95c635efSGarrett D'Amore MDOC_ARG_MAX 146*95c635efSGarrett D'Amore }; 147*95c635efSGarrett D'Amore 148*95c635efSGarrett D'Amore static const struct mdocarg mdocargs[MDOC_MAX] = { 149*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Ap */ 150*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Dd */ 151*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Dt */ 152*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Os */ 153*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Sh */ 154*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Ss */ 155*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Pp */ 156*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* D1 */ 157*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Dl */ 158*95c635efSGarrett D'Amore { ARGSFL_NONE, args_Bd }, /* Bd */ 159*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Ed */ 160*95c635efSGarrett D'Amore { ARGSFL_NONE, args_Bl }, /* Bl */ 161*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* El */ 162*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* It */ 163*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Ad */ 164*95c635efSGarrett D'Amore { ARGSFL_DELIM, args_An }, /* An */ 165*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Ar */ 166*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Cd */ 167*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Cm */ 168*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Dv */ 169*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Er */ 170*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Ev */ 171*95c635efSGarrett D'Amore { ARGSFL_NONE, args_Ex }, /* Ex */ 172*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Fa */ 173*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Fd */ 174*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Fl */ 175*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Fn */ 176*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Ft */ 177*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Ic */ 178*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* In */ 179*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Li */ 180*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Nd */ 181*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Nm */ 182*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Op */ 183*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Ot */ 184*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Pa */ 185*95c635efSGarrett D'Amore { ARGSFL_NONE, args_Ex }, /* Rv */ 186*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* St */ 187*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Va */ 188*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Vt */ 189*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Xr */ 190*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* %A */ 191*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* %B */ 192*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* %D */ 193*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* %I */ 194*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* %J */ 195*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* %N */ 196*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* %O */ 197*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* %P */ 198*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* %R */ 199*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* %T */ 200*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* %V */ 201*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Ac */ 202*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Ao */ 203*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Aq */ 204*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* At */ 205*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Bc */ 206*95c635efSGarrett D'Amore { ARGSFL_NONE, args_Bf }, /* Bf */ 207*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Bo */ 208*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Bq */ 209*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Bsx */ 210*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Bx */ 211*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Db */ 212*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Dc */ 213*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Do */ 214*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Dq */ 215*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Ec */ 216*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Ef */ 217*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Em */ 218*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Eo */ 219*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Fx */ 220*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Ms */ 221*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* No */ 222*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Ns */ 223*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Nx */ 224*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Ox */ 225*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Pc */ 226*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Pf */ 227*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Po */ 228*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Pq */ 229*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Qc */ 230*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Ql */ 231*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Qo */ 232*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Qq */ 233*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Re */ 234*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Rs */ 235*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Sc */ 236*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* So */ 237*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Sq */ 238*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Sm */ 239*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Sx */ 240*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Sy */ 241*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Tn */ 242*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Ux */ 243*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Xc */ 244*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Xo */ 245*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Fo */ 246*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Fc */ 247*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Oo */ 248*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Oc */ 249*95c635efSGarrett D'Amore { ARGSFL_NONE, args_Bk }, /* Bk */ 250*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Ek */ 251*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Bt */ 252*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Hf */ 253*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Fr */ 254*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Ud */ 255*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Lb */ 256*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Lp */ 257*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Lk */ 258*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Mt */ 259*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Brq */ 260*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Bro */ 261*95c635efSGarrett D'Amore { ARGSFL_DELIM, NULL }, /* Brc */ 262*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* %C */ 263*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Es */ 264*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* En */ 265*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Dx */ 266*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* %Q */ 267*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* br */ 268*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* sp */ 269*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* %U */ 270*95c635efSGarrett D'Amore { ARGSFL_NONE, NULL }, /* Ta */ 271*95c635efSGarrett D'Amore }; 272*95c635efSGarrett D'Amore 273*95c635efSGarrett D'Amore 274*95c635efSGarrett D'Amore /* 275*95c635efSGarrett D'Amore * Parse an argument from line text. This comes in the form of -key 276*95c635efSGarrett D'Amore * [value0...], which may either have a single mandatory value, at least 277*95c635efSGarrett D'Amore * one mandatory value, an optional single value, or no value. 278*95c635efSGarrett D'Amore */ 279*95c635efSGarrett D'Amore enum margverr 280*95c635efSGarrett D'Amore mdoc_argv(struct mdoc *m, int line, enum mdoct tok, 281*95c635efSGarrett D'Amore struct mdoc_arg **v, int *pos, char *buf) 282*95c635efSGarrett D'Amore { 283*95c635efSGarrett D'Amore char *p, sv; 284*95c635efSGarrett D'Amore struct mdoc_argv tmp; 285*95c635efSGarrett D'Amore struct mdoc_arg *arg; 286*95c635efSGarrett D'Amore const enum mdocargt *ap; 287*95c635efSGarrett D'Amore 288*95c635efSGarrett D'Amore if ('\0' == buf[*pos]) 289*95c635efSGarrett D'Amore return(ARGV_EOLN); 290*95c635efSGarrett D'Amore else if (NULL == (ap = mdocargs[tok].argvs)) 291*95c635efSGarrett D'Amore return(ARGV_WORD); 292*95c635efSGarrett D'Amore else if ('-' != buf[*pos]) 293*95c635efSGarrett D'Amore return(ARGV_WORD); 294*95c635efSGarrett D'Amore 295*95c635efSGarrett D'Amore /* Seek to the first unescaped space. */ 296*95c635efSGarrett D'Amore 297*95c635efSGarrett D'Amore p = &buf[++(*pos)]; 298*95c635efSGarrett D'Amore 299*95c635efSGarrett D'Amore assert(*pos > 0); 300*95c635efSGarrett D'Amore 301*95c635efSGarrett D'Amore for ( ; buf[*pos] ; (*pos)++) 302*95c635efSGarrett D'Amore if (' ' == buf[*pos] && '\\' != buf[*pos - 1]) 303*95c635efSGarrett D'Amore break; 304*95c635efSGarrett D'Amore 305*95c635efSGarrett D'Amore /* 306*95c635efSGarrett D'Amore * We want to nil-terminate the word to look it up (it's easier 307*95c635efSGarrett D'Amore * that way). But we may not have a flag, in which case we need 308*95c635efSGarrett D'Amore * to restore the line as-is. So keep around the stray byte, 309*95c635efSGarrett D'Amore * which we'll reset upon exiting (if necessary). 310*95c635efSGarrett D'Amore */ 311*95c635efSGarrett D'Amore 312*95c635efSGarrett D'Amore if ('\0' != (sv = buf[*pos])) 313*95c635efSGarrett D'Amore buf[(*pos)++] = '\0'; 314*95c635efSGarrett D'Amore 315*95c635efSGarrett D'Amore /* 316*95c635efSGarrett D'Amore * Now look up the word as a flag. Use temporary storage that 317*95c635efSGarrett D'Amore * we'll copy into the node's flags, if necessary. 318*95c635efSGarrett D'Amore */ 319*95c635efSGarrett D'Amore 320*95c635efSGarrett D'Amore memset(&tmp, 0, sizeof(struct mdoc_argv)); 321*95c635efSGarrett D'Amore 322*95c635efSGarrett D'Amore tmp.line = line; 323*95c635efSGarrett D'Amore tmp.pos = *pos; 324*95c635efSGarrett D'Amore tmp.arg = MDOC_ARG_MAX; 325*95c635efSGarrett D'Amore 326*95c635efSGarrett D'Amore while (MDOC_ARG_MAX != (tmp.arg = *ap++)) 327*95c635efSGarrett D'Amore if (0 == strcmp(p, mdoc_argnames[tmp.arg])) 328*95c635efSGarrett D'Amore break; 329*95c635efSGarrett D'Amore 330*95c635efSGarrett D'Amore if (MDOC_ARG_MAX == tmp.arg) { 331*95c635efSGarrett D'Amore /* 332*95c635efSGarrett D'Amore * The flag was not found. 333*95c635efSGarrett D'Amore * Restore saved zeroed byte and return as a word. 334*95c635efSGarrett D'Amore */ 335*95c635efSGarrett D'Amore if (sv) 336*95c635efSGarrett D'Amore buf[*pos - 1] = sv; 337*95c635efSGarrett D'Amore return(ARGV_WORD); 338*95c635efSGarrett D'Amore } 339*95c635efSGarrett D'Amore 340*95c635efSGarrett D'Amore /* Read to the next word (the argument). */ 341*95c635efSGarrett D'Amore 342*95c635efSGarrett D'Amore while (buf[*pos] && ' ' == buf[*pos]) 343*95c635efSGarrett D'Amore (*pos)++; 344*95c635efSGarrett D'Amore 345*95c635efSGarrett D'Amore switch (argvflags[tmp.arg]) { 346*95c635efSGarrett D'Amore case (ARGV_SINGLE): 347*95c635efSGarrett D'Amore if ( ! argv_single(m, line, &tmp, pos, buf)) 348*95c635efSGarrett D'Amore return(ARGV_ERROR); 349*95c635efSGarrett D'Amore break; 350*95c635efSGarrett D'Amore case (ARGV_MULTI): 351*95c635efSGarrett D'Amore if ( ! argv_multi(m, line, &tmp, pos, buf)) 352*95c635efSGarrett D'Amore return(ARGV_ERROR); 353*95c635efSGarrett D'Amore break; 354*95c635efSGarrett D'Amore case (ARGV_OPT_SINGLE): 355*95c635efSGarrett D'Amore if ( ! argv_opt_single(m, line, &tmp, pos, buf)) 356*95c635efSGarrett D'Amore return(ARGV_ERROR); 357*95c635efSGarrett D'Amore break; 358*95c635efSGarrett D'Amore case (ARGV_NONE): 359*95c635efSGarrett D'Amore break; 360*95c635efSGarrett D'Amore } 361*95c635efSGarrett D'Amore 362*95c635efSGarrett D'Amore if (NULL == (arg = *v)) 363*95c635efSGarrett D'Amore arg = *v = mandoc_calloc(1, sizeof(struct mdoc_arg)); 364*95c635efSGarrett D'Amore 365*95c635efSGarrett D'Amore arg->argc++; 366*95c635efSGarrett D'Amore arg->argv = mandoc_realloc 367*95c635efSGarrett D'Amore (arg->argv, arg->argc * sizeof(struct mdoc_argv)); 368*95c635efSGarrett D'Amore 369*95c635efSGarrett D'Amore memcpy(&arg->argv[(int)arg->argc - 1], 370*95c635efSGarrett D'Amore &tmp, sizeof(struct mdoc_argv)); 371*95c635efSGarrett D'Amore 372*95c635efSGarrett D'Amore return(ARGV_ARG); 373*95c635efSGarrett D'Amore } 374*95c635efSGarrett D'Amore 375*95c635efSGarrett D'Amore void 376*95c635efSGarrett D'Amore mdoc_argv_free(struct mdoc_arg *p) 377*95c635efSGarrett D'Amore { 378*95c635efSGarrett D'Amore int i; 379*95c635efSGarrett D'Amore 380*95c635efSGarrett D'Amore if (NULL == p) 381*95c635efSGarrett D'Amore return; 382*95c635efSGarrett D'Amore 383*95c635efSGarrett D'Amore if (p->refcnt) { 384*95c635efSGarrett D'Amore --(p->refcnt); 385*95c635efSGarrett D'Amore if (p->refcnt) 386*95c635efSGarrett D'Amore return; 387*95c635efSGarrett D'Amore } 388*95c635efSGarrett D'Amore assert(p->argc); 389*95c635efSGarrett D'Amore 390*95c635efSGarrett D'Amore for (i = (int)p->argc - 1; i >= 0; i--) 391*95c635efSGarrett D'Amore argn_free(p, i); 392*95c635efSGarrett D'Amore 393*95c635efSGarrett D'Amore free(p->argv); 394*95c635efSGarrett D'Amore free(p); 395*95c635efSGarrett D'Amore } 396*95c635efSGarrett D'Amore 397*95c635efSGarrett D'Amore static void 398*95c635efSGarrett D'Amore argn_free(struct mdoc_arg *p, int iarg) 399*95c635efSGarrett D'Amore { 400*95c635efSGarrett D'Amore struct mdoc_argv *arg; 401*95c635efSGarrett D'Amore int j; 402*95c635efSGarrett D'Amore 403*95c635efSGarrett D'Amore arg = &p->argv[iarg]; 404*95c635efSGarrett D'Amore 405*95c635efSGarrett D'Amore if (arg->sz && arg->value) { 406*95c635efSGarrett D'Amore for (j = (int)arg->sz - 1; j >= 0; j--) 407*95c635efSGarrett D'Amore free(arg->value[j]); 408*95c635efSGarrett D'Amore free(arg->value); 409*95c635efSGarrett D'Amore } 410*95c635efSGarrett D'Amore 411*95c635efSGarrett D'Amore for (--p->argc; iarg < (int)p->argc; iarg++) 412*95c635efSGarrett D'Amore p->argv[iarg] = p->argv[iarg+1]; 413*95c635efSGarrett D'Amore } 414*95c635efSGarrett D'Amore 415*95c635efSGarrett D'Amore enum margserr 416*95c635efSGarrett D'Amore mdoc_zargs(struct mdoc *m, int line, int *pos, char *buf, char **v) 417*95c635efSGarrett D'Amore { 418*95c635efSGarrett D'Amore 419*95c635efSGarrett D'Amore return(args(m, line, pos, buf, ARGSFL_NONE, v)); 420*95c635efSGarrett D'Amore } 421*95c635efSGarrett D'Amore 422*95c635efSGarrett D'Amore enum margserr 423*95c635efSGarrett D'Amore mdoc_args(struct mdoc *m, int line, int *pos, 424*95c635efSGarrett D'Amore char *buf, enum mdoct tok, char **v) 425*95c635efSGarrett D'Amore { 426*95c635efSGarrett D'Amore enum argsflag fl; 427*95c635efSGarrett D'Amore struct mdoc_node *n; 428*95c635efSGarrett D'Amore 429*95c635efSGarrett D'Amore fl = mdocargs[tok].flags; 430*95c635efSGarrett D'Amore 431*95c635efSGarrett D'Amore if (MDOC_It != tok) 432*95c635efSGarrett D'Amore return(args(m, line, pos, buf, fl, v)); 433*95c635efSGarrett D'Amore 434*95c635efSGarrett D'Amore /* 435*95c635efSGarrett D'Amore * We know that we're in an `It', so it's reasonable to expect 436*95c635efSGarrett D'Amore * us to be sitting in a `Bl'. Someday this may not be the case 437*95c635efSGarrett D'Amore * (if we allow random `It's sitting out there), so provide a 438*95c635efSGarrett D'Amore * safe fall-back into the default behaviour. 439*95c635efSGarrett D'Amore */ 440*95c635efSGarrett D'Amore 441*95c635efSGarrett D'Amore for (n = m->last; n; n = n->parent) 442*95c635efSGarrett D'Amore if (MDOC_Bl == n->tok) 443*95c635efSGarrett D'Amore if (LIST_column == n->norm->Bl.type) { 444*95c635efSGarrett D'Amore fl = ARGSFL_TABSEP; 445*95c635efSGarrett D'Amore break; 446*95c635efSGarrett D'Amore } 447*95c635efSGarrett D'Amore 448*95c635efSGarrett D'Amore return(args(m, line, pos, buf, fl, v)); 449*95c635efSGarrett D'Amore } 450*95c635efSGarrett D'Amore 451*95c635efSGarrett D'Amore static enum margserr 452*95c635efSGarrett D'Amore args(struct mdoc *m, int line, int *pos, 453*95c635efSGarrett D'Amore char *buf, enum argsflag fl, char **v) 454*95c635efSGarrett D'Amore { 455*95c635efSGarrett D'Amore char *p, *pp; 456*95c635efSGarrett D'Amore enum margserr rc; 457*95c635efSGarrett D'Amore 458*95c635efSGarrett D'Amore if ('\0' == buf[*pos]) { 459*95c635efSGarrett D'Amore if (MDOC_PPHRASE & m->flags) 460*95c635efSGarrett D'Amore return(ARGS_EOLN); 461*95c635efSGarrett D'Amore /* 462*95c635efSGarrett D'Amore * If we're not in a partial phrase and the flag for 463*95c635efSGarrett D'Amore * being a phrase literal is still set, the punctuation 464*95c635efSGarrett D'Amore * is unterminated. 465*95c635efSGarrett D'Amore */ 466*95c635efSGarrett D'Amore if (MDOC_PHRASELIT & m->flags) 467*95c635efSGarrett D'Amore mdoc_pmsg(m, line, *pos, MANDOCERR_BADQUOTE); 468*95c635efSGarrett D'Amore 469*95c635efSGarrett D'Amore m->flags &= ~MDOC_PHRASELIT; 470*95c635efSGarrett D'Amore return(ARGS_EOLN); 471*95c635efSGarrett D'Amore } 472*95c635efSGarrett D'Amore 473*95c635efSGarrett D'Amore *v = &buf[*pos]; 474*95c635efSGarrett D'Amore 475*95c635efSGarrett D'Amore if (ARGSFL_DELIM == fl) 476*95c635efSGarrett D'Amore if (args_checkpunct(buf, *pos)) 477*95c635efSGarrett D'Amore return(ARGS_PUNCT); 478*95c635efSGarrett D'Amore 479*95c635efSGarrett D'Amore /* 480*95c635efSGarrett D'Amore * First handle TABSEP items, restricted to `Bl -column'. This 481*95c635efSGarrett D'Amore * ignores conventional token parsing and instead uses tabs or 482*95c635efSGarrett D'Amore * `Ta' macros to separate phrases. Phrases are parsed again 483*95c635efSGarrett D'Amore * for arguments at a later phase. 484*95c635efSGarrett D'Amore */ 485*95c635efSGarrett D'Amore 486*95c635efSGarrett D'Amore if (ARGSFL_TABSEP == fl) { 487*95c635efSGarrett D'Amore /* Scan ahead to tab (can't be escaped). */ 488*95c635efSGarrett D'Amore p = strchr(*v, '\t'); 489*95c635efSGarrett D'Amore pp = NULL; 490*95c635efSGarrett D'Amore 491*95c635efSGarrett D'Amore /* Scan ahead to unescaped `Ta'. */ 492*95c635efSGarrett D'Amore if ( ! (MDOC_PHRASELIT & m->flags)) 493*95c635efSGarrett D'Amore for (pp = *v; ; pp++) { 494*95c635efSGarrett D'Amore if (NULL == (pp = strstr(pp, "Ta"))) 495*95c635efSGarrett D'Amore break; 496*95c635efSGarrett D'Amore if (pp > *v && ' ' != *(pp - 1)) 497*95c635efSGarrett D'Amore continue; 498*95c635efSGarrett D'Amore if (' ' == *(pp + 2) || '\0' == *(pp + 2)) 499*95c635efSGarrett D'Amore break; 500*95c635efSGarrett D'Amore } 501*95c635efSGarrett D'Amore 502*95c635efSGarrett D'Amore /* By default, assume a phrase. */ 503*95c635efSGarrett D'Amore rc = ARGS_PHRASE; 504*95c635efSGarrett D'Amore 505*95c635efSGarrett D'Amore /* 506*95c635efSGarrett D'Amore * Adjust new-buffer position to be beyond delimiter 507*95c635efSGarrett D'Amore * mark (e.g., Ta -> end + 2). 508*95c635efSGarrett D'Amore */ 509*95c635efSGarrett D'Amore if (p && pp) { 510*95c635efSGarrett D'Amore *pos += pp < p ? 2 : 1; 511*95c635efSGarrett D'Amore rc = pp < p ? ARGS_PHRASE : ARGS_PPHRASE; 512*95c635efSGarrett D'Amore p = pp < p ? pp : p; 513*95c635efSGarrett D'Amore } else if (p && ! pp) { 514*95c635efSGarrett D'Amore rc = ARGS_PPHRASE; 515*95c635efSGarrett D'Amore *pos += 1; 516*95c635efSGarrett D'Amore } else if (pp && ! p) { 517*95c635efSGarrett D'Amore p = pp; 518*95c635efSGarrett D'Amore *pos += 2; 519*95c635efSGarrett D'Amore } else { 520*95c635efSGarrett D'Amore rc = ARGS_PEND; 521*95c635efSGarrett D'Amore p = strchr(*v, 0); 522*95c635efSGarrett D'Amore } 523*95c635efSGarrett D'Amore 524*95c635efSGarrett D'Amore /* Whitespace check for eoln case... */ 525*95c635efSGarrett D'Amore if ('\0' == *p && ' ' == *(p - 1)) 526*95c635efSGarrett D'Amore mdoc_pmsg(m, line, *pos, MANDOCERR_EOLNSPACE); 527*95c635efSGarrett D'Amore 528*95c635efSGarrett D'Amore *pos += (int)(p - *v); 529*95c635efSGarrett D'Amore 530*95c635efSGarrett D'Amore /* Strip delimiter's preceding whitespace. */ 531*95c635efSGarrett D'Amore pp = p - 1; 532*95c635efSGarrett D'Amore while (pp > *v && ' ' == *pp) { 533*95c635efSGarrett D'Amore if (pp > *v && '\\' == *(pp - 1)) 534*95c635efSGarrett D'Amore break; 535*95c635efSGarrett D'Amore pp--; 536*95c635efSGarrett D'Amore } 537*95c635efSGarrett D'Amore *(pp + 1) = 0; 538*95c635efSGarrett D'Amore 539*95c635efSGarrett D'Amore /* Strip delimiter's proceeding whitespace. */ 540*95c635efSGarrett D'Amore for (pp = &buf[*pos]; ' ' == *pp; pp++, (*pos)++) 541*95c635efSGarrett D'Amore /* Skip ahead. */ ; 542*95c635efSGarrett D'Amore 543*95c635efSGarrett D'Amore return(rc); 544*95c635efSGarrett D'Amore } 545*95c635efSGarrett D'Amore 546*95c635efSGarrett D'Amore /* 547*95c635efSGarrett D'Amore * Process a quoted literal. A quote begins with a double-quote 548*95c635efSGarrett D'Amore * and ends with a double-quote NOT preceded by a double-quote. 549*95c635efSGarrett D'Amore * Whitespace is NOT involved in literal termination. 550*95c635efSGarrett D'Amore */ 551*95c635efSGarrett D'Amore 552*95c635efSGarrett D'Amore if (MDOC_PHRASELIT & m->flags || '\"' == buf[*pos]) { 553*95c635efSGarrett D'Amore if ( ! (MDOC_PHRASELIT & m->flags)) 554*95c635efSGarrett D'Amore *v = &buf[++(*pos)]; 555*95c635efSGarrett D'Amore 556*95c635efSGarrett D'Amore if (MDOC_PPHRASE & m->flags) 557*95c635efSGarrett D'Amore m->flags |= MDOC_PHRASELIT; 558*95c635efSGarrett D'Amore 559*95c635efSGarrett D'Amore for ( ; buf[*pos]; (*pos)++) { 560*95c635efSGarrett D'Amore if ('\"' != buf[*pos]) 561*95c635efSGarrett D'Amore continue; 562*95c635efSGarrett D'Amore if ('\"' != buf[*pos + 1]) 563*95c635efSGarrett D'Amore break; 564*95c635efSGarrett D'Amore (*pos)++; 565*95c635efSGarrett D'Amore } 566*95c635efSGarrett D'Amore 567*95c635efSGarrett D'Amore if ('\0' == buf[*pos]) { 568*95c635efSGarrett D'Amore if (MDOC_PPHRASE & m->flags) 569*95c635efSGarrett D'Amore return(ARGS_QWORD); 570*95c635efSGarrett D'Amore mdoc_pmsg(m, line, *pos, MANDOCERR_BADQUOTE); 571*95c635efSGarrett D'Amore return(ARGS_QWORD); 572*95c635efSGarrett D'Amore } 573*95c635efSGarrett D'Amore 574*95c635efSGarrett D'Amore m->flags &= ~MDOC_PHRASELIT; 575*95c635efSGarrett D'Amore buf[(*pos)++] = '\0'; 576*95c635efSGarrett D'Amore 577*95c635efSGarrett D'Amore if ('\0' == buf[*pos]) 578*95c635efSGarrett D'Amore return(ARGS_QWORD); 579*95c635efSGarrett D'Amore 580*95c635efSGarrett D'Amore while (' ' == buf[*pos]) 581*95c635efSGarrett D'Amore (*pos)++; 582*95c635efSGarrett D'Amore 583*95c635efSGarrett D'Amore if ('\0' == buf[*pos]) 584*95c635efSGarrett D'Amore mdoc_pmsg(m, line, *pos, MANDOCERR_EOLNSPACE); 585*95c635efSGarrett D'Amore 586*95c635efSGarrett D'Amore return(ARGS_QWORD); 587*95c635efSGarrett D'Amore } 588*95c635efSGarrett D'Amore 589*95c635efSGarrett D'Amore p = &buf[*pos]; 590*95c635efSGarrett D'Amore *v = mandoc_getarg(m->parse, &p, line, pos); 591*95c635efSGarrett D'Amore 592*95c635efSGarrett D'Amore return(ARGS_WORD); 593*95c635efSGarrett D'Amore } 594*95c635efSGarrett D'Amore 595*95c635efSGarrett D'Amore /* 596*95c635efSGarrett D'Amore * Check if the string consists only of space-separated closing 597*95c635efSGarrett D'Amore * delimiters. This is a bit of a dance: the first must be a close 598*95c635efSGarrett D'Amore * delimiter, but it may be followed by middle delimiters. Arbitrary 599*95c635efSGarrett D'Amore * whitespace may separate these tokens. 600*95c635efSGarrett D'Amore */ 601*95c635efSGarrett D'Amore static int 602*95c635efSGarrett D'Amore args_checkpunct(const char *buf, int i) 603*95c635efSGarrett D'Amore { 604*95c635efSGarrett D'Amore int j; 605*95c635efSGarrett D'Amore char dbuf[DELIMSZ]; 606*95c635efSGarrett D'Amore enum mdelim d; 607*95c635efSGarrett D'Amore 608*95c635efSGarrett D'Amore /* First token must be a close-delimiter. */ 609*95c635efSGarrett D'Amore 610*95c635efSGarrett D'Amore for (j = 0; buf[i] && ' ' != buf[i] && j < DELIMSZ; j++, i++) 611*95c635efSGarrett D'Amore dbuf[j] = buf[i]; 612*95c635efSGarrett D'Amore 613*95c635efSGarrett D'Amore if (DELIMSZ == j) 614*95c635efSGarrett D'Amore return(0); 615*95c635efSGarrett D'Amore 616*95c635efSGarrett D'Amore dbuf[j] = '\0'; 617*95c635efSGarrett D'Amore if (DELIM_CLOSE != mdoc_isdelim(dbuf)) 618*95c635efSGarrett D'Amore return(0); 619*95c635efSGarrett D'Amore 620*95c635efSGarrett D'Amore while (' ' == buf[i]) 621*95c635efSGarrett D'Amore i++; 622*95c635efSGarrett D'Amore 623*95c635efSGarrett D'Amore /* Remaining must NOT be open/none. */ 624*95c635efSGarrett D'Amore 625*95c635efSGarrett D'Amore while (buf[i]) { 626*95c635efSGarrett D'Amore j = 0; 627*95c635efSGarrett D'Amore while (buf[i] && ' ' != buf[i] && j < DELIMSZ) 628*95c635efSGarrett D'Amore dbuf[j++] = buf[i++]; 629*95c635efSGarrett D'Amore 630*95c635efSGarrett D'Amore if (DELIMSZ == j) 631*95c635efSGarrett D'Amore return(0); 632*95c635efSGarrett D'Amore 633*95c635efSGarrett D'Amore dbuf[j] = '\0'; 634*95c635efSGarrett D'Amore d = mdoc_isdelim(dbuf); 635*95c635efSGarrett D'Amore if (DELIM_NONE == d || DELIM_OPEN == d) 636*95c635efSGarrett D'Amore return(0); 637*95c635efSGarrett D'Amore 638*95c635efSGarrett D'Amore while (' ' == buf[i]) 639*95c635efSGarrett D'Amore i++; 640*95c635efSGarrett D'Amore } 641*95c635efSGarrett D'Amore 642*95c635efSGarrett D'Amore return('\0' == buf[i]); 643*95c635efSGarrett D'Amore } 644*95c635efSGarrett D'Amore 645*95c635efSGarrett D'Amore static int 646*95c635efSGarrett D'Amore argv_multi(struct mdoc *m, int line, 647*95c635efSGarrett D'Amore struct mdoc_argv *v, int *pos, char *buf) 648*95c635efSGarrett D'Amore { 649*95c635efSGarrett D'Amore enum margserr ac; 650*95c635efSGarrett D'Amore char *p; 651*95c635efSGarrett D'Amore 652*95c635efSGarrett D'Amore for (v->sz = 0; ; v->sz++) { 653*95c635efSGarrett D'Amore if ('-' == buf[*pos]) 654*95c635efSGarrett D'Amore break; 655*95c635efSGarrett D'Amore ac = args(m, line, pos, buf, ARGSFL_NONE, &p); 656*95c635efSGarrett D'Amore if (ARGS_ERROR == ac) 657*95c635efSGarrett D'Amore return(0); 658*95c635efSGarrett D'Amore else if (ARGS_EOLN == ac) 659*95c635efSGarrett D'Amore break; 660*95c635efSGarrett D'Amore 661*95c635efSGarrett D'Amore if (0 == v->sz % MULTI_STEP) 662*95c635efSGarrett D'Amore v->value = mandoc_realloc(v->value, 663*95c635efSGarrett D'Amore (v->sz + MULTI_STEP) * sizeof(char *)); 664*95c635efSGarrett D'Amore 665*95c635efSGarrett D'Amore v->value[(int)v->sz] = mandoc_strdup(p); 666*95c635efSGarrett D'Amore } 667*95c635efSGarrett D'Amore 668*95c635efSGarrett D'Amore return(1); 669*95c635efSGarrett D'Amore } 670*95c635efSGarrett D'Amore 671*95c635efSGarrett D'Amore static int 672*95c635efSGarrett D'Amore argv_opt_single(struct mdoc *m, int line, 673*95c635efSGarrett D'Amore struct mdoc_argv *v, int *pos, char *buf) 674*95c635efSGarrett D'Amore { 675*95c635efSGarrett D'Amore enum margserr ac; 676*95c635efSGarrett D'Amore char *p; 677*95c635efSGarrett D'Amore 678*95c635efSGarrett D'Amore if ('-' == buf[*pos]) 679*95c635efSGarrett D'Amore return(1); 680*95c635efSGarrett D'Amore 681*95c635efSGarrett D'Amore ac = args(m, line, pos, buf, ARGSFL_NONE, &p); 682*95c635efSGarrett D'Amore if (ARGS_ERROR == ac) 683*95c635efSGarrett D'Amore return(0); 684*95c635efSGarrett D'Amore if (ARGS_EOLN == ac) 685*95c635efSGarrett D'Amore return(1); 686*95c635efSGarrett D'Amore 687*95c635efSGarrett D'Amore v->sz = 1; 688*95c635efSGarrett D'Amore v->value = mandoc_malloc(sizeof(char *)); 689*95c635efSGarrett D'Amore v->value[0] = mandoc_strdup(p); 690*95c635efSGarrett D'Amore 691*95c635efSGarrett D'Amore return(1); 692*95c635efSGarrett D'Amore } 693*95c635efSGarrett D'Amore 694*95c635efSGarrett D'Amore static int 695*95c635efSGarrett D'Amore argv_single(struct mdoc *m, int line, 696*95c635efSGarrett D'Amore struct mdoc_argv *v, int *pos, char *buf) 697*95c635efSGarrett D'Amore { 698*95c635efSGarrett D'Amore int ppos; 699*95c635efSGarrett D'Amore enum margserr ac; 700*95c635efSGarrett D'Amore char *p; 701*95c635efSGarrett D'Amore 702*95c635efSGarrett D'Amore ppos = *pos; 703*95c635efSGarrett D'Amore 704*95c635efSGarrett D'Amore ac = args(m, line, pos, buf, ARGSFL_NONE, &p); 705*95c635efSGarrett D'Amore if (ARGS_EOLN == ac) { 706*95c635efSGarrett D'Amore mdoc_pmsg(m, line, ppos, MANDOCERR_SYNTARGVCOUNT); 707*95c635efSGarrett D'Amore return(0); 708*95c635efSGarrett D'Amore } else if (ARGS_ERROR == ac) 709*95c635efSGarrett D'Amore return(0); 710*95c635efSGarrett D'Amore 711*95c635efSGarrett D'Amore v->sz = 1; 712*95c635efSGarrett D'Amore v->value = mandoc_malloc(sizeof(char *)); 713*95c635efSGarrett D'Amore v->value[0] = mandoc_strdup(p); 714*95c635efSGarrett D'Amore 715*95c635efSGarrett D'Amore return(1); 716*95c635efSGarrett D'Amore } 717