Annotation of mandoc/argv.c, Revision 1.1
1.1 ! kristaps 1: /* $Id: hash.c,v 1.2 2008/12/15 02:23:12 kristaps Exp $ */
! 2: /*
! 3: * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
! 4: *
! 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
! 8: * copies.
! 9: *
! 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.
! 18: */
! 19: #include <assert.h>
! 20: #include <ctype.h>
! 21: #include <err.h>
! 22: #include <stdlib.h>
! 23: #include <stdio.h>
! 24: #include <string.h>
! 25:
! 26: #include "private.h"
! 27:
! 28:
! 29: static int parse_next(struct mdoc *, int,
! 30: int *, char *, char **);
! 31:
! 32:
! 33: static int
! 34: parse_next(struct mdoc *mdoc, int tok,
! 35: int *pos, char *buf, char **v)
! 36: {
! 37:
! 38: if (0 == buf[*pos])
! 39: return(0);
! 40:
! 41: if ('\"' != buf[*pos]) {
! 42: *v = &buf[*pos];
! 43:
! 44: while (buf[*pos] && ! isspace(buf[*pos]))
! 45: (*pos)++;
! 46:
! 47: if (0 == buf[*pos])
! 48: return(1);
! 49:
! 50: buf[(*pos)++] = 0;
! 51: if (0 == buf[*pos])
! 52: return(1);
! 53:
! 54: while (buf[*pos] && isspace(buf[*pos]))
! 55: (*pos)++;
! 56:
! 57: if (buf[*pos])
! 58: return(1);
! 59:
! 60: if ( ! mdoc_warn(mdoc, tok, *pos, WARN_SYNTAX_WS_EOLN))
! 61: return(-1);
! 62: return(1);
! 63: }
! 64:
! 65: if ('-' == buf[*pos])
! 66: if ( ! mdoc_warn(mdoc, tok, *pos, WARN_SYNTAX_ARGLIKE))
! 67: return(-1);
! 68:
! 69: *v = &buf[++(*pos)];
! 70:
! 71: while (buf[*pos] && '\"' != buf[*pos])
! 72: (*pos)++;
! 73:
! 74: if (0 == buf[*pos]) {
! 75: (void)mdoc_err(mdoc, tok, *pos, ERR_SYNTAX_UNQUOTE);
! 76: return(-1);
! 77: }
! 78:
! 79: buf[(*pos)++] = 0;
! 80: if (0 == buf[*pos])
! 81: return(1);
! 82:
! 83: while (buf[*pos] && isspace(buf[*pos]))
! 84: (*pos)++;
! 85:
! 86: if (buf[*pos])
! 87: return(1);
! 88:
! 89: if ( ! mdoc_warn(mdoc, tok, *pos, WARN_SYNTAX_WS_EOLN))
! 90: return(-1);
! 91: return(1);
! 92: }
! 93:
! 94:
! 95: int
! 96: mdoc_argv_lookup(int tok, const char *argv)
! 97: {
! 98:
! 99: switch (tok) {
! 100: case (MDOC_Bl):
! 101: if (xstrcmp(argv, "ragged"))
! 102: return(MDOC_Ragged);
! 103: else if (xstrcmp(argv, "unfilled"))
! 104: return(MDOC_Unfilled);
! 105: else if (xstrcmp(argv, "literal"))
! 106: return(MDOC_Literal);
! 107: else if (xstrcmp(argv, "file"))
! 108: return(MDOC_File);
! 109: else if (xstrcmp(argv, "offset"))
! 110: return(MDOC_Offset);
! 111: else if (xstrcmp(argv, "bullet"))
! 112: return(MDOC_Bullet);
! 113: else if (xstrcmp(argv, "dash"))
! 114: return(MDOC_Dash);
! 115: else if (xstrcmp(argv, "hyphen"))
! 116: return(MDOC_Hyphen);
! 117: else if (xstrcmp(argv, "item"))
! 118: return(MDOC_Item);
! 119: else if (xstrcmp(argv, "enum"))
! 120: return(MDOC_Enum);
! 121: else if (xstrcmp(argv, "tag"))
! 122: return(MDOC_Tag);
! 123: else if (xstrcmp(argv, "diag"))
! 124: return(MDOC_Diag);
! 125: else if (xstrcmp(argv, "hang"))
! 126: return(MDOC_Hang);
! 127: else if (xstrcmp(argv, "ohang"))
! 128: return(MDOC_Ohang);
! 129: else if (xstrcmp(argv, "inset"))
! 130: return(MDOC_Inset);
! 131: else if (xstrcmp(argv, "column"))
! 132: return(MDOC_Column);
! 133: else if (xstrcmp(argv, "width"))
! 134: return(MDOC_Width);
! 135: else if (xstrcmp(argv, "compact"))
! 136: return(MDOC_Compact);
! 137:
! 138: break;
! 139: default:
! 140: abort();
! 141: /* NOTREACHED */
! 142: }
! 143:
! 144: return(MDOC_ARG_MAX);
! 145: }
! 146:
! 147:
! 148: int
! 149: mdoc_argv_parse(struct mdoc *mdoc, int tok, int arg,
! 150: struct mdoc_arg *v, int *pos, char *buf)
! 151: {
! 152: char *p;
! 153: int c, ppos, i;
! 154:
! 155: v->arg = arg;
! 156: ppos = *pos;
! 157:
! 158: switch (arg) {
! 159: case(MDOC_Compact):
! 160: /* FALLTHROUGH */
! 161: case(MDOC_Ragged):
! 162: /* FALLTHROUGH */
! 163: case(MDOC_Unfilled):
! 164: /* FALLTHROUGH */
! 165: case(MDOC_Literal):
! 166: /* FALLTHROUGH */
! 167: case(MDOC_File):
! 168: /* FALLTHROUGH */
! 169: case(MDOC_Bullet):
! 170: /* FALLTHROUGH */
! 171: case(MDOC_Dash):
! 172: /* FALLTHROUGH */
! 173: case(MDOC_Hyphen):
! 174: /* FALLTHROUGH */
! 175: case(MDOC_Item):
! 176: /* FALLTHROUGH */
! 177: case(MDOC_Enum):
! 178: /* FALLTHROUGH */
! 179: case(MDOC_Tag):
! 180: /* FALLTHROUGH */
! 181: case(MDOC_Diag):
! 182: /* FALLTHROUGH */
! 183: case(MDOC_Hang):
! 184: /* FALLTHROUGH */
! 185: case(MDOC_Ohang):
! 186: /* FALLTHROUGH */
! 187: case(MDOC_Inset):
! 188: v->sz = 0;
! 189: v->value = NULL;
! 190: break;
! 191:
! 192: case(MDOC_Width):
! 193: /* FALLTHROUGH */
! 194: case(MDOC_Offset):
! 195: /*
! 196: * This has a single value for an argument.
! 197: */
! 198: c = parse_next(mdoc, tok, pos, buf, &p);
! 199: if (-1 == c)
! 200: return(0);
! 201: else if (0 == c)
! 202: return(mdoc_err(mdoc, tok, ppos, ERR_SYNTAX_ARGVAL));
! 203:
! 204: v->sz = 1;
! 205: v->value = xcalloc(1, sizeof(char *));
! 206: v->value[0] = p;
! 207: break;
! 208:
! 209: case(MDOC_Column):
! 210: /*
! 211: * This has several value for a single argument. We
! 212: * pre-allocate a pointer array and don't let it exceed
! 213: * this size.
! 214: */
! 215: v->sz = 0;
! 216: v->value = xcalloc(MDOC_LINEARG_MAX, sizeof(char *));
! 217: for (i = 0; i < MDOC_LINEARG_MAX; i++) {
! 218: c = parse_next(mdoc, tok, pos, buf, &p);
! 219: if (-1 == c) {
! 220: free(v->value);
! 221: return(0);
! 222: } else if (0 == c)
! 223: break;
! 224: v->value[i] = p;
! 225: }
! 226: if (0 == i) {
! 227: free(v->value);
! 228: return(mdoc_err(mdoc, tok, ppos, ERR_SYNTAX_ARGVAL));
! 229: } else if (MDOC_LINEARG_MAX == i)
! 230: return(mdoc_err(mdoc, tok, ppos, ERR_SYNTAX_ARGMANY));
! 231:
! 232: v->sz = i;
! 233: break;
! 234: default:
! 235: abort();
! 236: /* NOTREACHED */
! 237: }
! 238:
! 239: return(1);
! 240: }
! 241:
! 242:
! 243: void
! 244: mdoc_argv_free(int sz, struct mdoc_arg *arg)
! 245: {
! 246: int i;
! 247:
! 248: for (i = 0; i < sz; i++) {
! 249: if (0 == arg[i].sz) {
! 250: assert(NULL == arg[i].value);
! 251: continue;
! 252: }
! 253: assert(arg[i].value);
! 254: free(arg[i].value);
! 255: }
! 256: }
CVSweb