112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* $NetBSD: unvis.c,v 1.41 2012/12/15 04:29:53 matt Exp $ */ 212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/*- 412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * Copyright (c) 1989, 1993 512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * The Regents of the University of California. All rights reserved. 612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * 712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * Redistribution and use in source and binary forms, with or without 812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * modification, are permitted provided that the following conditions 912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * are met: 1012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * 1. Redistributions of source code must retain the above copyright 1112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * notice, this list of conditions and the following disclaimer. 1212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * 2. Redistributions in binary form must reproduce the above copyright 1312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * notice, this list of conditions and the following disclaimer in the 1412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * documentation and/or other materials provided with the distribution. 1512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * 3. Neither the name of the University nor the names of its contributors 1612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * may be used to endorse or promote products derived from this software 1712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * without specific prior written permission. 1812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * 1912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * SUCH DAMAGE. 3012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */ 3112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 3212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#include "config.h" 3312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#if defined(LIBC_SCCS) && !defined(lint) 3412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#if 0 3512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialastatic char sccsid[] = "@(#)unvis.c 8.1 (Berkeley) 6/4/93"; 3612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#else 3712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala__RCSID("$NetBSD: unvis.c,v 1.41 2012/12/15 04:29:53 matt Exp $"); 3812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif 3912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif /* LIBC_SCCS and not lint */ 4012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 4112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#include <sys/types.h> 4212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 4312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#include <assert.h> 4412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#include <ctype.h> 4512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#ifdef HAVE_STDINT_H 4612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#include <stdint.h> 4712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif 4812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#include <stdio.h> 4912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#include <errno.h> 5012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#include <vis.h> 5112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 5212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#ifdef __weak_alias 5312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala__weak_alias(strnunvisx,_strnunvisx) 5412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif 5512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 5612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#if !HAVE_VIS 5712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* 5812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * decode driven by state machine 5912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */ 6012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define S_GROUND 0 /* haven't seen escape char */ 6112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define S_START 1 /* start decoding special sequence */ 6212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define S_META 2 /* metachar started (M) */ 6312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define S_META1 3 /* metachar more, regular char (-) */ 6412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define S_CTRL 4 /* control char started (^) */ 6512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define S_OCTAL2 5 /* octal digit 2 */ 6612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define S_OCTAL3 6 /* octal digit 3 */ 6712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define S_HEX 7 /* mandatory hex digit */ 6812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define S_HEX1 8 /* http hex digit */ 6912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define S_HEX2 9 /* http hex digit 2 */ 7012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define S_MIME1 10 /* mime hex digit 1 */ 7112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define S_MIME2 11 /* mime hex digit 2 */ 7212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define S_EATCRNL 12 /* mime eating CRNL */ 7312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define S_AMP 13 /* seen & */ 7412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define S_NUMBER 14 /* collecting number */ 7512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define S_STRING 15 /* collecting string */ 7612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 7712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7') 7812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define xtod(c) (isdigit(c) ? (c - '0') : ((tolower(c) - 'a') + 10)) 7912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define XTOD(c) (isdigit(c) ? (c - '0') : ((c - 'A') + 10)) 8012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 8112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* 8212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * RFC 1866 8312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */ 8412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialastatic const struct nv { 8512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala char name[7]; 8612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala uint8_t value; 8712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala} nv[] = { 8812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "AElig", 198 }, /* capital AE diphthong (ligature) */ 8912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "Aacute", 193 }, /* capital A, acute accent */ 9012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "Acirc", 194 }, /* capital A, circumflex accent */ 9112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "Agrave", 192 }, /* capital A, grave accent */ 9212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "Aring", 197 }, /* capital A, ring */ 9312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "Atilde", 195 }, /* capital A, tilde */ 9412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "Auml", 196 }, /* capital A, dieresis or umlaut mark */ 9512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "Ccedil", 199 }, /* capital C, cedilla */ 9612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "ETH", 208 }, /* capital Eth, Icelandic */ 9712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "Eacute", 201 }, /* capital E, acute accent */ 9812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "Ecirc", 202 }, /* capital E, circumflex accent */ 9912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "Egrave", 200 }, /* capital E, grave accent */ 10012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "Euml", 203 }, /* capital E, dieresis or umlaut mark */ 10112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "Iacute", 205 }, /* capital I, acute accent */ 10212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "Icirc", 206 }, /* capital I, circumflex accent */ 10312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "Igrave", 204 }, /* capital I, grave accent */ 10412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "Iuml", 207 }, /* capital I, dieresis or umlaut mark */ 10512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "Ntilde", 209 }, /* capital N, tilde */ 10612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "Oacute", 211 }, /* capital O, acute accent */ 10712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "Ocirc", 212 }, /* capital O, circumflex accent */ 10812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "Ograve", 210 }, /* capital O, grave accent */ 10912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "Oslash", 216 }, /* capital O, slash */ 11012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "Otilde", 213 }, /* capital O, tilde */ 11112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "Ouml", 214 }, /* capital O, dieresis or umlaut mark */ 11212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "THORN", 222 }, /* capital THORN, Icelandic */ 11312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "Uacute", 218 }, /* capital U, acute accent */ 11412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "Ucirc", 219 }, /* capital U, circumflex accent */ 11512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "Ugrave", 217 }, /* capital U, grave accent */ 11612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "Uuml", 220 }, /* capital U, dieresis or umlaut mark */ 11712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "Yacute", 221 }, /* capital Y, acute accent */ 11812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "aacute", 225 }, /* small a, acute accent */ 11912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "acirc", 226 }, /* small a, circumflex accent */ 12012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "acute", 180 }, /* acute accent */ 12112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "aelig", 230 }, /* small ae diphthong (ligature) */ 12212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "agrave", 224 }, /* small a, grave accent */ 12312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "amp", 38 }, /* ampersand */ 12412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "aring", 229 }, /* small a, ring */ 12512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "atilde", 227 }, /* small a, tilde */ 12612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "auml", 228 }, /* small a, dieresis or umlaut mark */ 12712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "brvbar", 166 }, /* broken (vertical) bar */ 12812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "ccedil", 231 }, /* small c, cedilla */ 12912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "cedil", 184 }, /* cedilla */ 13012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "cent", 162 }, /* cent sign */ 13112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "copy", 169 }, /* copyright sign */ 13212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "curren", 164 }, /* general currency sign */ 13312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "deg", 176 }, /* degree sign */ 13412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "divide", 247 }, /* divide sign */ 13512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "eacute", 233 }, /* small e, acute accent */ 13612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "ecirc", 234 }, /* small e, circumflex accent */ 13712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "egrave", 232 }, /* small e, grave accent */ 13812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "eth", 240 }, /* small eth, Icelandic */ 13912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "euml", 235 }, /* small e, dieresis or umlaut mark */ 14012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "frac12", 189 }, /* fraction one-half */ 14112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "frac14", 188 }, /* fraction one-quarter */ 14212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "frac34", 190 }, /* fraction three-quarters */ 14312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "gt", 62 }, /* greater than */ 14412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "iacute", 237 }, /* small i, acute accent */ 14512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "icirc", 238 }, /* small i, circumflex accent */ 14612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "iexcl", 161 }, /* inverted exclamation mark */ 14712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "igrave", 236 }, /* small i, grave accent */ 14812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "iquest", 191 }, /* inverted question mark */ 14912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "iuml", 239 }, /* small i, dieresis or umlaut mark */ 15012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "laquo", 171 }, /* angle quotation mark, left */ 15112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "lt", 60 }, /* less than */ 15212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "macr", 175 }, /* macron */ 15312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "micro", 181 }, /* micro sign */ 15412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "middot", 183 }, /* middle dot */ 15512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "nbsp", 160 }, /* no-break space */ 15612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "not", 172 }, /* not sign */ 15712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "ntilde", 241 }, /* small n, tilde */ 15812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "oacute", 243 }, /* small o, acute accent */ 15912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "ocirc", 244 }, /* small o, circumflex accent */ 16012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "ograve", 242 }, /* small o, grave accent */ 16112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "ordf", 170 }, /* ordinal indicator, feminine */ 16212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "ordm", 186 }, /* ordinal indicator, masculine */ 16312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "oslash", 248 }, /* small o, slash */ 16412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "otilde", 245 }, /* small o, tilde */ 16512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "ouml", 246 }, /* small o, dieresis or umlaut mark */ 16612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "para", 182 }, /* pilcrow (paragraph sign) */ 16712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "plusmn", 177 }, /* plus-or-minus sign */ 16812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "pound", 163 }, /* pound sterling sign */ 16912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "quot", 34 }, /* double quote */ 17012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "raquo", 187 }, /* angle quotation mark, right */ 17112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "reg", 174 }, /* registered sign */ 17212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "sect", 167 }, /* section sign */ 17312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "shy", 173 }, /* soft hyphen */ 17412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "sup1", 185 }, /* superscript one */ 17512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "sup2", 178 }, /* superscript two */ 17612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "sup3", 179 }, /* superscript three */ 17712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "szlig", 223 }, /* small sharp s, German (sz ligature) */ 17812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "thorn", 254 }, /* small thorn, Icelandic */ 17912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "times", 215 }, /* multiply sign */ 18012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "uacute", 250 }, /* small u, acute accent */ 18112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "ucirc", 251 }, /* small u, circumflex accent */ 18212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "ugrave", 249 }, /* small u, grave accent */ 18312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "uml", 168 }, /* umlaut (dieresis) */ 18412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "uuml", 252 }, /* small u, dieresis or umlaut mark */ 18512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "yacute", 253 }, /* small y, acute accent */ 18612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "yen", 165 }, /* yen sign */ 18712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { "yuml", 255 }, /* small y, dieresis or umlaut mark */ 18812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}; 18912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 19012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* 19112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * unvis - decode characters previously encoded by vis 19212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */ 19312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaint 19412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaunvis(char *cp, int c, int *astate, int flag) 19512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{ 19612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala unsigned char uc = (unsigned char)c; 19712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala unsigned char st, ia, is, lc; 19812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 19912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* 20012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * Bottom 8 bits of astate hold the state machine state. 20112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * Top 8 bits hold the current character in the http 1866 nv string decoding 20212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */ 20312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define GS(a) ((a) & 0xff) 20412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define SS(a, b) (((uint32_t)(a) << 24) | (b)) 20512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define GI(a) ((uint32_t)(a) >> 24) 20612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 20712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala _DIAGASSERT(cp != NULL); 20812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala _DIAGASSERT(astate != NULL); 20912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala st = GS(*astate); 21012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 21112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (flag & UNVIS_END) { 21212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala switch (st) { 21312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case S_OCTAL2: 21412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case S_OCTAL3: 21512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case S_HEX2: 21612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *astate = SS(0, S_GROUND); 21712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return UNVIS_VALID; 21812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case S_GROUND: 21912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return UNVIS_NOCHAR; 22012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala default: 22112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return UNVIS_SYNBAD; 22212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 22312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 22412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 22512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala switch (st) { 22612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 22712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case S_GROUND: 22812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *cp = 0; 22912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if ((flag & VIS_NOESCAPE) == 0 && c == '\\') { 23012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *astate = SS(0, S_START); 23112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return UNVIS_NOCHAR; 23212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 23312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if ((flag & VIS_HTTP1808) && c == '%') { 23412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *astate = SS(0, S_HEX1); 23512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return UNVIS_NOCHAR; 23612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 23712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if ((flag & VIS_HTTP1866) && c == '&') { 23812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *astate = SS(0, S_AMP); 23912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return UNVIS_NOCHAR; 24012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 24112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if ((flag & VIS_MIMESTYLE) && c == '=') { 24212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *astate = SS(0, S_MIME1); 24312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return UNVIS_NOCHAR; 24412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 24512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *cp = c; 24612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return UNVIS_VALID; 24712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 24812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case S_START: 24912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala switch(c) { 25012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case '\\': 25112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *cp = c; 25212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *astate = SS(0, S_GROUND); 25312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return UNVIS_VALID; 25412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case '0': case '1': case '2': case '3': 25512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case '4': case '5': case '6': case '7': 25612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *cp = (c - '0'); 25712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *astate = SS(0, S_OCTAL2); 25812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return UNVIS_NOCHAR; 25912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case 'M': 26012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *cp = (char)0200; 26112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *astate = SS(0, S_META); 26212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return UNVIS_NOCHAR; 26312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case '^': 26412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *astate = SS(0, S_CTRL); 26512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return UNVIS_NOCHAR; 26612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case 'n': 26712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *cp = '\n'; 26812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *astate = SS(0, S_GROUND); 26912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return UNVIS_VALID; 27012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case 'r': 27112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *cp = '\r'; 27212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *astate = SS(0, S_GROUND); 27312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return UNVIS_VALID; 27412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case 'b': 27512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *cp = '\b'; 27612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *astate = SS(0, S_GROUND); 27712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return UNVIS_VALID; 27812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case 'a': 27912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *cp = '\007'; 28012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *astate = SS(0, S_GROUND); 28112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return UNVIS_VALID; 28212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case 'v': 28312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *cp = '\v'; 28412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *astate = SS(0, S_GROUND); 28512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return UNVIS_VALID; 28612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case 't': 28712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *cp = '\t'; 28812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *astate = SS(0, S_GROUND); 28912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return UNVIS_VALID; 29012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case 'f': 29112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *cp = '\f'; 29212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *astate = SS(0, S_GROUND); 29312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return UNVIS_VALID; 29412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case 's': 29512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *cp = ' '; 29612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *astate = SS(0, S_GROUND); 29712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return UNVIS_VALID; 29812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case 'E': 29912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *cp = '\033'; 30012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *astate = SS(0, S_GROUND); 30112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return UNVIS_VALID; 30212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case 'x': 30312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *astate = SS(0, S_HEX); 30412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return UNVIS_NOCHAR; 30512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case '\n': 30612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala /* 30712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * hidden newline 30812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */ 30912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *astate = SS(0, S_GROUND); 31012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return UNVIS_NOCHAR; 31112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case '$': 31212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala /* 31312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * hidden marker 31412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */ 31512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *astate = SS(0, S_GROUND); 31612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return UNVIS_NOCHAR; 31712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 31812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala goto bad; 31912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 32012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case S_META: 32112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (c == '-') 32212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *astate = SS(0, S_META1); 32312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala else if (c == '^') 32412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *astate = SS(0, S_CTRL); 32512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala else 32612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala goto bad; 32712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return UNVIS_NOCHAR; 32812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 32912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case S_META1: 33012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *astate = SS(0, S_GROUND); 33112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *cp |= c; 33212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return UNVIS_VALID; 33312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 33412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case S_CTRL: 33512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (c == '?') 33612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *cp |= 0177; 33712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala else 33812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *cp |= c & 037; 33912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *astate = SS(0, S_GROUND); 34012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return UNVIS_VALID; 34112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 34212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case S_OCTAL2: /* second possible octal digit */ 34312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (isoctal(uc)) { 34412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala /* 34512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * yes - and maybe a third 34612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */ 34712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *cp = (*cp << 3) + (c - '0'); 34812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *astate = SS(0, S_OCTAL3); 34912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return UNVIS_NOCHAR; 35012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 35112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala /* 35212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * no - done with current sequence, push back passed char 35312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */ 35412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *astate = SS(0, S_GROUND); 35512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return UNVIS_VALIDPUSH; 35612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 35712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case S_OCTAL3: /* third possible octal digit */ 35812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *astate = SS(0, S_GROUND); 35912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (isoctal(uc)) { 36012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *cp = (*cp << 3) + (c - '0'); 36112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return UNVIS_VALID; 36212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 36312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala /* 36412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * we were done, push back passed char 36512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */ 36612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return UNVIS_VALIDPUSH; 36712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 36812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case S_HEX: 36912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (!isxdigit(uc)) 37012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala goto bad; 37112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala /*FALLTHROUGH*/ 37212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case S_HEX1: 37312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (isxdigit(uc)) { 37412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *cp = xtod(uc); 37512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *astate = SS(0, S_HEX2); 37612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return UNVIS_NOCHAR; 37712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 37812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala /* 37912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * no - done with current sequence, push back passed char 38012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */ 38112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *astate = SS(0, S_GROUND); 38212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return UNVIS_VALIDPUSH; 38312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 38412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case S_HEX2: 38512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *astate = S_GROUND; 38612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (isxdigit(uc)) { 38712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *cp = xtod(uc) | (*cp << 4); 38812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return UNVIS_VALID; 38912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 39012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return UNVIS_VALIDPUSH; 39112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 39212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case S_MIME1: 39312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (uc == '\n' || uc == '\r') { 39412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *astate = SS(0, S_EATCRNL); 39512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return UNVIS_NOCHAR; 39612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 39712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (isxdigit(uc) && (isdigit(uc) || isupper(uc))) { 39812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *cp = XTOD(uc); 39912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *astate = SS(0, S_MIME2); 40012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return UNVIS_NOCHAR; 40112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 40212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala goto bad; 40312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 40412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case S_MIME2: 40512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (isxdigit(uc) && (isdigit(uc) || isupper(uc))) { 40612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *astate = SS(0, S_GROUND); 40712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *cp = XTOD(uc) | (*cp << 4); 40812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return UNVIS_VALID; 40912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 41012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala goto bad; 41112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 41212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case S_EATCRNL: 41312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala switch (uc) { 41412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case '\r': 41512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case '\n': 41612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return UNVIS_NOCHAR; 41712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case '=': 41812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *astate = SS(0, S_MIME1); 41912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return UNVIS_NOCHAR; 42012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala default: 42112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *cp = uc; 42212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *astate = SS(0, S_GROUND); 42312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return UNVIS_VALID; 42412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 42512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 42612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case S_AMP: 42712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *cp = 0; 42812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (uc == '#') { 42912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *astate = SS(0, S_NUMBER); 43012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return UNVIS_NOCHAR; 43112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 43212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *astate = SS(0, S_STRING); 43312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala /*FALLTHROUGH*/ 43412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 43512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case S_STRING: 43612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala ia = *cp; /* index in the array */ 43712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala is = GI(*astate); /* index in the string */ 43812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala lc = is == 0 ? 0 : nv[ia].name[is - 1]; /* last character */ 43912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 44012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (uc == ';') 44112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala uc = '\0'; 44212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 44312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala for (; ia < __arraycount(nv); ia++) { 44412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (is != 0 && nv[ia].name[is - 1] != lc) 44512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala goto bad; 44612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (nv[ia].name[is] == uc) 44712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala break; 44812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 44912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 45012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (ia == __arraycount(nv)) 45112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala goto bad; 45212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 45312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (uc != 0) { 45412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *cp = ia; 45512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *astate = SS(is + 1, S_STRING); 45612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return UNVIS_NOCHAR; 45712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 45812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 45912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *cp = nv[ia].value; 46012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *astate = SS(0, S_GROUND); 46112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return UNVIS_VALID; 46212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 46312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case S_NUMBER: 46412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (uc == ';') 46512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return UNVIS_VALID; 46612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (!isdigit(uc)) 46712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala goto bad; 46812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *cp += (*cp * 10) + uc - '0'; 46912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return UNVIS_NOCHAR; 47012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 47112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala default: 47212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala bad: 47312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala /* 47412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * decoder in unknown state - (probably uninitialized) 47512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */ 47612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *astate = SS(0, S_GROUND); 47712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return UNVIS_SYNBAD; 47812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 47912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala} 48012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 48112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* 48212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * strnunvisx - decode src into dst 48312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * 48412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * Number of chars decoded into dst is returned, -1 on error. 48512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * Dst is null terminated. 48612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */ 48712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 48812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaint 48912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialastrnunvisx(char *dst, size_t dlen, const char *src, int flag) 49012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{ 49112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala char c; 49212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala char t = '\0', *start = dst; 49312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala int state = 0; 49412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 49512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala _DIAGASSERT(src != NULL); 49612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala _DIAGASSERT(dst != NULL); 49712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define CHECKSPACE() \ 49812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala do { \ 49912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (dlen-- == 0) { \ 50012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala errno = ENOSPC; \ 50112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return -1; \ 50212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } \ 50312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } while (/*CONSTCOND*/0) 50412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 50512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala while ((c = *src++) != '\0') { 50612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala again: 50712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala switch (unvis(&t, c, &state, flag)) { 50812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case UNVIS_VALID: 50912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala CHECKSPACE(); 51012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *dst++ = t; 51112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala break; 51212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case UNVIS_VALIDPUSH: 51312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala CHECKSPACE(); 51412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *dst++ = t; 51512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala goto again; 51612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case 0: 51712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case UNVIS_NOCHAR: 51812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala break; 51912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case UNVIS_SYNBAD: 52012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala errno = EINVAL; 52112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return -1; 52212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala default: 52312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala _DIAGASSERT(/*CONSTCOND*/0); 52412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala errno = EINVAL; 52512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return -1; 52612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 52712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 52812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (unvis(&t, c, &state, UNVIS_END) == UNVIS_VALID) { 52912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala CHECKSPACE(); 53012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *dst++ = t; 53112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 53212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala CHECKSPACE(); 53312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *dst = '\0'; 53412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return (int)(dst - start); 53512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala} 53612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 53712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaint 53812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialastrunvisx(char *dst, const char *src, int flag) 53912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{ 54012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return strnunvisx(dst, (size_t)~0, src, flag); 54112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala} 54212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 54312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaint 54412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialastrunvis(char *dst, const char *src) 54512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{ 54612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return strnunvisx(dst, (size_t)~0, src, 0); 54712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala} 54812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 54912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaint 55012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialastrnunvis(char *dst, size_t dlen, const char *src) 55112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{ 55212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return strnunvisx(dst, dlen, src, 0); 55312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala} 55412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif 555