14887Schin /***********************************************************************
24887Schin * *
34887Schin * This software is part of the ast package *
4*10898Sroland.mainz@nrubsig.org * Copyright (c) 2000-2009 AT&T Intellectual Property *
54887Schin * and is licensed under the *
64887Schin * Common Public License, Version 1.0 *
78462SApril.Chin@Sun.COM * by AT&T Intellectual Property *
84887Schin * *
94887Schin * A copy of the License is available at *
104887Schin * http://www.opensource.org/licenses/cpl1.0.txt *
114887Schin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
124887Schin * *
134887Schin * Information and Software Systems Research *
144887Schin * AT&T Research *
154887Schin * Florham Park NJ *
164887Schin * *
174887Schin * Glenn Fowler <gsf@research.att.com> *
184887Schin * *
194887Schin ***********************************************************************/
204887Schin #pragma prototyped
214887Schin /*
224887Schin * Glenn Fowler
234887Schin * AT&T Research
244887Schin */
254887Schin
264887Schin static const char usage[] =
274887Schin "[-?\n@(#)$Id: msgcvt (AT&T Research) 2000-05-01 $\n]"
284887Schin USAGE_LICENSE
294887Schin "[+NAME?msgcvt - convert message file to/from html]"
304887Schin "[+DESCRIPTION?\bmsgcvt\b reads a \bgencat\b(1) format file on the standard"
314887Schin " input and converts it to \bhtml\b on the standard output. The input"
324887Schin " file must contain the control statement \b$quote \"\b and use the \""
334887Schin " character to quote message text. The output is in a form suitable for"
344887Schin " automatic translation by web sites like"
354887Schin " \bhttp://babelfish.altavista.com/\b or filters like"
364887Schin " \btranslate\b(1).]"
374887Schin "[h:html?Generate \bhtml\b from \bgencat\b(1) input. This is the default.]"
384887Schin "[m:msg?Generate a \bgencat\b(1) message file from (presumably translated)"
394887Schin " \bhtml\b. Wide characters are UTF-8 encoded.]"
404887Schin "[r:raw?The message file is raw message text, one message per line, with no"
414887Schin " quoting or line numbering.]"
424887Schin "[+SEE ALSO?\bgencat\b(1), \bmsgcc\b(1), \bmsggen\b(1), \btranslate\b(1)]"
434887Schin ;
444887Schin
454887Schin #include <ast.h>
464887Schin #include <ctype.h>
474887Schin #include <error.h>
484887Schin
494887Schin #define MSG_RAW (1<<0)
504887Schin #define MSG_SPLICE (1<<1)
514887Schin
524887Schin #define SPACE(s) (isspace(*s)&&(s+=1)||*s=='\\'&&(*(s+1)=='n'||*(s+1)=='t')&&(s+=2))
534887Schin
544887Schin typedef void (*Convert_f)(Sfio_t*, Sfio_t*, int);
554887Schin
564887Schin typedef struct
574887Schin {
584887Schin const char* name;
594887Schin int code;
604887Schin } Code_t;
614887Schin
624887Schin static const Code_t codes[] =
634887Schin {
644887Schin "aacute", 225,
654887Schin "Aacute", 193,
664887Schin "acirc", 226,
674887Schin "Acirc", 194,
684887Schin "aelig", 230,
694887Schin "AElig", 198,
704887Schin "agrave", 224,
714887Schin "Agrave", 192,
724887Schin "amp", '&',
734887Schin "aring", 229,
744887Schin "Aring", 197,
754887Schin "atilde", 227,
764887Schin "Atilde", 195,
774887Schin "auml", 228,
784887Schin "Auml", 196,
794887Schin "ccedil", 231,
804887Schin "Ccedil", 199,
814887Schin "copy", 169,
824887Schin "eacute", 233,
834887Schin "Eacute", 201,
844887Schin "ecirc", 234,
854887Schin "Ecirc", 202,
864887Schin "egrave", 232,
874887Schin "Egrave", 200,
884887Schin "euml", 235,
894887Schin "Euml", 203,
904887Schin "gt", '>',
914887Schin "iacute", 237,
924887Schin "Iacute", 205,
934887Schin "icirc", 238,
944887Schin "Icirc", 206,
954887Schin "igrave", 236,
964887Schin "Igrave", 204,
974887Schin "iuml", 239,
984887Schin "Iuml", 207,
994887Schin "lt", '<',
1004887Schin "nbsp", ' ',
1014887Schin "ntilde", 241,
1024887Schin "Ntilde", 209,
1034887Schin "oacute", 243,
1044887Schin "Oacute", 211,
1054887Schin "ocirc", 244,
1064887Schin "Ocirc", 212,
1074887Schin "ograve", 242,
1084887Schin "Ograve", 210,
1094887Schin "oslash", 248,
1104887Schin "Oslash", 216,
1114887Schin "otilde", 245,
1124887Schin "Otilde", 213,
1134887Schin "ouml", 246,
1144887Schin "Ouml", 214,
1154887Schin "quot", '"',
1164887Schin "reg", 174,
1174887Schin "szlig", 223,
1184887Schin "uacute", 250,
1194887Schin "Uacute", 218,
1204887Schin "ucirc", 251,
1214887Schin "Ucirc", 219,
1224887Schin "ugrave", 249,
1234887Schin "Ugrave", 217,
1244887Schin "uuml", 252,
1254887Schin "Uuml", 220,
1264887Schin "yuml", 255,
1274887Schin };
1284887Schin
1294887Schin static int
decode(Sfio_t * ip)1304887Schin decode(Sfio_t* ip)
1314887Schin {
1324887Schin register int c;
1334887Schin register int i;
1344887Schin char name[32];
1354887Schin
1364887Schin if ((c = sfgetc(ip)) == EOF)
1374887Schin return '&';
1384887Schin name[0] = c;
1394887Schin i = 1;
1404887Schin if (c != '#' && !isalpha(c))
1414887Schin goto bad;
1424887Schin while ((c = sfgetc(ip)) != EOF && c != ';')
1434887Schin {
1444887Schin if (c == '&')
1454887Schin i = 0;
1464887Schin else
1474887Schin {
1484887Schin name[i++] = c;
1494887Schin if (!isalnum(c) && (i > 1 || c != '#') || i >= (elementsof(name) - 1))
1504887Schin goto bad;
1514887Schin }
1524887Schin }
1534887Schin name[i] = 0;
1544887Schin if (name[0] == '#')
1554887Schin {
1564887Schin switch (c = strtol(name + 1, NiL, 10))
1574887Schin {
1584887Schin case 91:
1594887Schin c = '[';
1604887Schin break;
1614887Schin case 93:
1624887Schin c = ']';
1634887Schin break;
1644887Schin }
1654887Schin }
1664887Schin else
1674887Schin {
1684887Schin for (i = 0; i < elementsof(codes); i++)
1694887Schin if (streq(codes[i].name, name))
1704887Schin {
1714887Schin c = codes[i].code;
1724887Schin break;
1734887Schin }
1744887Schin if (i >= elementsof(codes))
1754887Schin goto bad;
1764887Schin }
1774887Schin return c;
1784887Schin bad:
1794887Schin name[i] = 0;
1804887Schin if (c == ';')
1814887Schin error(1, "&%s: unknown HTML special character -- & assumed", name);
1824887Schin else
1834887Schin error(1, "&%s: invalid HTML special character -- & assumed", name);
1844887Schin while (i--)
1854887Schin sfungetc(ip, name[i]);
1864887Schin return '&';
1874887Schin }
1884887Schin
1894887Schin static int
sfpututf(Sfio_t * op,register int w)1904887Schin sfpututf(Sfio_t* op, register int w)
1914887Schin {
1924887Schin if (!(w & ~0x7F))
1934887Schin return sfputc(op, w);
1944887Schin else if (!(w & ~0x7FF))
1954887Schin sfputc(op, 0xC0 + (w >> 6));
1964887Schin else if (!(w & ~0xFFFF))
1974887Schin {
1984887Schin sfputc(op, 0xE0 + (w >> 12));
1994887Schin sfputc(op, 0x80 + (w >> 6 ) & 0x3F);
2004887Schin }
2014887Schin else
2024887Schin return sfputc(op, '?');
2034887Schin return sfputc(op, 0x80 + (w & 0x3F));
2044887Schin }
2054887Schin
2064887Schin static int
sfnext(Sfio_t * ip)2074887Schin sfnext(Sfio_t* ip)
2084887Schin {
2094887Schin register int c;
2104887Schin
2114887Schin while (isspace(c = sfgetc(ip)));
2124887Schin return c;
2134887Schin }
2144887Schin
2154887Schin static void
html2msg(register Sfio_t * ip,register Sfio_t * op,int flags)2164887Schin html2msg(register Sfio_t* ip, register Sfio_t* op, int flags)
2174887Schin {
2184887Schin register int c;
2194887Schin register int q;
2204887Schin
2214887Schin again:
2224887Schin while ((c = sfgetc(ip)) != EOF)
2234887Schin if (c == '<')
2244887Schin {
2254887Schin if ((c = sfnext(ip)) == 'O' &&
2264887Schin (c = sfnext(ip)) == 'L' &&
2274887Schin isspace(c = sfgetc(ip)) &&
2284887Schin (c = sfnext(ip)) == 'S' &&
2294887Schin (c = sfnext(ip)) == 'T' &&
2304887Schin (c = sfnext(ip)) == 'A' &&
2314887Schin (c = sfnext(ip)) == 'R' &&
2324887Schin (c = sfnext(ip)) == 'T' &&
2334887Schin (c = sfnext(ip)) == '=' &&
2344887Schin (c = sfnext(ip)) == '"' &&
2354887Schin (c = sfnext(ip)) == '5' &&
2364887Schin (c = sfnext(ip)) == '5' &&
2374887Schin (c = sfnext(ip)) == '0' &&
2384887Schin (c = sfnext(ip)) == '7' &&
2394887Schin (c = sfnext(ip)) == '1' &&
2404887Schin (c = sfnext(ip)) == '7' &&
2414887Schin (c = sfnext(ip)) == '"' &&
2424887Schin (c = sfnext(ip)) == '>')
2434887Schin break;
2444887Schin while (c != EOF && c != '>')
2454887Schin c = sfgetc(ip);
2464887Schin }
2474887Schin if ((c = sfnext(ip)) != EOF)
2484887Schin sfungetc(ip, c);
2494887Schin q = 0;
2504887Schin for (;;)
2514887Schin {
2524887Schin switch (c = sfgetc(ip))
2534887Schin {
2544887Schin case EOF:
2554887Schin break;
2564887Schin case '&':
2574887Schin c = decode(ip);
2584887Schin sfpututf(op, c);
2594887Schin if (isspace(c))
2604887Schin {
2614887Schin while (isspace(c = sfgetc(ip)));
2624887Schin if (c == EOF)
2634887Schin break;
2644887Schin sfungetc(ip, c);
2654887Schin }
2664887Schin continue;
2674887Schin case '<':
2684887Schin switch (c = sfnext(ip))
2694887Schin {
2704887Schin case '/':
2714887Schin if ((c = sfnext(ip)) == 'O' &&
2724887Schin (c = sfgetc(ip)) == 'L' &&
2734887Schin (c = sfnext(ip)) == '>')
2744887Schin {
2754887Schin if (q)
2764887Schin {
2774887Schin sfputc(op, q);
2784887Schin q = '"';
2794887Schin }
2804887Schin goto again;
2814887Schin }
2824887Schin break;
2834887Schin case 'B':
2844887Schin if ((c = sfgetc(ip)) == 'R' &&
2854887Schin (c = sfnext(ip)) == '>')
2864887Schin sfputc(op, ' ');
2874887Schin break;
2884887Schin case 'L':
2894887Schin if ((c = sfgetc(ip)) == 'I' &&
2904887Schin (c = sfnext(ip)) == '>' &&
2914887Schin isdigit(c = sfnext(ip)))
2924887Schin {
2934887Schin if (q)
2944887Schin sfputc(op, q);
2954887Schin else
2964887Schin q = '"';
2974887Schin sfputc(op, '\n');
2984887Schin do
2994887Schin {
3004887Schin sfputc(op, c);
3014887Schin } while (isdigit(c = sfgetc(ip)));
3024887Schin if (c == EOF)
3034887Schin break;
3044887Schin sfputc(op, ' ');
3054887Schin sfputc(op, '"');
3064887Schin if (isspace(c))
3074887Schin c = sfnext(ip);
3084887Schin if (c == '<' &&
3094887Schin (c = sfnext(ip)) == 'L' &&
3104887Schin (c = sfgetc(ip)) == 'I' &&
3114887Schin (c = sfnext(ip)) == '>')
3124887Schin /* great */;
3134887Schin continue;
3144887Schin }
3154887Schin break;
3164887Schin case 'P':
3174887Schin if ((c = sfnext(ip)) == '>')
3184887Schin sfputc(op, '\n');
3194887Schin else if (c == 'C' &&
3204887Schin (c = sfgetc(ip)) == 'L' &&
3214887Schin (c = sfgetc(ip)) == 'A' &&
3224887Schin (c = sfgetc(ip)) == 'S' &&
3234887Schin (c = sfgetc(ip)) == 'S' &&
3244887Schin (c = sfnext(ip)) == '=' &&
3254887Schin (c = sfnext(ip)) == '"')
3264887Schin for (;;)
3274887Schin {
3284887Schin switch (c = sfgetc(ip))
3294887Schin {
3304887Schin case EOF:
3314887Schin case '"':
3324887Schin break;
3334887Schin case '&':
3344887Schin c = decode(ip);
3354887Schin sfpututf(op, c);
3364887Schin continue;
3374887Schin default:
3384887Schin sfpututf(op, c);
3394887Schin continue;
3404887Schin }
3414887Schin break;
3424887Schin }
3434887Schin break;
3444887Schin }
3454887Schin while (c != EOF && c != '>')
3464887Schin c = sfgetc(ip);
3474887Schin if (c == EOF || (c = sfgetc(ip)) == EOF)
3484887Schin break;
3494887Schin sfungetc(ip, c);
3504887Schin continue;
3514887Schin case '"':
3524887Schin if (!flags)
3534887Schin sfputc(op, '\\');
3544887Schin sfputc(op, c);
3554887Schin continue;
3564887Schin case '\n':
3574887Schin if (flags)
3584887Schin {
3594887Schin sfputc(op, c);
3604887Schin continue;
3614887Schin }
3624887Schin /*FALLTHROUGH*/
3634887Schin case ' ':
3644887Schin case '\t':
3654887Schin while ((c = sfgetc(ip)) != EOF)
3664887Schin if (c == '&')
3674887Schin {
3684887Schin c = decode(ip);
3694887Schin if (!isspace(c))
3704887Schin sfputc(op, ' ');
3714887Schin sfpututf(op, c);
3724887Schin break;
3734887Schin }
3744887Schin else if (!isspace(c))
3754887Schin {
3764887Schin if (c == '<')
3774887Schin {
3784887Schin c = sfgetc(ip);
3794887Schin if (c == EOF)
3804887Schin break;
3814887Schin sfungetc(ip, c);
3824887Schin sfungetc(ip, '<');
3834887Schin if (c != 'L' && c != '/')
3844887Schin sfputc(op, ' ');
3854887Schin }
3864887Schin else
3874887Schin {
3884887Schin if (c != EOF)
3894887Schin sfungetc(ip, c);
3904887Schin sfputc(op, ' ');
3914887Schin }
3924887Schin break;
3934887Schin }
3944887Schin continue;
3954887Schin case '\r':
3964887Schin case '[':
3974887Schin case ']':
3984887Schin continue;
3994887Schin default:
4004887Schin sfpututf(op, c);
4014887Schin continue;
4024887Schin }
4034887Schin break;
4044887Schin }
4054887Schin if (q)
4064887Schin sfputc(op, q);
4074887Schin sfputc(op, '\n');
4084887Schin }
4094887Schin
4104887Schin static void
encode(Sfio_t * op,register int c)4114887Schin encode(Sfio_t* op, register int c)
4124887Schin {
4134887Schin if (c == '<')
4144887Schin sfprintf(op, "<");
4154887Schin else if (c == '>')
4164887Schin sfprintf(op, ">");
4174887Schin else if (c == '"')
4184887Schin sfprintf(op, """);
4194887Schin else if (c == '&')
4204887Schin sfprintf(op, "&");
4214887Schin else if (c == '[')
4224887Schin sfprintf(op, "[");
4234887Schin else if (c == ']')
4244887Schin sfprintf(op, "]");
4254887Schin else
4264887Schin sfputc(op, c);
4274887Schin }
4284887Schin
4294887Schin static void
msg2html(register Sfio_t * ip,register Sfio_t * op,register int flags)4304887Schin msg2html(register Sfio_t* ip, register Sfio_t* op, register int flags)
4314887Schin {
4324887Schin register char* s;
4334887Schin register int c;
4344887Schin register int q;
4354887Schin register int p;
4364887Schin
4374887Schin sfprintf(op, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\"><HTML><HEAD><!-- text massaged for external translation --></HEAD><BODY>\n");
4384887Schin sfprintf(op, "<OL START=\"550717\">\n");
4394887Schin p = q = 0;
4404887Schin while (s = sfgetr(ip, '\n', 1))
4414887Schin {
4424887Schin error_info.line++;
4434887Schin if (flags)
4444887Schin sfprintf(op, "<P>");
4454887Schin else
4464887Schin {
4474887Schin if (*s == '$')
4484887Schin {
4494887Schin if (p)
4504887Schin sfprintf(op, "<P>");
4514887Schin else
4524887Schin p = 1;
4534887Schin sfprintf(op, "<P CLASS=\"", s);
4544887Schin while (c = *s++)
4554887Schin encode(op, c);
4564887Schin sfprintf(op, "\">\n");
4574887Schin continue;
4584887Schin }
4594887Schin p = 0;
4604887Schin if (!isdigit(*s))
4614887Schin continue;
4624887Schin sfprintf(op, "<LI>");
4634887Schin while (isdigit(c = *s++))
4644887Schin sfputc(op, c);
4654887Schin sfprintf(op, "<LI>");
4664887Schin while (c && c != '"')
4674887Schin c = *s++;
4684887Schin if (!c)
4694887Schin s--;
4704887Schin else if (isspace(*s))
4714887Schin {
4724887Schin s++;
4734887Schin sfprintf(op, "<BR>");
4744887Schin }
4754887Schin }
4764887Schin for (;;)
4774887Schin {
4784887Schin switch (c = *s++)
4794887Schin {
4804887Schin case 0:
4814887Schin flags &= ~MSG_SPLICE;
4824887Schin if (q)
4834887Schin {
4844887Schin q = 0;
4854887Schin sfprintf(op, "\">");
4864887Schin }
4874887Schin sfputc(op, '\n');
4884887Schin break;
4894887Schin case '<':
4904887Schin sfprintf(op, "<");
4914887Schin continue;
4924887Schin case '>':
4934887Schin sfprintf(op, ">");
4944887Schin continue;
4954887Schin case '&':
4964887Schin sfprintf(op, "&");
4974887Schin continue;
4984887Schin case '[':
4994887Schin sfprintf(op, "[");
5004887Schin continue;
5014887Schin case ']':
5024887Schin sfprintf(op, "]");
5034887Schin continue;
5044887Schin case '$':
5054887Schin if (!q)
5064887Schin {
5074887Schin q = 1;
5084887Schin sfprintf(op, "<P CLASS=\"");
5094887Schin }
5104887Schin sfputc(op, c);
5114887Schin while (isalnum(c = *s++))
5124887Schin sfputc(op, c);
5134887Schin s--;
5144887Schin continue;
5154887Schin case '%':
5164887Schin if (!q)
5174887Schin {
5184887Schin q = 1;
5194887Schin sfprintf(op, "<P CLASS=\"");
5204887Schin }
5214887Schin sfputc(op, c);
5224887Schin if (*s == '%')
5234887Schin sfputc(op, *s++);
5244887Schin else
5254887Schin do
5264887Schin {
5274887Schin if (!(c = *s++) || c == '"')
5284887Schin {
5294887Schin s--;
5304887Schin break;
5314887Schin }
5324887Schin encode(op, c);
5334887Schin } while (!isalpha(c) || (!islower(c) || c == 'h' || c == 'l') && isalpha(*s));
5344887Schin if (SPACE(s))
5354887Schin sfprintf(op, " ");
5364887Schin continue;
5374887Schin case '"':
5384887Schin if (!(flags & MSG_RAW))
5394887Schin {
5404887Schin s = "";
5414887Schin continue;
5424887Schin }
5434887Schin /*FALLTHROUGH*/
5444887Schin case '\'':
5454887Schin case ':':
5464887Schin case '/':
5474887Schin case '+':
5484887Schin case '@':
5494887Schin if (!q)
5504887Schin {
5514887Schin q = 1;
5524887Schin sfprintf(op, "<P CLASS=\"");
5534887Schin }
5544887Schin /*FALLTHROUGH*/
5554887Schin case '.':
5564887Schin case ',':
5574887Schin sfputc(op, c);
5584887Schin if (SPACE(s))
5594887Schin sfprintf(op, " ");
5604887Schin continue;
5614887Schin case '\\':
5624887Schin if (!(c = *s++))
5634887Schin {
5644887Schin flags |= MSG_SPLICE;
5654887Schin break;
5664887Schin }
5674887Schin if (c != 'n' && c != 't')
5684887Schin {
5694887Schin if (!q)
5704887Schin {
5714887Schin q = 1;
5724887Schin sfprintf(op, "<P CLASS=\"");
5734887Schin }
5744887Schin sfputc(op, '\\');
5754887Schin encode(op, c);
5764887Schin if (c == 'b')
5774887Schin {
5784887Schin for (;;)
5794887Schin {
5804887Schin if (!(c = *s++) || c == '"')
5814887Schin {
5824887Schin s--;
5834887Schin break;
5844887Schin }
5854887Schin if (c == '?')
5864887Schin {
5874887Schin if (*s != '?')
5884887Schin {
5894887Schin s--;
5904887Schin break;
5914887Schin }
5924887Schin sfputc(op, c);
5934887Schin sfputc(op, *s++);
5944887Schin continue;
5954887Schin }
5964887Schin if (c == '\\')
5974887Schin {
5984887Schin if (!*s)
5994887Schin break;
6004887Schin sfputc(op, c);
6014887Schin if (*s == 'a' || *s == 'b' || *s == '0')
6024887Schin {
6034887Schin sfputc(op, *s++);
6044887Schin break;
6054887Schin }
6064887Schin c = *s++;
6074887Schin }
6084887Schin encode(op, c);
6094887Schin }
6104887Schin }
6114887Schin else if (isdigit(c) && isdigit(*s))
6124887Schin {
6134887Schin sfputc(op, *s++);
6144887Schin if (isdigit(*s))
6154887Schin sfputc(op, *s++);
6164887Schin }
6174887Schin if (SPACE(s))
6184887Schin sfprintf(op, " ");
6194887Schin continue;
6204887Schin }
6214887Schin /*FALLTHROUGH*/
6224887Schin case ' ':
6234887Schin case '\t':
6244887Schin while (isspace(*s) || *s == '\\' && (*(s + 1) == 'n' || *(s + 1) == 't') && s++)
6254887Schin s++;
6264887Schin if (*s == '"')
6274887Schin {
6284887Schin if (q)
6294887Schin {
6304887Schin q = 0;
6314887Schin sfprintf(op, " \">");
6324887Schin }
6334887Schin else
6344887Schin sfprintf(op, "<BR>");
6354887Schin continue;
6364887Schin }
6374887Schin c = ' ';
6384887Schin /*FALLTHROUGH*/
6394887Schin default:
6404887Schin if (q)
6414887Schin {
6424887Schin q = 0;
6434887Schin sfprintf(op, "\">");
6444887Schin }
6454887Schin sfputc(op, c);
6464887Schin continue;
6474887Schin }
6484887Schin break;
6494887Schin }
6504887Schin }
6514887Schin sfprintf(op, "</OL>\n");
6524887Schin sfprintf(op, "</BODY></HTML>\n");
6534887Schin error_info.line = 0;
6544887Schin }
6554887Schin
6564887Schin int
main(int argc,char ** argv)6574887Schin main(int argc, char** argv)
6584887Schin {
6594887Schin int flags = 0;
6604887Schin Convert_f convert = msg2html;
6614887Schin
6624887Schin NoP(argc);
6634887Schin error_info.id = "msgcvt";
6644887Schin for (;;)
6654887Schin {
6664887Schin switch (optget(argv, usage))
6674887Schin {
6684887Schin case 'h':
6694887Schin convert = msg2html;
6704887Schin continue;
6714887Schin case 'm':
6724887Schin convert = html2msg;
6734887Schin continue;
6744887Schin case 'r':
6754887Schin flags |= MSG_RAW;
6764887Schin continue;
6774887Schin case '?':
6784887Schin error(ERROR_USAGE|4, "%s", opt_info.arg);
6794887Schin continue;
6804887Schin case ':':
6814887Schin error(2, "%s", opt_info.arg);
6824887Schin continue;
6834887Schin }
6844887Schin break;
6854887Schin }
6864887Schin argv += opt_info.index;
6874887Schin if (error_info.errors)
6884887Schin error(ERROR_USAGE|4, "%s", optusage(NiL));
6894887Schin (*convert)(sfstdin, sfstdout, flags);
6904887Schin return error_info.errors != 0;
6914887Schin }
692