1 /*
2  * IRC - Internet Relay Chat, ircd/ircd_snprintf.c
3  * Copyright (C) 2000 Kevin L. Mitchell <klmitch@mit.edu>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 1, or (at your option)
8  * any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */
19 /** @file
20  * @brief IRC-specific printf() clone implementation.
21  * @version $Id$
22  */
23 #include "config.h"
24 
25 #include "client.h"
26 #include "channel.h"
27 #include "ircd_log.h"
28 #include "ircd_snprintf.h"
29 #include "struct.h"
30 
31 /* #include <assert.h> -- Now using assert in ircd_log.h */
32 #include <errno.h>
33 #include <stddef.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <time.h>
37 
38 /* Inhibit complaints when we use GCC extensions */
39 #if defined(__GNUC__) && SIZEOF_LONG_LONG
40 # define EXTENSION __extension__
41 #else
42 /** Fallback (empty) definition of EXTENSION. */
43 # define EXTENSION
44 #endif
45 
46 /* Find the largest type */
47 #if SIZEOF_LONG_LONG
48 EXTENSION typedef long long _large_t;
49 EXTENSION typedef unsigned long long _ularge_t;
50 # define SIZEOF__LARGE_T SIZEOF_LONG_LONG
51 /* Oh, if long long happens to be the size of void *, set _pointer_t, too */
52 # if SIZEOF_LONG_LONG == SIZEOF_VOID_P
53 typedef _ularge_t _pointer_t;
54 #  define HAVE_POINTER_T
55 # endif
56 #else
57 /** Fallback definition of the largest integer type. */
58 typedef long _large_t;
59 /** Fallback definition of the largest unsigned integer type. */
60 typedef unsigned long _ularge_t;
61 /** Fallback definition of SIZEOF__LARGE_T. */
62 # define SIZEOF__LARGE_T SIZEOF_LONG
63 #endif
64 
65 /* Select something for _pointer_t */
66 #ifndef HAVE_POINTER_T
67 # if SIZEOF_LONG == SIZEOF_VOID_P
68 /** Unsigned integer type large enough to hold a pointer. */
69 typedef unsigned long _pointer_t;
70 # elif SIZEOF_INT == SIZEOF_VOID_P
71 typedef unsigned int _pointer_t;
72 # else
73 #  error Unable to find a suitable type for _pointer_t
74 # endif
75 #endif /* HAVE_POINTER_T */
76 
77 /** rough length sufficient to hold an octal number, since those can be large */
78 #define INTBUF_LEN (SIZEOF__LARGE_T * 3)
79 
80 /** Return minimum of \a i1 and \a i2. */
81 #define SNP_MIN(i1, i2)	((i1) < (i2) ? (i1) : (i2))
82 /** Return maximum of \a i1 and \a i2. */
83 #define SNP_MAX(i1, i2)	((i1) > (i2) ? (i1) : (i2))
84 /** Indicate total number of bytes "pseudo-output" in buffer. */
85 #define TOTAL(buf_p)	((buf_p)->buf_loc + \
86 			 SNP_MAX((buf_p)->buf_overflow, (buf_p)->overflow))
87 
88 #define WIDTH_MAX	999	/**< keep from overflowing width */
89 
90 /** data about the output buffer */
91 struct BufData {
92   char	       *buf;		/**< pointer to buffer */
93   size_t	buf_size;	/**< maximum size of buffer */
94   size_t	buf_overflow;	/**< how much buffer has been overflowed */
95   size_t	buf_loc;	/**< where we are in the buffer */
96   short		limit;		/**< max # of chars to convert */
97   size_t	overflow;	/**< how much we overflowed the limit */
98 };
99 
100 /** initializer for BufData */
101 #define BUFDATA_INIT	{ 0, 0, 0, 0, 0, 0 }
102 
103 /** data about format fields */
104 struct FieldData {
105   unsigned int	flags;		/**< flags describing argument */
106   short		base;		/**< base for integer conversions */
107   short		width;		/**< width of field */
108   short		prec;		/**< precision of field */
109   union {
110     _ularge_t	v_int;		/**< an integer value */
111     long double	v_float;	/**< a floating point value -- NOT SUPPORTED */
112     void       *v_ptr;		/**< a pointer value */
113   }		value;		/**< value of a field */
114 };
115 
116 /** initializer for FieldData */
117 #define FIELDDATA_INIT	{ 0, 0, 0, 0, { 0 } }
118 
119 /* Specifier flags */
120 #define FLAG_MINUS	0x00000001	/**< found a '-' flag */
121 #define FLAG_PLUS	0x00000002	/**< found a '+' flag */
122 #define FLAG_SPACE	0x00000004	/**< found a ' ' flag */
123 #define FLAG_ALT	0x00000008	/**< found a '#' flag */
124 #define FLAG_ZERO	0x00000010	/**< found a '0' flag */
125 #define FLAG_COLON	0x00000020	/**< found a ':' flag */
126 
127 #define FLAG_RESERVED1	0x00000040	/**< reserved for future expansion */
128 #define FLAG_RESERVED0	0x00000080	/**< reserved for future expansion */
129 
130 /* integer types */
131 #define TYPE_CHAR	0x00000100	/**< number is a char */
132 #define TYPE_SHORT	0x00000200	/**< number is a short */
133 #define TYPE_LONG	0x00000400	/**< number is a long */
134 #define TYPE_QUAD	0x00000800	/**< number is a quad */
135 
136 /* special integer types */
137 #define TYPE_INTMAX	0x00001000	/**< number is an intmax_t */
138 #define TYPE_PTRDIFF	0x00002000	/**< number is a ptrdiff_t */
139 #define TYPE_SIZE	0x00004000	/**< number is a size_t */
140 #define TYPE_TIME	0x00008000	/**< number is a time_t */
141 #define TYPE_POINTER	0x00010000	/**< number is a pointer_t */
142 
143 /* floating point types */
144 #define TYPE_LONGDOUBLE	0x00020000	/**< number is a long double */
145 
146 #define TYPE_RESERVED1	0x00040000	/**< reserved for future expansion */
147 #define TYPE_RESERVED0	0x00080000	/**< reserved for future expansion */
148 
149 /** Mask to get just the type data */
150 #define TYPE_MASK	(TYPE_CHAR | TYPE_SHORT | TYPE_LONG | TYPE_QUAD | \
151 			 TYPE_INTMAX | TYPE_PTRDIFF | TYPE_SIZE | TYPE_TIME | \
152 			 TYPE_POINTER | TYPE_LONGDOUBLE)
153 
154 /* type of argument to extract */
155 #define ARG_INT		0x00100000	/**< argument is an integer */
156 #define ARG_FLOAT	0x00200000	/**< argument is a float */
157 #define ARG_PTR		0x00300000	/**< argument is a pointer */
158 
159 #define ARG_RESERVED11	0x00400000	/**< reserved for future expansion */
160 #define ARG_RESERVED10	0x00500000	/**< reserved for future expansion */
161 #define ARG_RESERVED9	0x00600000	/**< reserved for future expansion */
162 #define ARG_RESERVED8	0x00700000	/**< reserved for future expansion */
163 #define ARG_RESERVED7	0x00800000	/**< reserved for future expansion */
164 #define ARG_RESERVED6	0x00900000	/**< reserved for future expansion */
165 #define ARG_RESERVED5	0x00a00000	/**< reserved for future expansion */
166 #define ARG_RESERVED4	0x00b00000	/**< reserved for future expansion */
167 #define ARG_RESERVED3	0x00c00000	/**< reserved for future expansion */
168 #define ARG_RESERVED2	0x00d00000	/**< reserved for future expansion */
169 #define ARG_RESERVED1	0x00e00000	/**< reserved for future expansion */
170 #define ARG_RESERVED0	0x00f00000	/**< reserved for future expansion */
171 
172 /* Mask to get just the argument data */
173 #define ARG_MASK	0x00f00000      /**< masks off non-argument bits */
174 
175 /* type of conversion to perform */
176 #define CONV_INT	0x01000000	/**< convert integers */
177 #define CONV_FLOAT	0x02000000	/**< convert floats */
178 #define CONV_CHAR	0x03000000	/**< convert chars */
179 #define CONV_STRING	0x04000000	/**< convert strings */
180 #define CONV_VARARGS	0x05000000	/**< convert a %v */
181 #define CONV_CLIENT	0x06000000	/**< convert a struct Client */
182 #define CONV_CHANNEL	0x07000000	/**< convert a struct Channel */
183 
184 #define CONV_RESERVED7	0x08000000	/**< reserved for future expansion */
185 #define CONV_RESERVED6	0x09000000	/**< reserved for future expansion */
186 #define CONV_RESERVED5	0x0a000000	/**< reserved for future expansion */
187 #define CONV_RESERVED4	0x0b000000	/**< reserved for future expansion */
188 #define CONV_RESERVED3	0x0c000000	/**< reserved for future expansion */
189 #define CONV_RESERVED2	0x0d000000	/**< reserved for future expansion */
190 #define CONV_RESERVED1	0x0e000000	/**< reserved for future expansion */
191 #define CONV_RESERVED0	0x0f000000	/**< reserved for future expansion */
192 
193 /* Mask to get just the conversion data */
194 #define CONV_MASK	0x0f000000      /**< masks off non-conversion bits */
195 
196 /* Value information flags */
197 #define INFO_RESERVED0	0x10000000	/**< reserved for future expansion */
198 #define INFO_UPPERCASE	0x20000000	/**< use uppercase characters */
199 #define INFO_UNSIGNED	0x40000000	/**< number is unsigned */
200 #define INFO_NEGATIVE	0x80000000	/**< number is negative */
201 
202 #define BASE_OCTAL	9	/**< octal base; bits-per-char * 3 */
203 #define BASE_DECIMAL	-1000	/**< decimal base; 10 ** 3 */
204 #define BASE_HEX	12	/**< hexadecimal base; bits-per-char * 3 */
205 
206 
207 /* padding...			 1	   2	     3	       4	 5 */
208 /*			12345678901234567890123456789012345678901234567890 */
209 /** Predefined space padding. */
210 static char spaces[] = "                                                  ";
211 /** Predefined zero padding. */
212 static char zeros[]  = "00000000000000000000000000000000000000000000000000";
213 
214 /** Length of predefined padding strings. */
215 #define PAD_LENGTH	(sizeof(spaces) - 1)
216 
217 /*
218  * Note that these string tables have characters reversed.  There is, of
219  * course, a reason for this; check out how they're built in doprintf.
220  */
221 
222 /** string table for octal values */
223 static char *octal[] = {
224      "",   "1",   "2",   "3",   "4",   "5",   "6",   "7",
225    "01",  "11",  "21",  "31",  "41",  "51",  "61",  "71",
226    "02",  "12",  "22",  "32",  "42",  "52",  "62",  "72",
227    "03",  "13",  "23",  "33",  "43",  "53",  "63",  "73",
228    "04",  "14",  "24",  "34",  "44",  "54",  "64",  "74",
229    "05",  "15",  "25",  "35",  "45",  "55",  "65",  "75",
230    "06",  "16",  "26",  "36",  "46",  "56",  "66",  "76",
231    "07",  "17",  "27",  "37",  "47",  "57",  "67",  "77",
232   "001", "101", "201", "301", "401", "501", "601", "701",
233   "011", "111", "211", "311", "411", "511", "611", "711",
234   "021", "121", "221", "321", "421", "521", "621", "721",
235   "031", "131", "231", "331", "431", "531", "631", "731",
236   "041", "141", "241", "341", "441", "541", "641", "741",
237   "051", "151", "251", "351", "451", "551", "651", "751",
238   "061", "161", "261", "361", "461", "561", "661", "761",
239   "071", "171", "271", "371", "471", "571", "671", "771",
240   "002", "102", "202", "302", "402", "502", "602", "702",
241   "012", "112", "212", "312", "412", "512", "612", "712",
242   "022", "122", "222", "322", "422", "522", "622", "722",
243   "032", "132", "232", "332", "432", "532", "632", "732",
244   "042", "142", "242", "342", "442", "542", "642", "742",
245   "052", "152", "252", "352", "452", "552", "652", "752",
246   "062", "162", "262", "362", "462", "562", "662", "762",
247   "072", "172", "272", "372", "472", "572", "672", "772",
248   "003", "103", "203", "303", "403", "503", "603", "703",
249   "013", "113", "213", "313", "413", "513", "613", "713",
250   "023", "123", "223", "323", "423", "523", "623", "723",
251   "033", "133", "233", "333", "433", "533", "633", "733",
252   "043", "143", "243", "343", "443", "543", "643", "743",
253   "053", "153", "253", "353", "453", "553", "653", "753",
254   "063", "163", "263", "363", "463", "563", "663", "763",
255   "073", "173", "273", "373", "473", "573", "673", "773",
256   "004", "104", "204", "304", "404", "504", "604", "704",
257   "014", "114", "214", "314", "414", "514", "614", "714",
258   "024", "124", "224", "324", "424", "524", "624", "724",
259   "034", "134", "234", "334", "434", "534", "634", "734",
260   "044", "144", "244", "344", "444", "544", "644", "744",
261   "054", "154", "254", "354", "454", "554", "654", "754",
262   "064", "164", "264", "364", "464", "564", "664", "764",
263   "074", "174", "274", "374", "474", "574", "674", "774",
264   "005", "105", "205", "305", "405", "505", "605", "705",
265   "015", "115", "215", "315", "415", "515", "615", "715",
266   "025", "125", "225", "325", "425", "525", "625", "725",
267   "035", "135", "235", "335", "435", "535", "635", "735",
268   "045", "145", "245", "345", "445", "545", "645", "745",
269   "055", "155", "255", "355", "455", "555", "655", "755",
270   "065", "165", "265", "365", "465", "565", "665", "765",
271   "075", "175", "275", "375", "475", "575", "675", "775",
272   "006", "106", "206", "306", "406", "506", "606", "706",
273   "016", "116", "216", "316", "416", "516", "616", "716",
274   "026", "126", "226", "326", "426", "526", "626", "726",
275   "036", "136", "236", "336", "436", "536", "636", "736",
276   "046", "146", "246", "346", "446", "546", "646", "746",
277   "056", "156", "256", "356", "456", "556", "656", "756",
278   "066", "166", "266", "366", "466", "566", "666", "766",
279   "076", "176", "276", "376", "476", "576", "676", "776",
280   "007", "107", "207", "307", "407", "507", "607", "707",
281   "017", "117", "217", "317", "417", "517", "617", "717",
282   "027", "127", "227", "327", "427", "527", "627", "727",
283   "037", "137", "237", "337", "437", "537", "637", "737",
284   "047", "147", "247", "347", "447", "547", "647", "747",
285   "057", "157", "257", "357", "457", "557", "657", "757",
286   "067", "167", "267", "367", "467", "567", "667", "767",
287   "077", "177", "277", "377", "477", "577", "677", "777"
288 };
289 
290 /** string table for decimal values */
291 static char *decimal[] = {
292      "",   "1",   "2",   "3",   "4",   "5",   "6",   "7",   "8",   "9",
293    "01",  "11",  "21",  "31",  "41",  "51",  "61",  "71",  "81",  "91",
294    "02",  "12",  "22",  "32",  "42",  "52",  "62",  "72",  "82",  "92",
295    "03",  "13",  "23",  "33",  "43",  "53",  "63",  "73",  "83",  "93",
296    "04",  "14",  "24",  "34",  "44",  "54",  "64",  "74",  "84",  "94",
297    "05",  "15",  "25",  "35",  "45",  "55",  "65",  "75",  "85",  "95",
298    "06",  "16",  "26",  "36",  "46",  "56",  "66",  "76",  "86",  "96",
299    "07",  "17",  "27",  "37",  "47",  "57",  "67",  "77",  "87",  "97",
300    "08",  "18",  "28",  "38",  "48",  "58",  "68",  "78",  "88",  "98",
301    "09",  "19",  "29",  "39",  "49",  "59",  "69",  "79",  "89",  "99",
302   "001", "101", "201", "301", "401", "501", "601", "701", "801", "901",
303   "011", "111", "211", "311", "411", "511", "611", "711", "811", "911",
304   "021", "121", "221", "321", "421", "521", "621", "721", "821", "921",
305   "031", "131", "231", "331", "431", "531", "631", "731", "831", "931",
306   "041", "141", "241", "341", "441", "541", "641", "741", "841", "941",
307   "051", "151", "251", "351", "451", "551", "651", "751", "851", "951",
308   "061", "161", "261", "361", "461", "561", "661", "761", "861", "961",
309   "071", "171", "271", "371", "471", "571", "671", "771", "871", "971",
310   "081", "181", "281", "381", "481", "581", "681", "781", "881", "981",
311   "091", "191", "291", "391", "491", "591", "691", "791", "891", "991",
312   "002", "102", "202", "302", "402", "502", "602", "702", "802", "902",
313   "012", "112", "212", "312", "412", "512", "612", "712", "812", "912",
314   "022", "122", "222", "322", "422", "522", "622", "722", "822", "922",
315   "032", "132", "232", "332", "432", "532", "632", "732", "832", "932",
316   "042", "142", "242", "342", "442", "542", "642", "742", "842", "942",
317   "052", "152", "252", "352", "452", "552", "652", "752", "852", "952",
318   "062", "162", "262", "362", "462", "562", "662", "762", "862", "962",
319   "072", "172", "272", "372", "472", "572", "672", "772", "872", "972",
320   "082", "182", "282", "382", "482", "582", "682", "782", "882", "982",
321   "092", "192", "292", "392", "492", "592", "692", "792", "892", "992",
322   "003", "103", "203", "303", "403", "503", "603", "703", "803", "903",
323   "013", "113", "213", "313", "413", "513", "613", "713", "813", "913",
324   "023", "123", "223", "323", "423", "523", "623", "723", "823", "923",
325   "033", "133", "233", "333", "433", "533", "633", "733", "833", "933",
326   "043", "143", "243", "343", "443", "543", "643", "743", "843", "943",
327   "053", "153", "253", "353", "453", "553", "653", "753", "853", "953",
328   "063", "163", "263", "363", "463", "563", "663", "763", "863", "963",
329   "073", "173", "273", "373", "473", "573", "673", "773", "873", "973",
330   "083", "183", "283", "383", "483", "583", "683", "783", "883", "983",
331   "093", "193", "293", "393", "493", "593", "693", "793", "893", "993",
332   "004", "104", "204", "304", "404", "504", "604", "704", "804", "904",
333   "014", "114", "214", "314", "414", "514", "614", "714", "814", "914",
334   "024", "124", "224", "324", "424", "524", "624", "724", "824", "924",
335   "034", "134", "234", "334", "434", "534", "634", "734", "834", "934",
336   "044", "144", "244", "344", "444", "544", "644", "744", "844", "944",
337   "054", "154", "254", "354", "454", "554", "654", "754", "854", "954",
338   "064", "164", "264", "364", "464", "564", "664", "764", "864", "964",
339   "074", "174", "274", "374", "474", "574", "674", "774", "874", "974",
340   "084", "184", "284", "384", "484", "584", "684", "784", "884", "984",
341   "094", "194", "294", "394", "494", "594", "694", "794", "894", "994",
342   "005", "105", "205", "305", "405", "505", "605", "705", "805", "905",
343   "015", "115", "215", "315", "415", "515", "615", "715", "815", "915",
344   "025", "125", "225", "325", "425", "525", "625", "725", "825", "925",
345   "035", "135", "235", "335", "435", "535", "635", "735", "835", "935",
346   "045", "145", "245", "345", "445", "545", "645", "745", "845", "945",
347   "055", "155", "255", "355", "455", "555", "655", "755", "855", "955",
348   "065", "165", "265", "365", "465", "565", "665", "765", "865", "965",
349   "075", "175", "275", "375", "475", "575", "675", "775", "875", "975",
350   "085", "185", "285", "385", "485", "585", "685", "785", "885", "985",
351   "095", "195", "295", "395", "495", "595", "695", "795", "895", "995",
352   "006", "106", "206", "306", "406", "506", "606", "706", "806", "906",
353   "016", "116", "216", "316", "416", "516", "616", "716", "816", "916",
354   "026", "126", "226", "326", "426", "526", "626", "726", "826", "926",
355   "036", "136", "236", "336", "436", "536", "636", "736", "836", "936",
356   "046", "146", "246", "346", "446", "546", "646", "746", "846", "946",
357   "056", "156", "256", "356", "456", "556", "656", "756", "856", "956",
358   "066", "166", "266", "366", "466", "566", "666", "766", "866", "966",
359   "076", "176", "276", "376", "476", "576", "676", "776", "876", "976",
360   "086", "186", "286", "386", "486", "586", "686", "786", "886", "986",
361   "096", "196", "296", "396", "496", "596", "696", "796", "896", "996",
362   "007", "107", "207", "307", "407", "507", "607", "707", "807", "907",
363   "017", "117", "217", "317", "417", "517", "617", "717", "817", "917",
364   "027", "127", "227", "327", "427", "527", "627", "727", "827", "927",
365   "037", "137", "237", "337", "437", "537", "637", "737", "837", "937",
366   "047", "147", "247", "347", "447", "547", "647", "747", "847", "947",
367   "057", "157", "257", "357", "457", "557", "657", "757", "857", "957",
368   "067", "167", "267", "367", "467", "567", "667", "767", "867", "967",
369   "077", "177", "277", "377", "477", "577", "677", "777", "877", "977",
370   "087", "187", "287", "387", "487", "587", "687", "787", "887", "987",
371   "097", "197", "297", "397", "497", "597", "697", "797", "897", "997",
372   "008", "108", "208", "308", "408", "508", "608", "708", "808", "908",
373   "018", "118", "218", "318", "418", "518", "618", "718", "818", "918",
374   "028", "128", "228", "328", "428", "528", "628", "728", "828", "928",
375   "038", "138", "238", "338", "438", "538", "638", "738", "838", "938",
376   "048", "148", "248", "348", "448", "548", "648", "748", "848", "948",
377   "058", "158", "258", "358", "458", "558", "658", "758", "858", "958",
378   "068", "168", "268", "368", "468", "568", "668", "768", "868", "968",
379   "078", "178", "278", "378", "478", "578", "678", "778", "878", "978",
380   "088", "188", "288", "388", "488", "588", "688", "788", "888", "988",
381   "098", "198", "298", "398", "498", "598", "698", "798", "898", "998",
382   "009", "109", "209", "309", "409", "509", "609", "709", "809", "909",
383   "019", "119", "219", "319", "419", "519", "619", "719", "819", "919",
384   "029", "129", "229", "329", "429", "529", "629", "729", "829", "929",
385   "039", "139", "239", "339", "439", "539", "639", "739", "839", "939",
386   "049", "149", "249", "349", "449", "549", "649", "749", "849", "949",
387   "059", "159", "259", "359", "459", "559", "659", "759", "859", "959",
388   "069", "169", "269", "369", "469", "569", "669", "769", "869", "969",
389   "079", "179", "279", "379", "479", "579", "679", "779", "879", "979",
390   "089", "189", "289", "389", "489", "589", "689", "789", "889", "989",
391   "099", "199", "299", "399", "499", "599", "699", "799", "899", "999"
392 };
393 
394 /** string table for lower-case hexadecimal values */
395 static char *hex[] = {
396      "",   "1",   "2",   "3",   "4",   "5",   "6",   "7",
397     "8",   "9",   "a",   "b",   "c",   "d",   "e",   "f",
398    "01",  "11",  "21",  "31",  "41",  "51",  "61",  "71",
399    "81",  "91",  "a1",  "b1",  "c1",  "d1",  "e1",  "f1",
400    "02",  "12",  "22",  "32",  "42",  "52",  "62",  "72",
401    "82",  "92",  "a2",  "b2",  "c2",  "d2",  "e2",  "f2",
402    "03",  "13",  "23",  "33",  "43",  "53",  "63",  "73",
403    "83",  "93",  "a3",  "b3",  "c3",  "d3",  "e3",  "f3",
404    "04",  "14",  "24",  "34",  "44",  "54",  "64",  "74",
405    "84",  "94",  "a4",  "b4",  "c4",  "d4",  "e4",  "f4",
406    "05",  "15",  "25",  "35",  "45",  "55",  "65",  "75",
407    "85",  "95",  "a5",  "b5",  "c5",  "d5",  "e5",  "f5",
408    "06",  "16",  "26",  "36",  "46",  "56",  "66",  "76",
409    "86",  "96",  "a6",  "b6",  "c6",  "d6",  "e6",  "f6",
410    "07",  "17",  "27",  "37",  "47",  "57",  "67",  "77",
411    "87",  "97",  "a7",  "b7",  "c7",  "d7",  "e7",  "f7",
412    "08",  "18",  "28",  "38",  "48",  "58",  "68",  "78",
413    "88",  "98",  "a8",  "b8",  "c8",  "d8",  "e8",  "f8",
414    "09",  "19",  "29",  "39",  "49",  "59",  "69",  "79",
415    "89",  "99",  "a9",  "b9",  "c9",  "d9",  "e9",  "f9",
416    "0a",  "1a",  "2a",  "3a",  "4a",  "5a",  "6a",  "7a",
417    "8a",  "9a",  "aa",  "ba",  "ca",  "da",  "ea",  "fa",
418    "0b",  "1b",  "2b",  "3b",  "4b",  "5b",  "6b",  "7b",
419    "8b",  "9b",  "ab",  "bb",  "cb",  "db",  "eb",  "fb",
420    "0c",  "1c",  "2c",  "3c",  "4c",  "5c",  "6c",  "7c",
421    "8c",  "9c",  "ac",  "bc",  "cc",  "dc",  "ec",  "fc",
422    "0d",  "1d",  "2d",  "3d",  "4d",  "5d",  "6d",  "7d",
423    "8d",  "9d",  "ad",  "bd",  "cd",  "dd",  "ed",  "fd",
424    "0e",  "1e",  "2e",  "3e",  "4e",  "5e",  "6e",  "7e",
425    "8e",  "9e",  "ae",  "be",  "ce",  "de",  "ee",  "fe",
426    "0f",  "1f",  "2f",  "3f",  "4f",  "5f",  "6f",  "7f",
427    "8f",  "9f",  "af",  "bf",  "cf",  "df",  "ef",  "ff",
428   "001", "101", "201", "301", "401", "501", "601", "701",
429   "801", "901", "a01", "b01", "c01", "d01", "e01", "f01",
430   "011", "111", "211", "311", "411", "511", "611", "711",
431   "811", "911", "a11", "b11", "c11", "d11", "e11", "f11",
432   "021", "121", "221", "321", "421", "521", "621", "721",
433   "821", "921", "a21", "b21", "c21", "d21", "e21", "f21",
434   "031", "131", "231", "331", "431", "531", "631", "731",
435   "831", "931", "a31", "b31", "c31", "d31", "e31", "f31",
436   "041", "141", "241", "341", "441", "541", "641", "741",
437   "841", "941", "a41", "b41", "c41", "d41", "e41", "f41",
438   "051", "151", "251", "351", "451", "551", "651", "751",
439   "851", "951", "a51", "b51", "c51", "d51", "e51", "f51",
440   "061", "161", "261", "361", "461", "561", "661", "761",
441   "861", "961", "a61", "b61", "c61", "d61", "e61", "f61",
442   "071", "171", "271", "371", "471", "571", "671", "771",
443   "871", "971", "a71", "b71", "c71", "d71", "e71", "f71",
444   "081", "181", "281", "381", "481", "581", "681", "781",
445   "881", "981", "a81", "b81", "c81", "d81", "e81", "f81",
446   "091", "191", "291", "391", "491", "591", "691", "791",
447   "891", "991", "a91", "b91", "c91", "d91", "e91", "f91",
448   "0a1", "1a1", "2a1", "3a1", "4a1", "5a1", "6a1", "7a1",
449   "8a1", "9a1", "aa1", "ba1", "ca1", "da1", "ea1", "fa1",
450   "0b1", "1b1", "2b1", "3b1", "4b1", "5b1", "6b1", "7b1",
451   "8b1", "9b1", "ab1", "bb1", "cb1", "db1", "eb1", "fb1",
452   "0c1", "1c1", "2c1", "3c1", "4c1", "5c1", "6c1", "7c1",
453   "8c1", "9c1", "ac1", "bc1", "cc1", "dc1", "ec1", "fc1",
454   "0d1", "1d1", "2d1", "3d1", "4d1", "5d1", "6d1", "7d1",
455   "8d1", "9d1", "ad1", "bd1", "cd1", "dd1", "ed1", "fd1",
456   "0e1", "1e1", "2e1", "3e1", "4e1", "5e1", "6e1", "7e1",
457   "8e1", "9e1", "ae1", "be1", "ce1", "de1", "ee1", "fe1",
458   "0f1", "1f1", "2f1", "3f1", "4f1", "5f1", "6f1", "7f1",
459   "8f1", "9f1", "af1", "bf1", "cf1", "df1", "ef1", "ff1",
460   "002", "102", "202", "302", "402", "502", "602", "702",
461   "802", "902", "a02", "b02", "c02", "d02", "e02", "f02",
462   "012", "112", "212", "312", "412", "512", "612", "712",
463   "812", "912", "a12", "b12", "c12", "d12", "e12", "f12",
464   "022", "122", "222", "322", "422", "522", "622", "722",
465   "822", "922", "a22", "b22", "c22", "d22", "e22", "f22",
466   "032", "132", "232", "332", "432", "532", "632", "732",
467   "832", "932", "a32", "b32", "c32", "d32", "e32", "f32",
468   "042", "142", "242", "342", "442", "542", "642", "742",
469   "842", "942", "a42", "b42", "c42", "d42", "e42", "f42",
470   "052", "152", "252", "352", "452", "552", "652", "752",
471   "852", "952", "a52", "b52", "c52", "d52", "e52", "f52",
472   "062", "162", "262", "362", "462", "562", "662", "762",
473   "862", "962", "a62", "b62", "c62", "d62", "e62", "f62",
474   "072", "172", "272", "372", "472", "572", "672", "772",
475   "872", "972", "a72", "b72", "c72", "d72", "e72", "f72",
476   "082", "182", "282", "382", "482", "582", "682", "782",
477   "882", "982", "a82", "b82", "c82", "d82", "e82", "f82",
478   "092", "192", "292", "392", "492", "592", "692", "792",
479   "892", "992", "a92", "b92", "c92", "d92", "e92", "f92",
480   "0a2", "1a2", "2a2", "3a2", "4a2", "5a2", "6a2", "7a2",
481   "8a2", "9a2", "aa2", "ba2", "ca2", "da2", "ea2", "fa2",
482   "0b2", "1b2", "2b2", "3b2", "4b2", "5b2", "6b2", "7b2",
483   "8b2", "9b2", "ab2", "bb2", "cb2", "db2", "eb2", "fb2",
484   "0c2", "1c2", "2c2", "3c2", "4c2", "5c2", "6c2", "7c2",
485   "8c2", "9c2", "ac2", "bc2", "cc2", "dc2", "ec2", "fc2",
486   "0d2", "1d2", "2d2", "3d2", "4d2", "5d2", "6d2", "7d2",
487   "8d2", "9d2", "ad2", "bd2", "cd2", "dd2", "ed2", "fd2",
488   "0e2", "1e2", "2e2", "3e2", "4e2", "5e2", "6e2", "7e2",
489   "8e2", "9e2", "ae2", "be2", "ce2", "de2", "ee2", "fe2",
490   "0f2", "1f2", "2f2", "3f2", "4f2", "5f2", "6f2", "7f2",
491   "8f2", "9f2", "af2", "bf2", "cf2", "df2", "ef2", "ff2",
492   "003", "103", "203", "303", "403", "503", "603", "703",
493   "803", "903", "a03", "b03", "c03", "d03", "e03", "f03",
494   "013", "113", "213", "313", "413", "513", "613", "713",
495   "813", "913", "a13", "b13", "c13", "d13", "e13", "f13",
496   "023", "123", "223", "323", "423", "523", "623", "723",
497   "823", "923", "a23", "b23", "c23", "d23", "e23", "f23",
498   "033", "133", "233", "333", "433", "533", "633", "733",
499   "833", "933", "a33", "b33", "c33", "d33", "e33", "f33",
500   "043", "143", "243", "343", "443", "543", "643", "743",
501   "843", "943", "a43", "b43", "c43", "d43", "e43", "f43",
502   "053", "153", "253", "353", "453", "553", "653", "753",
503   "853", "953", "a53", "b53", "c53", "d53", "e53", "f53",
504   "063", "163", "263", "363", "463", "563", "663", "763",
505   "863", "963", "a63", "b63", "c63", "d63", "e63", "f63",
506   "073", "173", "273", "373", "473", "573", "673", "773",
507   "873", "973", "a73", "b73", "c73", "d73", "e73", "f73",
508   "083", "183", "283", "383", "483", "583", "683", "783",
509   "883", "983", "a83", "b83", "c83", "d83", "e83", "f83",
510   "093", "193", "293", "393", "493", "593", "693", "793",
511   "893", "993", "a93", "b93", "c93", "d93", "e93", "f93",
512   "0a3", "1a3", "2a3", "3a3", "4a3", "5a3", "6a3", "7a3",
513   "8a3", "9a3", "aa3", "ba3", "ca3", "da3", "ea3", "fa3",
514   "0b3", "1b3", "2b3", "3b3", "4b3", "5b3", "6b3", "7b3",
515   "8b3", "9b3", "ab3", "bb3", "cb3", "db3", "eb3", "fb3",
516   "0c3", "1c3", "2c3", "3c3", "4c3", "5c3", "6c3", "7c3",
517   "8c3", "9c3", "ac3", "bc3", "cc3", "dc3", "ec3", "fc3",
518   "0d3", "1d3", "2d3", "3d3", "4d3", "5d3", "6d3", "7d3",
519   "8d3", "9d3", "ad3", "bd3", "cd3", "dd3", "ed3", "fd3",
520   "0e3", "1e3", "2e3", "3e3", "4e3", "5e3", "6e3", "7e3",
521   "8e3", "9e3", "ae3", "be3", "ce3", "de3", "ee3", "fe3",
522   "0f3", "1f3", "2f3", "3f3", "4f3", "5f3", "6f3", "7f3",
523   "8f3", "9f3", "af3", "bf3", "cf3", "df3", "ef3", "ff3",
524   "004", "104", "204", "304", "404", "504", "604", "704",
525   "804", "904", "a04", "b04", "c04", "d04", "e04", "f04",
526   "014", "114", "214", "314", "414", "514", "614", "714",
527   "814", "914", "a14", "b14", "c14", "d14", "e14", "f14",
528   "024", "124", "224", "324", "424", "524", "624", "724",
529   "824", "924", "a24", "b24", "c24", "d24", "e24", "f24",
530   "034", "134", "234", "334", "434", "534", "634", "734",
531   "834", "934", "a34", "b34", "c34", "d34", "e34", "f34",
532   "044", "144", "244", "344", "444", "544", "644", "744",
533   "844", "944", "a44", "b44", "c44", "d44", "e44", "f44",
534   "054", "154", "254", "354", "454", "554", "654", "754",
535   "854", "954", "a54", "b54", "c54", "d54", "e54", "f54",
536   "064", "164", "264", "364", "464", "564", "664", "764",
537   "864", "964", "a64", "b64", "c64", "d64", "e64", "f64",
538   "074", "174", "274", "374", "474", "574", "674", "774",
539   "874", "974", "a74", "b74", "c74", "d74", "e74", "f74",
540   "084", "184", "284", "384", "484", "584", "684", "784",
541   "884", "984", "a84", "b84", "c84", "d84", "e84", "f84",
542   "094", "194", "294", "394", "494", "594", "694", "794",
543   "894", "994", "a94", "b94", "c94", "d94", "e94", "f94",
544   "0a4", "1a4", "2a4", "3a4", "4a4", "5a4", "6a4", "7a4",
545   "8a4", "9a4", "aa4", "ba4", "ca4", "da4", "ea4", "fa4",
546   "0b4", "1b4", "2b4", "3b4", "4b4", "5b4", "6b4", "7b4",
547   "8b4", "9b4", "ab4", "bb4", "cb4", "db4", "eb4", "fb4",
548   "0c4", "1c4", "2c4", "3c4", "4c4", "5c4", "6c4", "7c4",
549   "8c4", "9c4", "ac4", "bc4", "cc4", "dc4", "ec4", "fc4",
550   "0d4", "1d4", "2d4", "3d4", "4d4", "5d4", "6d4", "7d4",
551   "8d4", "9d4", "ad4", "bd4", "cd4", "dd4", "ed4", "fd4",
552   "0e4", "1e4", "2e4", "3e4", "4e4", "5e4", "6e4", "7e4",
553   "8e4", "9e4", "ae4", "be4", "ce4", "de4", "ee4", "fe4",
554   "0f4", "1f4", "2f4", "3f4", "4f4", "5f4", "6f4", "7f4",
555   "8f4", "9f4", "af4", "bf4", "cf4", "df4", "ef4", "ff4",
556   "005", "105", "205", "305", "405", "505", "605", "705",
557   "805", "905", "a05", "b05", "c05", "d05", "e05", "f05",
558   "015", "115", "215", "315", "415", "515", "615", "715",
559   "815", "915", "a15", "b15", "c15", "d15", "e15", "f15",
560   "025", "125", "225", "325", "425", "525", "625", "725",
561   "825", "925", "a25", "b25", "c25", "d25", "e25", "f25",
562   "035", "135", "235", "335", "435", "535", "635", "735",
563   "835", "935", "a35", "b35", "c35", "d35", "e35", "f35",
564   "045", "145", "245", "345", "445", "545", "645", "745",
565   "845", "945", "a45", "b45", "c45", "d45", "e45", "f45",
566   "055", "155", "255", "355", "455", "555", "655", "755",
567   "855", "955", "a55", "b55", "c55", "d55", "e55", "f55",
568   "065", "165", "265", "365", "465", "565", "665", "765",
569   "865", "965", "a65", "b65", "c65", "d65", "e65", "f65",
570   "075", "175", "275", "375", "475", "575", "675", "775",
571   "875", "975", "a75", "b75", "c75", "d75", "e75", "f75",
572   "085", "185", "285", "385", "485", "585", "685", "785",
573   "885", "985", "a85", "b85", "c85", "d85", "e85", "f85",
574   "095", "195", "295", "395", "495", "595", "695", "795",
575   "895", "995", "a95", "b95", "c95", "d95", "e95", "f95",
576   "0a5", "1a5", "2a5", "3a5", "4a5", "5a5", "6a5", "7a5",
577   "8a5", "9a5", "aa5", "ba5", "ca5", "da5", "ea5", "fa5",
578   "0b5", "1b5", "2b5", "3b5", "4b5", "5b5", "6b5", "7b5",
579   "8b5", "9b5", "ab5", "bb5", "cb5", "db5", "eb5", "fb5",
580   "0c5", "1c5", "2c5", "3c5", "4c5", "5c5", "6c5", "7c5",
581   "8c5", "9c5", "ac5", "bc5", "cc5", "dc5", "ec5", "fc5",
582   "0d5", "1d5", "2d5", "3d5", "4d5", "5d5", "6d5", "7d5",
583   "8d5", "9d5", "ad5", "bd5", "cd5", "dd5", "ed5", "fd5",
584   "0e5", "1e5", "2e5", "3e5", "4e5", "5e5", "6e5", "7e5",
585   "8e5", "9e5", "ae5", "be5", "ce5", "de5", "ee5", "fe5",
586   "0f5", "1f5", "2f5", "3f5", "4f5", "5f5", "6f5", "7f5",
587   "8f5", "9f5", "af5", "bf5", "cf5", "df5", "ef5", "ff5",
588   "006", "106", "206", "306", "406", "506", "606", "706",
589   "806", "906", "a06", "b06", "c06", "d06", "e06", "f06",
590   "016", "116", "216", "316", "416", "516", "616", "716",
591   "816", "916", "a16", "b16", "c16", "d16", "e16", "f16",
592   "026", "126", "226", "326", "426", "526", "626", "726",
593   "826", "926", "a26", "b26", "c26", "d26", "e26", "f26",
594   "036", "136", "236", "336", "436", "536", "636", "736",
595   "836", "936", "a36", "b36", "c36", "d36", "e36", "f36",
596   "046", "146", "246", "346", "446", "546", "646", "746",
597   "846", "946", "a46", "b46", "c46", "d46", "e46", "f46",
598   "056", "156", "256", "356", "456", "556", "656", "756",
599   "856", "956", "a56", "b56", "c56", "d56", "e56", "f56",
600   "066", "166", "266", "366", "466", "566", "666", "766",
601   "866", "966", "a66", "b66", "c66", "d66", "e66", "f66",
602   "076", "176", "276", "376", "476", "576", "676", "776",
603   "876", "976", "a76", "b76", "c76", "d76", "e76", "f76",
604   "086", "186", "286", "386", "486", "586", "686", "786",
605   "886", "986", "a86", "b86", "c86", "d86", "e86", "f86",
606   "096", "196", "296", "396", "496", "596", "696", "796",
607   "896", "996", "a96", "b96", "c96", "d96", "e96", "f96",
608   "0a6", "1a6", "2a6", "3a6", "4a6", "5a6", "6a6", "7a6",
609   "8a6", "9a6", "aa6", "ba6", "ca6", "da6", "ea6", "fa6",
610   "0b6", "1b6", "2b6", "3b6", "4b6", "5b6", "6b6", "7b6",
611   "8b6", "9b6", "ab6", "bb6", "cb6", "db6", "eb6", "fb6",
612   "0c6", "1c6", "2c6", "3c6", "4c6", "5c6", "6c6", "7c6",
613   "8c6", "9c6", "ac6", "bc6", "cc6", "dc6", "ec6", "fc6",
614   "0d6", "1d6", "2d6", "3d6", "4d6", "5d6", "6d6", "7d6",
615   "8d6", "9d6", "ad6", "bd6", "cd6", "dd6", "ed6", "fd6",
616   "0e6", "1e6", "2e6", "3e6", "4e6", "5e6", "6e6", "7e6",
617   "8e6", "9e6", "ae6", "be6", "ce6", "de6", "ee6", "fe6",
618   "0f6", "1f6", "2f6", "3f6", "4f6", "5f6", "6f6", "7f6",
619   "8f6", "9f6", "af6", "bf6", "cf6", "df6", "ef6", "ff6",
620   "007", "107", "207", "307", "407", "507", "607", "707",
621   "807", "907", "a07", "b07", "c07", "d07", "e07", "f07",
622   "017", "117", "217", "317", "417", "517", "617", "717",
623   "817", "917", "a17", "b17", "c17", "d17", "e17", "f17",
624   "027", "127", "227", "327", "427", "527", "627", "727",
625   "827", "927", "a27", "b27", "c27", "d27", "e27", "f27",
626   "037", "137", "237", "337", "437", "537", "637", "737",
627   "837", "937", "a37", "b37", "c37", "d37", "e37", "f37",
628   "047", "147", "247", "347", "447", "547", "647", "747",
629   "847", "947", "a47", "b47", "c47", "d47", "e47", "f47",
630   "057", "157", "257", "357", "457", "557", "657", "757",
631   "857", "957", "a57", "b57", "c57", "d57", "e57", "f57",
632   "067", "167", "267", "367", "467", "567", "667", "767",
633   "867", "967", "a67", "b67", "c67", "d67", "e67", "f67",
634   "077", "177", "277", "377", "477", "577", "677", "777",
635   "877", "977", "a77", "b77", "c77", "d77", "e77", "f77",
636   "087", "187", "287", "387", "487", "587", "687", "787",
637   "887", "987", "a87", "b87", "c87", "d87", "e87", "f87",
638   "097", "197", "297", "397", "497", "597", "697", "797",
639   "897", "997", "a97", "b97", "c97", "d97", "e97", "f97",
640   "0a7", "1a7", "2a7", "3a7", "4a7", "5a7", "6a7", "7a7",
641   "8a7", "9a7", "aa7", "ba7", "ca7", "da7", "ea7", "fa7",
642   "0b7", "1b7", "2b7", "3b7", "4b7", "5b7", "6b7", "7b7",
643   "8b7", "9b7", "ab7", "bb7", "cb7", "db7", "eb7", "fb7",
644   "0c7", "1c7", "2c7", "3c7", "4c7", "5c7", "6c7", "7c7",
645   "8c7", "9c7", "ac7", "bc7", "cc7", "dc7", "ec7", "fc7",
646   "0d7", "1d7", "2d7", "3d7", "4d7", "5d7", "6d7", "7d7",
647   "8d7", "9d7", "ad7", "bd7", "cd7", "dd7", "ed7", "fd7",
648   "0e7", "1e7", "2e7", "3e7", "4e7", "5e7", "6e7", "7e7",
649   "8e7", "9e7", "ae7", "be7", "ce7", "de7", "ee7", "fe7",
650   "0f7", "1f7", "2f7", "3f7", "4f7", "5f7", "6f7", "7f7",
651   "8f7", "9f7", "af7", "bf7", "cf7", "df7", "ef7", "ff7",
652   "008", "108", "208", "308", "408", "508", "608", "708",
653   "808", "908", "a08", "b08", "c08", "d08", "e08", "f08",
654   "018", "118", "218", "318", "418", "518", "618", "718",
655   "818", "918", "a18", "b18", "c18", "d18", "e18", "f18",
656   "028", "128", "228", "328", "428", "528", "628", "728",
657   "828", "928", "a28", "b28", "c28", "d28", "e28", "f28",
658   "038", "138", "238", "338", "438", "538", "638", "738",
659   "838", "938", "a38", "b38", "c38", "d38", "e38", "f38",
660   "048", "148", "248", "348", "448", "548", "648", "748",
661   "848", "948", "a48", "b48", "c48", "d48", "e48", "f48",
662   "058", "158", "258", "358", "458", "558", "658", "758",
663   "858", "958", "a58", "b58", "c58", "d58", "e58", "f58",
664   "068", "168", "268", "368", "468", "568", "668", "768",
665   "868", "968", "a68", "b68", "c68", "d68", "e68", "f68",
666   "078", "178", "278", "378", "478", "578", "678", "778",
667   "878", "978", "a78", "b78", "c78", "d78", "e78", "f78",
668   "088", "188", "288", "388", "488", "588", "688", "788",
669   "888", "988", "a88", "b88", "c88", "d88", "e88", "f88",
670   "098", "198", "298", "398", "498", "598", "698", "798",
671   "898", "998", "a98", "b98", "c98", "d98", "e98", "f98",
672   "0a8", "1a8", "2a8", "3a8", "4a8", "5a8", "6a8", "7a8",
673   "8a8", "9a8", "aa8", "ba8", "ca8", "da8", "ea8", "fa8",
674   "0b8", "1b8", "2b8", "3b8", "4b8", "5b8", "6b8", "7b8",
675   "8b8", "9b8", "ab8", "bb8", "cb8", "db8", "eb8", "fb8",
676   "0c8", "1c8", "2c8", "3c8", "4c8", "5c8", "6c8", "7c8",
677   "8c8", "9c8", "ac8", "bc8", "cc8", "dc8", "ec8", "fc8",
678   "0d8", "1d8", "2d8", "3d8", "4d8", "5d8", "6d8", "7d8",
679   "8d8", "9d8", "ad8", "bd8", "cd8", "dd8", "ed8", "fd8",
680   "0e8", "1e8", "2e8", "3e8", "4e8", "5e8", "6e8", "7e8",
681   "8e8", "9e8", "ae8", "be8", "ce8", "de8", "ee8", "fe8",
682   "0f8", "1f8", "2f8", "3f8", "4f8", "5f8", "6f8", "7f8",
683   "8f8", "9f8", "af8", "bf8", "cf8", "df8", "ef8", "ff8",
684   "009", "109", "209", "309", "409", "509", "609", "709",
685   "809", "909", "a09", "b09", "c09", "d09", "e09", "f09",
686   "019", "119", "219", "319", "419", "519", "619", "719",
687   "819", "919", "a19", "b19", "c19", "d19", "e19", "f19",
688   "029", "129", "229", "329", "429", "529", "629", "729",
689   "829", "929", "a29", "b29", "c29", "d29", "e29", "f29",
690   "039", "139", "239", "339", "439", "539", "639", "739",
691   "839", "939", "a39", "b39", "c39", "d39", "e39", "f39",
692   "049", "149", "249", "349", "449", "549", "649", "749",
693   "849", "949", "a49", "b49", "c49", "d49", "e49", "f49",
694   "059", "159", "259", "359", "459", "559", "659", "759",
695   "859", "959", "a59", "b59", "c59", "d59", "e59", "f59",
696   "069", "169", "269", "369", "469", "569", "669", "769",
697   "869", "969", "a69", "b69", "c69", "d69", "e69", "f69",
698   "079", "179", "279", "379", "479", "579", "679", "779",
699   "879", "979", "a79", "b79", "c79", "d79", "e79", "f79",
700   "089", "189", "289", "389", "489", "589", "689", "789",
701   "889", "989", "a89", "b89", "c89", "d89", "e89", "f89",
702   "099", "199", "299", "399", "499", "599", "699", "799",
703   "899", "999", "a99", "b99", "c99", "d99", "e99", "f99",
704   "0a9", "1a9", "2a9", "3a9", "4a9", "5a9", "6a9", "7a9",
705   "8a9", "9a9", "aa9", "ba9", "ca9", "da9", "ea9", "fa9",
706   "0b9", "1b9", "2b9", "3b9", "4b9", "5b9", "6b9", "7b9",
707   "8b9", "9b9", "ab9", "bb9", "cb9", "db9", "eb9", "fb9",
708   "0c9", "1c9", "2c9", "3c9", "4c9", "5c9", "6c9", "7c9",
709   "8c9", "9c9", "ac9", "bc9", "cc9", "dc9", "ec9", "fc9",
710   "0d9", "1d9", "2d9", "3d9", "4d9", "5d9", "6d9", "7d9",
711   "8d9", "9d9", "ad9", "bd9", "cd9", "dd9", "ed9", "fd9",
712   "0e9", "1e9", "2e9", "3e9", "4e9", "5e9", "6e9", "7e9",
713   "8e9", "9e9", "ae9", "be9", "ce9", "de9", "ee9", "fe9",
714   "0f9", "1f9", "2f9", "3f9", "4f9", "5f9", "6f9", "7f9",
715   "8f9", "9f9", "af9", "bf9", "cf9", "df9", "ef9", "ff9",
716   "00a", "10a", "20a", "30a", "40a", "50a", "60a", "70a",
717   "80a", "90a", "a0a", "b0a", "c0a", "d0a", "e0a", "f0a",
718   "01a", "11a", "21a", "31a", "41a", "51a", "61a", "71a",
719   "81a", "91a", "a1a", "b1a", "c1a", "d1a", "e1a", "f1a",
720   "02a", "12a", "22a", "32a", "42a", "52a", "62a", "72a",
721   "82a", "92a", "a2a", "b2a", "c2a", "d2a", "e2a", "f2a",
722   "03a", "13a", "23a", "33a", "43a", "53a", "63a", "73a",
723   "83a", "93a", "a3a", "b3a", "c3a", "d3a", "e3a", "f3a",
724   "04a", "14a", "24a", "34a", "44a", "54a", "64a", "74a",
725   "84a", "94a", "a4a", "b4a", "c4a", "d4a", "e4a", "f4a",
726   "05a", "15a", "25a", "35a", "45a", "55a", "65a", "75a",
727   "85a", "95a", "a5a", "b5a", "c5a", "d5a", "e5a", "f5a",
728   "06a", "16a", "26a", "36a", "46a", "56a", "66a", "76a",
729   "86a", "96a", "a6a", "b6a", "c6a", "d6a", "e6a", "f6a",
730   "07a", "17a", "27a", "37a", "47a", "57a", "67a", "77a",
731   "87a", "97a", "a7a", "b7a", "c7a", "d7a", "e7a", "f7a",
732   "08a", "18a", "28a", "38a", "48a", "58a", "68a", "78a",
733   "88a", "98a", "a8a", "b8a", "c8a", "d8a", "e8a", "f8a",
734   "09a", "19a", "29a", "39a", "49a", "59a", "69a", "79a",
735   "89a", "99a", "a9a", "b9a", "c9a", "d9a", "e9a", "f9a",
736   "0aa", "1aa", "2aa", "3aa", "4aa", "5aa", "6aa", "7aa",
737   "8aa", "9aa", "aaa", "baa", "caa", "daa", "eaa", "faa",
738   "0ba", "1ba", "2ba", "3ba", "4ba", "5ba", "6ba", "7ba",
739   "8ba", "9ba", "aba", "bba", "cba", "dba", "eba", "fba",
740   "0ca", "1ca", "2ca", "3ca", "4ca", "5ca", "6ca", "7ca",
741   "8ca", "9ca", "aca", "bca", "cca", "dca", "eca", "fca",
742   "0da", "1da", "2da", "3da", "4da", "5da", "6da", "7da",
743   "8da", "9da", "ada", "bda", "cda", "dda", "eda", "fda",
744   "0ea", "1ea", "2ea", "3ea", "4ea", "5ea", "6ea", "7ea",
745   "8ea", "9ea", "aea", "bea", "cea", "dea", "eea", "fea",
746   "0fa", "1fa", "2fa", "3fa", "4fa", "5fa", "6fa", "7fa",
747   "8fa", "9fa", "afa", "bfa", "cfa", "dfa", "efa", "ffa",
748   "00b", "10b", "20b", "30b", "40b", "50b", "60b", "70b",
749   "80b", "90b", "a0b", "b0b", "c0b", "d0b", "e0b", "f0b",
750   "01b", "11b", "21b", "31b", "41b", "51b", "61b", "71b",
751   "81b", "91b", "a1b", "b1b", "c1b", "d1b", "e1b", "f1b",
752   "02b", "12b", "22b", "32b", "42b", "52b", "62b", "72b",
753   "82b", "92b", "a2b", "b2b", "c2b", "d2b", "e2b", "f2b",
754   "03b", "13b", "23b", "33b", "43b", "53b", "63b", "73b",
755   "83b", "93b", "a3b", "b3b", "c3b", "d3b", "e3b", "f3b",
756   "04b", "14b", "24b", "34b", "44b", "54b", "64b", "74b",
757   "84b", "94b", "a4b", "b4b", "c4b", "d4b", "e4b", "f4b",
758   "05b", "15b", "25b", "35b", "45b", "55b", "65b", "75b",
759   "85b", "95b", "a5b", "b5b", "c5b", "d5b", "e5b", "f5b",
760   "06b", "16b", "26b", "36b", "46b", "56b", "66b", "76b",
761   "86b", "96b", "a6b", "b6b", "c6b", "d6b", "e6b", "f6b",
762   "07b", "17b", "27b", "37b", "47b", "57b", "67b", "77b",
763   "87b", "97b", "a7b", "b7b", "c7b", "d7b", "e7b", "f7b",
764   "08b", "18b", "28b", "38b", "48b", "58b", "68b", "78b",
765   "88b", "98b", "a8b", "b8b", "c8b", "d8b", "e8b", "f8b",
766   "09b", "19b", "29b", "39b", "49b", "59b", "69b", "79b",
767   "89b", "99b", "a9b", "b9b", "c9b", "d9b", "e9b", "f9b",
768   "0ab", "1ab", "2ab", "3ab", "4ab", "5ab", "6ab", "7ab",
769   "8ab", "9ab", "aab", "bab", "cab", "dab", "eab", "fab",
770   "0bb", "1bb", "2bb", "3bb", "4bb", "5bb", "6bb", "7bb",
771   "8bb", "9bb", "abb", "bbb", "cbb", "dbb", "ebb", "fbb",
772   "0cb", "1cb", "2cb", "3cb", "4cb", "5cb", "6cb", "7cb",
773   "8cb", "9cb", "acb", "bcb", "ccb", "dcb", "ecb", "fcb",
774   "0db", "1db", "2db", "3db", "4db", "5db", "6db", "7db",
775   "8db", "9db", "adb", "bdb", "cdb", "ddb", "edb", "fdb",
776   "0eb", "1eb", "2eb", "3eb", "4eb", "5eb", "6eb", "7eb",
777   "8eb", "9eb", "aeb", "beb", "ceb", "deb", "eeb", "feb",
778   "0fb", "1fb", "2fb", "3fb", "4fb", "5fb", "6fb", "7fb",
779   "8fb", "9fb", "afb", "bfb", "cfb", "dfb", "efb", "ffb",
780   "00c", "10c", "20c", "30c", "40c", "50c", "60c", "70c",
781   "80c", "90c", "a0c", "b0c", "c0c", "d0c", "e0c", "f0c",
782   "01c", "11c", "21c", "31c", "41c", "51c", "61c", "71c",
783   "81c", "91c", "a1c", "b1c", "c1c", "d1c", "e1c", "f1c",
784   "02c", "12c", "22c", "32c", "42c", "52c", "62c", "72c",
785   "82c", "92c", "a2c", "b2c", "c2c", "d2c", "e2c", "f2c",
786   "03c", "13c", "23c", "33c", "43c", "53c", "63c", "73c",
787   "83c", "93c", "a3c", "b3c", "c3c", "d3c", "e3c", "f3c",
788   "04c", "14c", "24c", "34c", "44c", "54c", "64c", "74c",
789   "84c", "94c", "a4c", "b4c", "c4c", "d4c", "e4c", "f4c",
790   "05c", "15c", "25c", "35c", "45c", "55c", "65c", "75c",
791   "85c", "95c", "a5c", "b5c", "c5c", "d5c", "e5c", "f5c",
792   "06c", "16c", "26c", "36c", "46c", "56c", "66c", "76c",
793   "86c", "96c", "a6c", "b6c", "c6c", "d6c", "e6c", "f6c",
794   "07c", "17c", "27c", "37c", "47c", "57c", "67c", "77c",
795   "87c", "97c", "a7c", "b7c", "c7c", "d7c", "e7c", "f7c",
796   "08c", "18c", "28c", "38c", "48c", "58c", "68c", "78c",
797   "88c", "98c", "a8c", "b8c", "c8c", "d8c", "e8c", "f8c",
798   "09c", "19c", "29c", "39c", "49c", "59c", "69c", "79c",
799   "89c", "99c", "a9c", "b9c", "c9c", "d9c", "e9c", "f9c",
800   "0ac", "1ac", "2ac", "3ac", "4ac", "5ac", "6ac", "7ac",
801   "8ac", "9ac", "aac", "bac", "cac", "dac", "eac", "fac",
802   "0bc", "1bc", "2bc", "3bc", "4bc", "5bc", "6bc", "7bc",
803   "8bc", "9bc", "abc", "bbc", "cbc", "dbc", "ebc", "fbc",
804   "0cc", "1cc", "2cc", "3cc", "4cc", "5cc", "6cc", "7cc",
805   "8cc", "9cc", "acc", "bcc", "ccc", "dcc", "ecc", "fcc",
806   "0dc", "1dc", "2dc", "3dc", "4dc", "5dc", "6dc", "7dc",
807   "8dc", "9dc", "adc", "bdc", "cdc", "ddc", "edc", "fdc",
808   "0ec", "1ec", "2ec", "3ec", "4ec", "5ec", "6ec", "7ec",
809   "8ec", "9ec", "aec", "bec", "cec", "dec", "eec", "fec",
810   "0fc", "1fc", "2fc", "3fc", "4fc", "5fc", "6fc", "7fc",
811   "8fc", "9fc", "afc", "bfc", "cfc", "dfc", "efc", "ffc",
812   "00d", "10d", "20d", "30d", "40d", "50d", "60d", "70d",
813   "80d", "90d", "a0d", "b0d", "c0d", "d0d", "e0d", "f0d",
814   "01d", "11d", "21d", "31d", "41d", "51d", "61d", "71d",
815   "81d", "91d", "a1d", "b1d", "c1d", "d1d", "e1d", "f1d",
816   "02d", "12d", "22d", "32d", "42d", "52d", "62d", "72d",
817   "82d", "92d", "a2d", "b2d", "c2d", "d2d", "e2d", "f2d",
818   "03d", "13d", "23d", "33d", "43d", "53d", "63d", "73d",
819   "83d", "93d", "a3d", "b3d", "c3d", "d3d", "e3d", "f3d",
820   "04d", "14d", "24d", "34d", "44d", "54d", "64d", "74d",
821   "84d", "94d", "a4d", "b4d", "c4d", "d4d", "e4d", "f4d",
822   "05d", "15d", "25d", "35d", "45d", "55d", "65d", "75d",
823   "85d", "95d", "a5d", "b5d", "c5d", "d5d", "e5d", "f5d",
824   "06d", "16d", "26d", "36d", "46d", "56d", "66d", "76d",
825   "86d", "96d", "a6d", "b6d", "c6d", "d6d", "e6d", "f6d",
826   "07d", "17d", "27d", "37d", "47d", "57d", "67d", "77d",
827   "87d", "97d", "a7d", "b7d", "c7d", "d7d", "e7d", "f7d",
828   "08d", "18d", "28d", "38d", "48d", "58d", "68d", "78d",
829   "88d", "98d", "a8d", "b8d", "c8d", "d8d", "e8d", "f8d",
830   "09d", "19d", "29d", "39d", "49d", "59d", "69d", "79d",
831   "89d", "99d", "a9d", "b9d", "c9d", "d9d", "e9d", "f9d",
832   "0ad", "1ad", "2ad", "3ad", "4ad", "5ad", "6ad", "7ad",
833   "8ad", "9ad", "aad", "bad", "cad", "dad", "ead", "fad",
834   "0bd", "1bd", "2bd", "3bd", "4bd", "5bd", "6bd", "7bd",
835   "8bd", "9bd", "abd", "bbd", "cbd", "dbd", "ebd", "fbd",
836   "0cd", "1cd", "2cd", "3cd", "4cd", "5cd", "6cd", "7cd",
837   "8cd", "9cd", "acd", "bcd", "ccd", "dcd", "ecd", "fcd",
838   "0dd", "1dd", "2dd", "3dd", "4dd", "5dd", "6dd", "7dd",
839   "8dd", "9dd", "add", "bdd", "cdd", "ddd", "edd", "fdd",
840   "0ed", "1ed", "2ed", "3ed", "4ed", "5ed", "6ed", "7ed",
841   "8ed", "9ed", "aed", "bed", "ced", "ded", "eed", "fed",
842   "0fd", "1fd", "2fd", "3fd", "4fd", "5fd", "6fd", "7fd",
843   "8fd", "9fd", "afd", "bfd", "cfd", "dfd", "efd", "ffd",
844   "00e", "10e", "20e", "30e", "40e", "50e", "60e", "70e",
845   "80e", "90e", "a0e", "b0e", "c0e", "d0e", "e0e", "f0e",
846   "01e", "11e", "21e", "31e", "41e", "51e", "61e", "71e",
847   "81e", "91e", "a1e", "b1e", "c1e", "d1e", "e1e", "f1e",
848   "02e", "12e", "22e", "32e", "42e", "52e", "62e", "72e",
849   "82e", "92e", "a2e", "b2e", "c2e", "d2e", "e2e", "f2e",
850   "03e", "13e", "23e", "33e", "43e", "53e", "63e", "73e",
851   "83e", "93e", "a3e", "b3e", "c3e", "d3e", "e3e", "f3e",
852   "04e", "14e", "24e", "34e", "44e", "54e", "64e", "74e",
853   "84e", "94e", "a4e", "b4e", "c4e", "d4e", "e4e", "f4e",
854   "05e", "15e", "25e", "35e", "45e", "55e", "65e", "75e",
855   "85e", "95e", "a5e", "b5e", "c5e", "d5e", "e5e", "f5e",
856   "06e", "16e", "26e", "36e", "46e", "56e", "66e", "76e",
857   "86e", "96e", "a6e", "b6e", "c6e", "d6e", "e6e", "f6e",
858   "07e", "17e", "27e", "37e", "47e", "57e", "67e", "77e",
859   "87e", "97e", "a7e", "b7e", "c7e", "d7e", "e7e", "f7e",
860   "08e", "18e", "28e", "38e", "48e", "58e", "68e", "78e",
861   "88e", "98e", "a8e", "b8e", "c8e", "d8e", "e8e", "f8e",
862   "09e", "19e", "29e", "39e", "49e", "59e", "69e", "79e",
863   "89e", "99e", "a9e", "b9e", "c9e", "d9e", "e9e", "f9e",
864   "0ae", "1ae", "2ae", "3ae", "4ae", "5ae", "6ae", "7ae",
865   "8ae", "9ae", "aae", "bae", "cae", "dae", "eae", "fae",
866   "0be", "1be", "2be", "3be", "4be", "5be", "6be", "7be",
867   "8be", "9be", "abe", "bbe", "cbe", "dbe", "ebe", "fbe",
868   "0ce", "1ce", "2ce", "3ce", "4ce", "5ce", "6ce", "7ce",
869   "8ce", "9ce", "ace", "bce", "cce", "dce", "ece", "fce",
870   "0de", "1de", "2de", "3de", "4de", "5de", "6de", "7de",
871   "8de", "9de", "ade", "bde", "cde", "dde", "ede", "fde",
872   "0ee", "1ee", "2ee", "3ee", "4ee", "5ee", "6ee", "7ee",
873   "8ee", "9ee", "aee", "bee", "cee", "dee", "eee", "fee",
874   "0fe", "1fe", "2fe", "3fe", "4fe", "5fe", "6fe", "7fe",
875   "8fe", "9fe", "afe", "bfe", "cfe", "dfe", "efe", "ffe",
876   "00f", "10f", "20f", "30f", "40f", "50f", "60f", "70f",
877   "80f", "90f", "a0f", "b0f", "c0f", "d0f", "e0f", "f0f",
878   "01f", "11f", "21f", "31f", "41f", "51f", "61f", "71f",
879   "81f", "91f", "a1f", "b1f", "c1f", "d1f", "e1f", "f1f",
880   "02f", "12f", "22f", "32f", "42f", "52f", "62f", "72f",
881   "82f", "92f", "a2f", "b2f", "c2f", "d2f", "e2f", "f2f",
882   "03f", "13f", "23f", "33f", "43f", "53f", "63f", "73f",
883   "83f", "93f", "a3f", "b3f", "c3f", "d3f", "e3f", "f3f",
884   "04f", "14f", "24f", "34f", "44f", "54f", "64f", "74f",
885   "84f", "94f", "a4f", "b4f", "c4f", "d4f", "e4f", "f4f",
886   "05f", "15f", "25f", "35f", "45f", "55f", "65f", "75f",
887   "85f", "95f", "a5f", "b5f", "c5f", "d5f", "e5f", "f5f",
888   "06f", "16f", "26f", "36f", "46f", "56f", "66f", "76f",
889   "86f", "96f", "a6f", "b6f", "c6f", "d6f", "e6f", "f6f",
890   "07f", "17f", "27f", "37f", "47f", "57f", "67f", "77f",
891   "87f", "97f", "a7f", "b7f", "c7f", "d7f", "e7f", "f7f",
892   "08f", "18f", "28f", "38f", "48f", "58f", "68f", "78f",
893   "88f", "98f", "a8f", "b8f", "c8f", "d8f", "e8f", "f8f",
894   "09f", "19f", "29f", "39f", "49f", "59f", "69f", "79f",
895   "89f", "99f", "a9f", "b9f", "c9f", "d9f", "e9f", "f9f",
896   "0af", "1af", "2af", "3af", "4af", "5af", "6af", "7af",
897   "8af", "9af", "aaf", "baf", "caf", "daf", "eaf", "faf",
898   "0bf", "1bf", "2bf", "3bf", "4bf", "5bf", "6bf", "7bf",
899   "8bf", "9bf", "abf", "bbf", "cbf", "dbf", "ebf", "fbf",
900   "0cf", "1cf", "2cf", "3cf", "4cf", "5cf", "6cf", "7cf",
901   "8cf", "9cf", "acf", "bcf", "ccf", "dcf", "ecf", "fcf",
902   "0df", "1df", "2df", "3df", "4df", "5df", "6df", "7df",
903   "8df", "9df", "adf", "bdf", "cdf", "ddf", "edf", "fdf",
904   "0ef", "1ef", "2ef", "3ef", "4ef", "5ef", "6ef", "7ef",
905   "8ef", "9ef", "aef", "bef", "cef", "def", "eef", "fef",
906   "0ff", "1ff", "2ff", "3ff", "4ff", "5ff", "6ff", "7ff",
907   "8ff", "9ff", "aff", "bff", "cff", "dff", "eff", "fff"
908 };
909 
910 /** string table for upper-case hexadecimal values */
911 static char *HEX[] = {
912      "",   "1",   "2",   "3",   "4",   "5",   "6",   "7",
913     "8",   "9",   "A",   "B",   "C",   "D",   "E",   "F",
914    "01",  "11",  "21",  "31",  "41",  "51",  "61",  "71",
915    "81",  "91",  "A1",  "B1",  "C1",  "D1",  "E1",  "F1",
916    "02",  "12",  "22",  "32",  "42",  "52",  "62",  "72",
917    "82",  "92",  "A2",  "B2",  "C2",  "D2",  "E2",  "F2",
918    "03",  "13",  "23",  "33",  "43",  "53",  "63",  "73",
919    "83",  "93",  "A3",  "B3",  "C3",  "D3",  "E3",  "F3",
920    "04",  "14",  "24",  "34",  "44",  "54",  "64",  "74",
921    "84",  "94",  "A4",  "B4",  "C4",  "D4",  "E4",  "F4",
922    "05",  "15",  "25",  "35",  "45",  "55",  "65",  "75",
923    "85",  "95",  "A5",  "B5",  "C5",  "D5",  "E5",  "F5",
924    "06",  "16",  "26",  "36",  "46",  "56",  "66",  "76",
925    "86",  "96",  "A6",  "B6",  "C6",  "D6",  "E6",  "F6",
926    "07",  "17",  "27",  "37",  "47",  "57",  "67",  "77",
927    "87",  "97",  "A7",  "B7",  "C7",  "D7",  "E7",  "F7",
928    "08",  "18",  "28",  "38",  "48",  "58",  "68",  "78",
929    "88",  "98",  "A8",  "B8",  "C8",  "D8",  "E8",  "F8",
930    "09",  "19",  "29",  "39",  "49",  "59",  "69",  "79",
931    "89",  "99",  "A9",  "B9",  "C9",  "D9",  "E9",  "F9",
932    "0A",  "1A",  "2A",  "3A",  "4A",  "5A",  "6A",  "7A",
933    "8A",  "9A",  "AA",  "BA",  "CA",  "DA",  "EA",  "FA",
934    "0B",  "1B",  "2B",  "3B",  "4B",  "5B",  "6B",  "7B",
935    "8B",  "9B",  "AB",  "BB",  "CB",  "DB",  "EB",  "FB",
936    "0C",  "1C",  "2C",  "3C",  "4C",  "5C",  "6C",  "7C",
937    "8C",  "9C",  "AC",  "BC",  "CC",  "DC",  "EC",  "FC",
938    "0D",  "1D",  "2D",  "3D",  "4D",  "5D",  "6D",  "7D",
939    "8D",  "9D",  "AD",  "BD",  "CD",  "DD",  "ED",  "FD",
940    "0E",  "1E",  "2E",  "3E",  "4E",  "5E",  "6E",  "7E",
941    "8E",  "9E",  "AE",  "BE",  "CE",  "DE",  "EE",  "FE",
942    "0F",  "1F",  "2F",  "3F",  "4F",  "5F",  "6F",  "7F",
943    "8F",  "9F",  "AF",  "BF",  "CF",  "DF",  "EF",  "FF",
944   "001", "101", "201", "301", "401", "501", "601", "701",
945   "801", "901", "A01", "B01", "C01", "D01", "E01", "F01",
946   "011", "111", "211", "311", "411", "511", "611", "711",
947   "811", "911", "A11", "B11", "C11", "D11", "E11", "F11",
948   "021", "121", "221", "321", "421", "521", "621", "721",
949   "821", "921", "A21", "B21", "C21", "D21", "E21", "F21",
950   "031", "131", "231", "331", "431", "531", "631", "731",
951   "831", "931", "A31", "B31", "C31", "D31", "E31", "F31",
952   "041", "141", "241", "341", "441", "541", "641", "741",
953   "841", "941", "A41", "B41", "C41", "D41", "E41", "F41",
954   "051", "151", "251", "351", "451", "551", "651", "751",
955   "851", "951", "A51", "B51", "C51", "D51", "E51", "F51",
956   "061", "161", "261", "361", "461", "561", "661", "761",
957   "861", "961", "A61", "B61", "C61", "D61", "E61", "F61",
958   "071", "171", "271", "371", "471", "571", "671", "771",
959   "871", "971", "A71", "B71", "C71", "D71", "E71", "F71",
960   "081", "181", "281", "381", "481", "581", "681", "781",
961   "881", "981", "A81", "B81", "C81", "D81", "E81", "F81",
962   "091", "191", "291", "391", "491", "591", "691", "791",
963   "891", "991", "A91", "B91", "C91", "D91", "E91", "F91",
964   "0A1", "1A1", "2A1", "3A1", "4A1", "5A1", "6A1", "7A1",
965   "8A1", "9A1", "AA1", "BA1", "CA1", "DA1", "EA1", "FA1",
966   "0B1", "1B1", "2B1", "3B1", "4B1", "5B1", "6B1", "7B1",
967   "8B1", "9B1", "AB1", "BB1", "CB1", "DB1", "EB1", "FB1",
968   "0C1", "1C1", "2C1", "3C1", "4C1", "5C1", "6C1", "7C1",
969   "8C1", "9C1", "AC1", "BC1", "CC1", "DC1", "EC1", "FC1",
970   "0D1", "1D1", "2D1", "3D1", "4D1", "5D1", "6D1", "7D1",
971   "8D1", "9D1", "AD1", "BD1", "CD1", "DD1", "ED1", "FD1",
972   "0E1", "1E1", "2E1", "3E1", "4E1", "5E1", "6E1", "7E1",
973   "8E1", "9E1", "AE1", "BE1", "CE1", "DE1", "EE1", "FE1",
974   "0F1", "1F1", "2F1", "3F1", "4F1", "5F1", "6F1", "7F1",
975   "8F1", "9F1", "AF1", "BF1", "CF1", "DF1", "EF1", "FF1",
976   "002", "102", "202", "302", "402", "502", "602", "702",
977   "802", "902", "A02", "B02", "C02", "D02", "E02", "F02",
978   "012", "112", "212", "312", "412", "512", "612", "712",
979   "812", "912", "A12", "B12", "C12", "D12", "E12", "F12",
980   "022", "122", "222", "322", "422", "522", "622", "722",
981   "822", "922", "A22", "B22", "C22", "D22", "E22", "F22",
982   "032", "132", "232", "332", "432", "532", "632", "732",
983   "832", "932", "A32", "B32", "C32", "D32", "E32", "F32",
984   "042", "142", "242", "342", "442", "542", "642", "742",
985   "842", "942", "A42", "B42", "C42", "D42", "E42", "F42",
986   "052", "152", "252", "352", "452", "552", "652", "752",
987   "852", "952", "A52", "B52", "C52", "D52", "E52", "F52",
988   "062", "162", "262", "362", "462", "562", "662", "762",
989   "862", "962", "A62", "B62", "C62", "D62", "E62", "F62",
990   "072", "172", "272", "372", "472", "572", "672", "772",
991   "872", "972", "A72", "B72", "C72", "D72", "E72", "F72",
992   "082", "182", "282", "382", "482", "582", "682", "782",
993   "882", "982", "A82", "B82", "C82", "D82", "E82", "F82",
994   "092", "192", "292", "392", "492", "592", "692", "792",
995   "892", "992", "A92", "B92", "C92", "D92", "E92", "F92",
996   "0A2", "1A2", "2A2", "3A2", "4A2", "5A2", "6A2", "7A2",
997   "8A2", "9A2", "AA2", "BA2", "CA2", "DA2", "EA2", "FA2",
998   "0B2", "1B2", "2B2", "3B2", "4B2", "5B2", "6B2", "7B2",
999   "8B2", "9B2", "AB2", "BB2", "CB2", "DB2", "EB2", "FB2",
1000   "0C2", "1C2", "2C2", "3C2", "4C2", "5C2", "6C2", "7C2",
1001   "8C2", "9C2", "AC2", "BC2", "CC2", "DC2", "EC2", "FC2",
1002   "0D2", "1D2", "2D2", "3D2", "4D2", "5D2", "6D2", "7D2",
1003   "8D2", "9D2", "AD2", "BD2", "CD2", "DD2", "ED2", "FD2",
1004   "0E2", "1E2", "2E2", "3E2", "4E2", "5E2", "6E2", "7E2",
1005   "8E2", "9E2", "AE2", "BE2", "CE2", "DE2", "EE2", "FE2",
1006   "0F2", "1F2", "2F2", "3F2", "4F2", "5F2", "6F2", "7F2",
1007   "8F2", "9F2", "AF2", "BF2", "CF2", "DF2", "EF2", "FF2",
1008   "003", "103", "203", "303", "403", "503", "603", "703",
1009   "803", "903", "A03", "B03", "C03", "D03", "E03", "F03",
1010   "013", "113", "213", "313", "413", "513", "613", "713",
1011   "813", "913", "A13", "B13", "C13", "D13", "E13", "F13",
1012   "023", "123", "223", "323", "423", "523", "623", "723",
1013   "823", "923", "A23", "B23", "C23", "D23", "E23", "F23",
1014   "033", "133", "233", "333", "433", "533", "633", "733",
1015   "833", "933", "A33", "B33", "C33", "D33", "E33", "F33",
1016   "043", "143", "243", "343", "443", "543", "643", "743",
1017   "843", "943", "A43", "B43", "C43", "D43", "E43", "F43",
1018   "053", "153", "253", "353", "453", "553", "653", "753",
1019   "853", "953", "A53", "B53", "C53", "D53", "E53", "F53",
1020   "063", "163", "263", "363", "463", "563", "663", "763",
1021   "863", "963", "A63", "B63", "C63", "D63", "E63", "F63",
1022   "073", "173", "273", "373", "473", "573", "673", "773",
1023   "873", "973", "A73", "B73", "C73", "D73", "E73", "F73",
1024   "083", "183", "283", "383", "483", "583", "683", "783",
1025   "883", "983", "A83", "B83", "C83", "D83", "E83", "F83",
1026   "093", "193", "293", "393", "493", "593", "693", "793",
1027   "893", "993", "A93", "B93", "C93", "D93", "E93", "F93",
1028   "0A3", "1A3", "2A3", "3A3", "4A3", "5A3", "6A3", "7A3",
1029   "8A3", "9A3", "AA3", "BA3", "CA3", "DA3", "EA3", "FA3",
1030   "0B3", "1B3", "2B3", "3B3", "4B3", "5B3", "6B3", "7B3",
1031   "8B3", "9B3", "AB3", "BB3", "CB3", "DB3", "EB3", "FB3",
1032   "0C3", "1C3", "2C3", "3C3", "4C3", "5C3", "6C3", "7C3",
1033   "8C3", "9C3", "AC3", "BC3", "CC3", "DC3", "EC3", "FC3",
1034   "0D3", "1D3", "2D3", "3D3", "4D3", "5D3", "6D3", "7D3",
1035   "8D3", "9D3", "AD3", "BD3", "CD3", "DD3", "ED3", "FD3",
1036   "0E3", "1E3", "2E3", "3E3", "4E3", "5E3", "6E3", "7E3",
1037   "8E3", "9E3", "AE3", "BE3", "CE3", "DE3", "EE3", "FE3",
1038   "0F3", "1F3", "2F3", "3F3", "4F3", "5F3", "6F3", "7F3",
1039   "8F3", "9F3", "AF3", "BF3", "CF3", "DF3", "EF3", "FF3",
1040   "004", "104", "204", "304", "404", "504", "604", "704",
1041   "804", "904", "A04", "B04", "C04", "D04", "E04", "F04",
1042   "014", "114", "214", "314", "414", "514", "614", "714",
1043   "814", "914", "A14", "B14", "C14", "D14", "E14", "F14",
1044   "024", "124", "224", "324", "424", "524", "624", "724",
1045   "824", "924", "A24", "B24", "C24", "D24", "E24", "F24",
1046   "034", "134", "234", "334", "434", "534", "634", "734",
1047   "834", "934", "A34", "B34", "C34", "D34", "E34", "F34",
1048   "044", "144", "244", "344", "444", "544", "644", "744",
1049   "844", "944", "A44", "B44", "C44", "D44", "E44", "F44",
1050   "054", "154", "254", "354", "454", "554", "654", "754",
1051   "854", "954", "A54", "B54", "C54", "D54", "E54", "F54",
1052   "064", "164", "264", "364", "464", "564", "664", "764",
1053   "864", "964", "A64", "B64", "C64", "D64", "E64", "F64",
1054   "074", "174", "274", "374", "474", "574", "674", "774",
1055   "874", "974", "A74", "B74", "C74", "D74", "E74", "F74",
1056   "084", "184", "284", "384", "484", "584", "684", "784",
1057   "884", "984", "A84", "B84", "C84", "D84", "E84", "F84",
1058   "094", "194", "294", "394", "494", "594", "694", "794",
1059   "894", "994", "A94", "B94", "C94", "D94", "E94", "F94",
1060   "0A4", "1A4", "2A4", "3A4", "4A4", "5A4", "6A4", "7A4",
1061   "8A4", "9A4", "AA4", "BA4", "CA4", "DA4", "EA4", "FA4",
1062   "0B4", "1B4", "2B4", "3B4", "4B4", "5B4", "6B4", "7B4",
1063   "8B4", "9B4", "AB4", "BB4", "CB4", "DB4", "EB4", "FB4",
1064   "0C4", "1C4", "2C4", "3C4", "4C4", "5C4", "6C4", "7C4",
1065   "8C4", "9C4", "AC4", "BC4", "CC4", "DC4", "EC4", "FC4",
1066   "0D4", "1D4", "2D4", "3D4", "4D4", "5D4", "6D4", "7D4",
1067   "8D4", "9D4", "AD4", "BD4", "CD4", "DD4", "ED4", "FD4",
1068   "0E4", "1E4", "2E4", "3E4", "4E4", "5E4", "6E4", "7E4",
1069   "8E4", "9E4", "AE4", "BE4", "CE4", "DE4", "EE4", "FE4",
1070   "0F4", "1F4", "2F4", "3F4", "4F4", "5F4", "6F4", "7F4",
1071   "8F4", "9F4", "AF4", "BF4", "CF4", "DF4", "EF4", "FF4",
1072   "005", "105", "205", "305", "405", "505", "605", "705",
1073   "805", "905", "A05", "B05", "C05", "D05", "E05", "F05",
1074   "015", "115", "215", "315", "415", "515", "615", "715",
1075   "815", "915", "A15", "B15", "C15", "D15", "E15", "F15",
1076   "025", "125", "225", "325", "425", "525", "625", "725",
1077   "825", "925", "A25", "B25", "C25", "D25", "E25", "F25",
1078   "035", "135", "235", "335", "435", "535", "635", "735",
1079   "835", "935", "A35", "B35", "C35", "D35", "E35", "F35",
1080   "045", "145", "245", "345", "445", "545", "645", "745",
1081   "845", "945", "A45", "B45", "C45", "D45", "E45", "F45",
1082   "055", "155", "255", "355", "455", "555", "655", "755",
1083   "855", "955", "A55", "B55", "C55", "D55", "E55", "F55",
1084   "065", "165", "265", "365", "465", "565", "665", "765",
1085   "865", "965", "A65", "B65", "C65", "D65", "E65", "F65",
1086   "075", "175", "275", "375", "475", "575", "675", "775",
1087   "875", "975", "A75", "B75", "C75", "D75", "E75", "F75",
1088   "085", "185", "285", "385", "485", "585", "685", "785",
1089   "885", "985", "A85", "B85", "C85", "D85", "E85", "F85",
1090   "095", "195", "295", "395", "495", "595", "695", "795",
1091   "895", "995", "A95", "B95", "C95", "D95", "E95", "F95",
1092   "0A5", "1A5", "2A5", "3A5", "4A5", "5A5", "6A5", "7A5",
1093   "8A5", "9A5", "AA5", "BA5", "CA5", "DA5", "EA5", "FA5",
1094   "0B5", "1B5", "2B5", "3B5", "4B5", "5B5", "6B5", "7B5",
1095   "8B5", "9B5", "AB5", "BB5", "CB5", "DB5", "EB5", "FB5",
1096   "0C5", "1C5", "2C5", "3C5", "4C5", "5C5", "6C5", "7C5",
1097   "8C5", "9C5", "AC5", "BC5", "CC5", "DC5", "EC5", "FC5",
1098   "0D5", "1D5", "2D5", "3D5", "4D5", "5D5", "6D5", "7D5",
1099   "8D5", "9D5", "AD5", "BD5", "CD5", "DD5", "ED5", "FD5",
1100   "0E5", "1E5", "2E5", "3E5", "4E5", "5E5", "6E5", "7E5",
1101   "8E5", "9E5", "AE5", "BE5", "CE5", "DE5", "EE5", "FE5",
1102   "0F5", "1F5", "2F5", "3F5", "4F5", "5F5", "6F5", "7F5",
1103   "8F5", "9F5", "AF5", "BF5", "CF5", "DF5", "EF5", "FF5",
1104   "006", "106", "206", "306", "406", "506", "606", "706",
1105   "806", "906", "A06", "B06", "C06", "D06", "E06", "F06",
1106   "016", "116", "216", "316", "416", "516", "616", "716",
1107   "816", "916", "A16", "B16", "C16", "D16", "E16", "F16",
1108   "026", "126", "226", "326", "426", "526", "626", "726",
1109   "826", "926", "A26", "B26", "C26", "D26", "E26", "F26",
1110   "036", "136", "236", "336", "436", "536", "636", "736",
1111   "836", "936", "A36", "B36", "C36", "D36", "E36", "F36",
1112   "046", "146", "246", "346", "446", "546", "646", "746",
1113   "846", "946", "A46", "B46", "C46", "D46", "E46", "F46",
1114   "056", "156", "256", "356", "456", "556", "656", "756",
1115   "856", "956", "A56", "B56", "C56", "D56", "E56", "F56",
1116   "066", "166", "266", "366", "466", "566", "666", "766",
1117   "866", "966", "A66", "B66", "C66", "D66", "E66", "F66",
1118   "076", "176", "276", "376", "476", "576", "676", "776",
1119   "876", "976", "A76", "B76", "C76", "D76", "E76", "F76",
1120   "086", "186", "286", "386", "486", "586", "686", "786",
1121   "886", "986", "A86", "B86", "C86", "D86", "E86", "F86",
1122   "096", "196", "296", "396", "496", "596", "696", "796",
1123   "896", "996", "A96", "B96", "C96", "D96", "E96", "F96",
1124   "0A6", "1A6", "2A6", "3A6", "4A6", "5A6", "6A6", "7A6",
1125   "8A6", "9A6", "AA6", "BA6", "CA6", "DA6", "EA6", "FA6",
1126   "0B6", "1B6", "2B6", "3B6", "4B6", "5B6", "6B6", "7B6",
1127   "8B6", "9B6", "AB6", "BB6", "CB6", "DB6", "EB6", "FB6",
1128   "0C6", "1C6", "2C6", "3C6", "4C6", "5C6", "6C6", "7C6",
1129   "8C6", "9C6", "AC6", "BC6", "CC6", "DC6", "EC6", "FC6",
1130   "0D6", "1D6", "2D6", "3D6", "4D6", "5D6", "6D6", "7D6",
1131   "8D6", "9D6", "AD6", "BD6", "CD6", "DD6", "ED6", "FD6",
1132   "0E6", "1E6", "2E6", "3E6", "4E6", "5E6", "6E6", "7E6",
1133   "8E6", "9E6", "AE6", "BE6", "CE6", "DE6", "EE6", "FE6",
1134   "0F6", "1F6", "2F6", "3F6", "4F6", "5F6", "6F6", "7F6",
1135   "8F6", "9F6", "AF6", "BF6", "CF6", "DF6", "EF6", "FF6",
1136   "007", "107", "207", "307", "407", "507", "607", "707",
1137   "807", "907", "A07", "B07", "C07", "D07", "E07", "F07",
1138   "017", "117", "217", "317", "417", "517", "617", "717",
1139   "817", "917", "A17", "B17", "C17", "D17", "E17", "F17",
1140   "027", "127", "227", "327", "427", "527", "627", "727",
1141   "827", "927", "A27", "B27", "C27", "D27", "E27", "F27",
1142   "037", "137", "237", "337", "437", "537", "637", "737",
1143   "837", "937", "A37", "B37", "C37", "D37", "E37", "F37",
1144   "047", "147", "247", "347", "447", "547", "647", "747",
1145   "847", "947", "A47", "B47", "C47", "D47", "E47", "F47",
1146   "057", "157", "257", "357", "457", "557", "657", "757",
1147   "857", "957", "A57", "B57", "C57", "D57", "E57", "F57",
1148   "067", "167", "267", "367", "467", "567", "667", "767",
1149   "867", "967", "A67", "B67", "C67", "D67", "E67", "F67",
1150   "077", "177", "277", "377", "477", "577", "677", "777",
1151   "877", "977", "A77", "B77", "C77", "D77", "E77", "F77",
1152   "087", "187", "287", "387", "487", "587", "687", "787",
1153   "887", "987", "A87", "B87", "C87", "D87", "E87", "F87",
1154   "097", "197", "297", "397", "497", "597", "697", "797",
1155   "897", "997", "A97", "B97", "C97", "D97", "E97", "F97",
1156   "0A7", "1A7", "2A7", "3A7", "4A7", "5A7", "6A7", "7A7",
1157   "8A7", "9A7", "AA7", "BA7", "CA7", "DA7", "EA7", "FA7",
1158   "0B7", "1B7", "2B7", "3B7", "4B7", "5B7", "6B7", "7B7",
1159   "8B7", "9B7", "AB7", "BB7", "CB7", "DB7", "EB7", "FB7",
1160   "0C7", "1C7", "2C7", "3C7", "4C7", "5C7", "6C7", "7C7",
1161   "8C7", "9C7", "AC7", "BC7", "CC7", "DC7", "EC7", "FC7",
1162   "0D7", "1D7", "2D7", "3D7", "4D7", "5D7", "6D7", "7D7",
1163   "8D7", "9D7", "AD7", "BD7", "CD7", "DD7", "ED7", "FD7",
1164   "0E7", "1E7", "2E7", "3E7", "4E7", "5E7", "6E7", "7E7",
1165   "8E7", "9E7", "AE7", "BE7", "CE7", "DE7", "EE7", "FE7",
1166   "0F7", "1F7", "2F7", "3F7", "4F7", "5F7", "6F7", "7F7",
1167   "8F7", "9F7", "AF7", "BF7", "CF7", "DF7", "EF7", "FF7",
1168   "008", "108", "208", "308", "408", "508", "608", "708",
1169   "808", "908", "A08", "B08", "C08", "D08", "E08", "F08",
1170   "018", "118", "218", "318", "418", "518", "618", "718",
1171   "818", "918", "A18", "B18", "C18", "D18", "E18", "F18",
1172   "028", "128", "228", "328", "428", "528", "628", "728",
1173   "828", "928", "A28", "B28", "C28", "D28", "E28", "F28",
1174   "038", "138", "238", "338", "438", "538", "638", "738",
1175   "838", "938", "A38", "B38", "C38", "D38", "E38", "F38",
1176   "048", "148", "248", "348", "448", "548", "648", "748",
1177   "848", "948", "A48", "B48", "C48", "D48", "E48", "F48",
1178   "058", "158", "258", "358", "458", "558", "658", "758",
1179   "858", "958", "A58", "B58", "C58", "D58", "E58", "F58",
1180   "068", "168", "268", "368", "468", "568", "668", "768",
1181   "868", "968", "A68", "B68", "C68", "D68", "E68", "F68",
1182   "078", "178", "278", "378", "478", "578", "678", "778",
1183   "878", "978", "A78", "B78", "C78", "D78", "E78", "F78",
1184   "088", "188", "288", "388", "488", "588", "688", "788",
1185   "888", "988", "A88", "B88", "C88", "D88", "E88", "F88",
1186   "098", "198", "298", "398", "498", "598", "698", "798",
1187   "898", "998", "A98", "B98", "C98", "D98", "E98", "F98",
1188   "0A8", "1A8", "2A8", "3A8", "4A8", "5A8", "6A8", "7A8",
1189   "8A8", "9A8", "AA8", "BA8", "CA8", "DA8", "EA8", "FA8",
1190   "0B8", "1B8", "2B8", "3B8", "4B8", "5B8", "6B8", "7B8",
1191   "8B8", "9B8", "AB8", "BB8", "CB8", "DB8", "EB8", "FB8",
1192   "0C8", "1C8", "2C8", "3C8", "4C8", "5C8", "6C8", "7C8",
1193   "8C8", "9C8", "AC8", "BC8", "CC8", "DC8", "EC8", "FC8",
1194   "0D8", "1D8", "2D8", "3D8", "4D8", "5D8", "6D8", "7D8",
1195   "8D8", "9D8", "AD8", "BD8", "CD8", "DD8", "ED8", "FD8",
1196   "0E8", "1E8", "2E8", "3E8", "4E8", "5E8", "6E8", "7E8",
1197   "8E8", "9E8", "AE8", "BE8", "CE8", "DE8", "EE8", "FE8",
1198   "0F8", "1F8", "2F8", "3F8", "4F8", "5F8", "6F8", "7F8",
1199   "8F8", "9F8", "AF8", "BF8", "CF8", "DF8", "EF8", "FF8",
1200   "009", "109", "209", "309", "409", "509", "609", "709",
1201   "809", "909", "A09", "B09", "C09", "D09", "E09", "F09",
1202   "019", "119", "219", "319", "419", "519", "619", "719",
1203   "819", "919", "A19", "B19", "C19", "D19", "E19", "F19",
1204   "029", "129", "229", "329", "429", "529", "629", "729",
1205   "829", "929", "A29", "B29", "C29", "D29", "E29", "F29",
1206   "039", "139", "239", "339", "439", "539", "639", "739",
1207   "839", "939", "A39", "B39", "C39", "D39", "E39", "F39",
1208   "049", "149", "249", "349", "449", "549", "649", "749",
1209   "849", "949", "A49", "B49", "C49", "D49", "E49", "F49",
1210   "059", "159", "259", "359", "459", "559", "659", "759",
1211   "859", "959", "A59", "B59", "C59", "D59", "E59", "F59",
1212   "069", "169", "269", "369", "469", "569", "669", "769",
1213   "869", "969", "A69", "B69", "C69", "D69", "E69", "F69",
1214   "079", "179", "279", "379", "479", "579", "679", "779",
1215   "879", "979", "A79", "B79", "C79", "D79", "E79", "F79",
1216   "089", "189", "289", "389", "489", "589", "689", "789",
1217   "889", "989", "A89", "B89", "C89", "D89", "E89", "F89",
1218   "099", "199", "299", "399", "499", "599", "699", "799",
1219   "899", "999", "A99", "B99", "C99", "D99", "E99", "F99",
1220   "0A9", "1A9", "2A9", "3A9", "4A9", "5A9", "6A9", "7A9",
1221   "8A9", "9A9", "AA9", "BA9", "CA9", "DA9", "EA9", "FA9",
1222   "0B9", "1B9", "2B9", "3B9", "4B9", "5B9", "6B9", "7B9",
1223   "8B9", "9B9", "AB9", "BB9", "CB9", "DB9", "EB9", "FB9",
1224   "0C9", "1C9", "2C9", "3C9", "4C9", "5C9", "6C9", "7C9",
1225   "8C9", "9C9", "AC9", "BC9", "CC9", "DC9", "EC9", "FC9",
1226   "0D9", "1D9", "2D9", "3D9", "4D9", "5D9", "6D9", "7D9",
1227   "8D9", "9D9", "AD9", "BD9", "CD9", "DD9", "ED9", "FD9",
1228   "0E9", "1E9", "2E9", "3E9", "4E9", "5E9", "6E9", "7E9",
1229   "8E9", "9E9", "AE9", "BE9", "CE9", "DE9", "EE9", "FE9",
1230   "0F9", "1F9", "2F9", "3F9", "4F9", "5F9", "6F9", "7F9",
1231   "8F9", "9F9", "AF9", "BF9", "CF9", "DF9", "EF9", "FF9",
1232   "00A", "10A", "20A", "30A", "40A", "50A", "60A", "70A",
1233   "80A", "90A", "A0A", "B0A", "C0A", "D0A", "E0A", "F0A",
1234   "01A", "11A", "21A", "31A", "41A", "51A", "61A", "71A",
1235   "81A", "91A", "A1A", "B1A", "C1A", "D1A", "E1A", "F1A",
1236   "02A", "12A", "22A", "32A", "42A", "52A", "62A", "72A",
1237   "82A", "92A", "A2A", "B2A", "C2A", "D2A", "E2A", "F2A",
1238   "03A", "13A", "23A", "33A", "43A", "53A", "63A", "73A",
1239   "83A", "93A", "A3A", "B3A", "C3A", "D3A", "E3A", "F3A",
1240   "04A", "14A", "24A", "34A", "44A", "54A", "64A", "74A",
1241   "84A", "94A", "A4A", "B4A", "C4A", "D4A", "E4A", "F4A",
1242   "05A", "15A", "25A", "35A", "45A", "55A", "65A", "75A",
1243   "85A", "95A", "A5A", "B5A", "C5A", "D5A", "E5A", "F5A",
1244   "06A", "16A", "26A", "36A", "46A", "56A", "66A", "76A",
1245   "86A", "96A", "A6A", "B6A", "C6A", "D6A", "E6A", "F6A",
1246   "07A", "17A", "27A", "37A", "47A", "57A", "67A", "77A",
1247   "87A", "97A", "A7A", "B7A", "C7A", "D7A", "E7A", "F7A",
1248   "08A", "18A", "28A", "38A", "48A", "58A", "68A", "78A",
1249   "88A", "98A", "A8A", "B8A", "C8A", "D8A", "E8A", "F8A",
1250   "09A", "19A", "29A", "39A", "49A", "59A", "69A", "79A",
1251   "89A", "99A", "A9A", "B9A", "C9A", "D9A", "E9A", "F9A",
1252   "0AA", "1AA", "2AA", "3AA", "4AA", "5AA", "6AA", "7AA",
1253   "8AA", "9AA", "AAA", "BAA", "CAA", "DAA", "EAA", "FAA",
1254   "0BA", "1BA", "2BA", "3BA", "4BA", "5BA", "6BA", "7BA",
1255   "8BA", "9BA", "ABA", "BBA", "CBA", "DBA", "EBA", "FBA",
1256   "0CA", "1CA", "2CA", "3CA", "4CA", "5CA", "6CA", "7CA",
1257   "8CA", "9CA", "ACA", "BCA", "CCA", "DCA", "ECA", "FCA",
1258   "0DA", "1DA", "2DA", "3DA", "4DA", "5DA", "6DA", "7DA",
1259   "8DA", "9DA", "ADA", "BDA", "CDA", "DDA", "EDA", "FDA",
1260   "0EA", "1EA", "2EA", "3EA", "4EA", "5EA", "6EA", "7EA",
1261   "8EA", "9EA", "AEA", "BEA", "CEA", "DEA", "EEA", "FEA",
1262   "0FA", "1FA", "2FA", "3FA", "4FA", "5FA", "6FA", "7FA",
1263   "8FA", "9FA", "AFA", "BFA", "CFA", "DFA", "EFA", "FFA",
1264   "00B", "10B", "20B", "30B", "40B", "50B", "60B", "70B",
1265   "80B", "90B", "A0B", "B0B", "C0B", "D0B", "E0B", "F0B",
1266   "01B", "11B", "21B", "31B", "41B", "51B", "61B", "71B",
1267   "81B", "91B", "A1B", "B1B", "C1B", "D1B", "E1B", "F1B",
1268   "02B", "12B", "22B", "32B", "42B", "52B", "62B", "72B",
1269   "82B", "92B", "A2B", "B2B", "C2B", "D2B", "E2B", "F2B",
1270   "03B", "13B", "23B", "33B", "43B", "53B", "63B", "73B",
1271   "83B", "93B", "A3B", "B3B", "C3B", "D3B", "E3B", "F3B",
1272   "04B", "14B", "24B", "34B", "44B", "54B", "64B", "74B",
1273   "84B", "94B", "A4B", "B4B", "C4B", "D4B", "E4B", "F4B",
1274   "05B", "15B", "25B", "35B", "45B", "55B", "65B", "75B",
1275   "85B", "95B", "A5B", "B5B", "C5B", "D5B", "E5B", "F5B",
1276   "06B", "16B", "26B", "36B", "46B", "56B", "66B", "76B",
1277   "86B", "96B", "A6B", "B6B", "C6B", "D6B", "E6B", "F6B",
1278   "07B", "17B", "27B", "37B", "47B", "57B", "67B", "77B",
1279   "87B", "97B", "A7B", "B7B", "C7B", "D7B", "E7B", "F7B",
1280   "08B", "18B", "28B", "38B", "48B", "58B", "68B", "78B",
1281   "88B", "98B", "A8B", "B8B", "C8B", "D8B", "E8B", "F8B",
1282   "09B", "19B", "29B", "39B", "49B", "59B", "69B", "79B",
1283   "89B", "99B", "A9B", "B9B", "C9B", "D9B", "E9B", "F9B",
1284   "0AB", "1AB", "2AB", "3AB", "4AB", "5AB", "6AB", "7AB",
1285   "8AB", "9AB", "AAB", "BAB", "CAB", "DAB", "EAB", "FAB",
1286   "0BB", "1BB", "2BB", "3BB", "4BB", "5BB", "6BB", "7BB",
1287   "8BB", "9BB", "ABB", "BBB", "CBB", "DBB", "EBB", "FBB",
1288   "0CB", "1CB", "2CB", "3CB", "4CB", "5CB", "6CB", "7CB",
1289   "8CB", "9CB", "ACB", "BCB", "CCB", "DCB", "ECB", "FCB",
1290   "0DB", "1DB", "2DB", "3DB", "4DB", "5DB", "6DB", "7DB",
1291   "8DB", "9DB", "ADB", "BDB", "CDB", "DDB", "EDB", "FDB",
1292   "0EB", "1EB", "2EB", "3EB", "4EB", "5EB", "6EB", "7EB",
1293   "8EB", "9EB", "AEB", "BEB", "CEB", "DEB", "EEB", "FEB",
1294   "0FB", "1FB", "2FB", "3FB", "4FB", "5FB", "6FB", "7FB",
1295   "8FB", "9FB", "AFB", "BFB", "CFB", "DFB", "EFB", "FFB",
1296   "00C", "10C", "20C", "30C", "40C", "50C", "60C", "70C",
1297   "80C", "90C", "A0C", "B0C", "C0C", "D0C", "E0C", "F0C",
1298   "01C", "11C", "21C", "31C", "41C", "51C", "61C", "71C",
1299   "81C", "91C", "A1C", "B1C", "C1C", "D1C", "E1C", "F1C",
1300   "02C", "12C", "22C", "32C", "42C", "52C", "62C", "72C",
1301   "82C", "92C", "A2C", "B2C", "C2C", "D2C", "E2C", "F2C",
1302   "03C", "13C", "23C", "33C", "43C", "53C", "63C", "73C",
1303   "83C", "93C", "A3C", "B3C", "C3C", "D3C", "E3C", "F3C",
1304   "04C", "14C", "24C", "34C", "44C", "54C", "64C", "74C",
1305   "84C", "94C", "A4C", "B4C", "C4C", "D4C", "E4C", "F4C",
1306   "05C", "15C", "25C", "35C", "45C", "55C", "65C", "75C",
1307   "85C", "95C", "A5C", "B5C", "C5C", "D5C", "E5C", "F5C",
1308   "06C", "16C", "26C", "36C", "46C", "56C", "66C", "76C",
1309   "86C", "96C", "A6C", "B6C", "C6C", "D6C", "E6C", "F6C",
1310   "07C", "17C", "27C", "37C", "47C", "57C", "67C", "77C",
1311   "87C", "97C", "A7C", "B7C", "C7C", "D7C", "E7C", "F7C",
1312   "08C", "18C", "28C", "38C", "48C", "58C", "68C", "78C",
1313   "88C", "98C", "A8C", "B8C", "C8C", "D8C", "E8C", "F8C",
1314   "09C", "19C", "29C", "39C", "49C", "59C", "69C", "79C",
1315   "89C", "99C", "A9C", "B9C", "C9C", "D9C", "E9C", "F9C",
1316   "0AC", "1AC", "2AC", "3AC", "4AC", "5AC", "6AC", "7AC",
1317   "8AC", "9AC", "AAC", "BAC", "CAC", "DAC", "EAC", "FAC",
1318   "0BC", "1BC", "2BC", "3BC", "4BC", "5BC", "6BC", "7BC",
1319   "8BC", "9BC", "ABC", "BBC", "CBC", "DBC", "EBC", "FBC",
1320   "0CC", "1CC", "2CC", "3CC", "4CC", "5CC", "6CC", "7CC",
1321   "8CC", "9CC", "ACC", "BCC", "CCC", "DCC", "ECC", "FCC",
1322   "0DC", "1DC", "2DC", "3DC", "4DC", "5DC", "6DC", "7DC",
1323   "8DC", "9DC", "ADC", "BDC", "CDC", "DDC", "EDC", "FDC",
1324   "0EC", "1EC", "2EC", "3EC", "4EC", "5EC", "6EC", "7EC",
1325   "8EC", "9EC", "AEC", "BEC", "CEC", "DEC", "EEC", "FEC",
1326   "0FC", "1FC", "2FC", "3FC", "4FC", "5FC", "6FC", "7FC",
1327   "8FC", "9FC", "AFC", "BFC", "CFC", "DFC", "EFC", "FFC",
1328   "00D", "10D", "20D", "30D", "40D", "50D", "60D", "70D",
1329   "80D", "90D", "A0D", "B0D", "C0D", "D0D", "E0D", "F0D",
1330   "01D", "11D", "21D", "31D", "41D", "51D", "61D", "71D",
1331   "81D", "91D", "A1D", "B1D", "C1D", "D1D", "E1D", "F1D",
1332   "02D", "12D", "22D", "32D", "42D", "52D", "62D", "72D",
1333   "82D", "92D", "A2D", "B2D", "C2D", "D2D", "E2D", "F2D",
1334   "03D", "13D", "23D", "33D", "43D", "53D", "63D", "73D",
1335   "83D", "93D", "A3D", "B3D", "C3D", "D3D", "E3D", "F3D",
1336   "04D", "14D", "24D", "34D", "44D", "54D", "64D", "74D",
1337   "84D", "94D", "A4D", "B4D", "C4D", "D4D", "E4D", "F4D",
1338   "05D", "15D", "25D", "35D", "45D", "55D", "65D", "75D",
1339   "85D", "95D", "A5D", "B5D", "C5D", "D5D", "E5D", "F5D",
1340   "06D", "16D", "26D", "36D", "46D", "56D", "66D", "76D",
1341   "86D", "96D", "A6D", "B6D", "C6D", "D6D", "E6D", "F6D",
1342   "07D", "17D", "27D", "37D", "47D", "57D", "67D", "77D",
1343   "87D", "97D", "A7D", "B7D", "C7D", "D7D", "E7D", "F7D",
1344   "08D", "18D", "28D", "38D", "48D", "58D", "68D", "78D",
1345   "88D", "98D", "A8D", "B8D", "C8D", "D8D", "E8D", "F8D",
1346   "09D", "19D", "29D", "39D", "49D", "59D", "69D", "79D",
1347   "89D", "99D", "A9D", "B9D", "C9D", "D9D", "E9D", "F9D",
1348   "0AD", "1AD", "2AD", "3AD", "4AD", "5AD", "6AD", "7AD",
1349   "8AD", "9AD", "AAD", "BAD", "CAD", "DAD", "EAD", "FAD",
1350   "0BD", "1BD", "2BD", "3BD", "4BD", "5BD", "6BD", "7BD",
1351   "8BD", "9BD", "ABD", "BBD", "CBD", "DBD", "EBD", "FBD",
1352   "0CD", "1CD", "2CD", "3CD", "4CD", "5CD", "6CD", "7CD",
1353   "8CD", "9CD", "ACD", "BCD", "CCD", "DCD", "ECD", "FCD",
1354   "0DD", "1DD", "2DD", "3DD", "4DD", "5DD", "6DD", "7DD",
1355   "8DD", "9DD", "ADD", "BDD", "CDD", "DDD", "EDD", "FDD",
1356   "0ED", "1ED", "2ED", "3ED", "4ED", "5ED", "6ED", "7ED",
1357   "8ED", "9ED", "AED", "BED", "CED", "DED", "EED", "FED",
1358   "0FD", "1FD", "2FD", "3FD", "4FD", "5FD", "6FD", "7FD",
1359   "8FD", "9FD", "AFD", "BFD", "CFD", "DFD", "EFD", "FFD",
1360   "00E", "10E", "20E", "30E", "40E", "50E", "60E", "70E",
1361   "80E", "90E", "A0E", "B0E", "C0E", "D0E", "E0E", "F0E",
1362   "01E", "11E", "21E", "31E", "41E", "51E", "61E", "71E",
1363   "81E", "91E", "A1E", "B1E", "C1E", "D1E", "E1E", "F1E",
1364   "02E", "12E", "22E", "32E", "42E", "52E", "62E", "72E",
1365   "82E", "92E", "A2E", "B2E", "C2E", "D2E", "E2E", "F2E",
1366   "03E", "13E", "23E", "33E", "43E", "53E", "63E", "73E",
1367   "83E", "93E", "A3E", "B3E", "C3E", "D3E", "E3E", "F3E",
1368   "04E", "14E", "24E", "34E", "44E", "54E", "64E", "74E",
1369   "84E", "94E", "A4E", "B4E", "C4E", "D4E", "E4E", "F4E",
1370   "05E", "15E", "25E", "35E", "45E", "55E", "65E", "75E",
1371   "85E", "95E", "A5E", "B5E", "C5E", "D5E", "E5E", "F5E",
1372   "06E", "16E", "26E", "36E", "46E", "56E", "66E", "76E",
1373   "86E", "96E", "A6E", "B6E", "C6E", "D6E", "E6E", "F6E",
1374   "07E", "17E", "27E", "37E", "47E", "57E", "67E", "77E",
1375   "87E", "97E", "A7E", "B7E", "C7E", "D7E", "E7E", "F7E",
1376   "08E", "18E", "28E", "38E", "48E", "58E", "68E", "78E",
1377   "88E", "98E", "A8E", "B8E", "C8E", "D8E", "E8E", "F8E",
1378   "09E", "19E", "29E", "39E", "49E", "59E", "69E", "79E",
1379   "89E", "99E", "A9E", "B9E", "C9E", "D9E", "E9E", "F9E",
1380   "0AE", "1AE", "2AE", "3AE", "4AE", "5AE", "6AE", "7AE",
1381   "8AE", "9AE", "AAE", "BAE", "CAE", "DAE", "EAE", "FAE",
1382   "0BE", "1BE", "2BE", "3BE", "4BE", "5BE", "6BE", "7BE",
1383   "8BE", "9BE", "ABE", "BBE", "CBE", "DBE", "EBE", "FBE",
1384   "0CE", "1CE", "2CE", "3CE", "4CE", "5CE", "6CE", "7CE",
1385   "8CE", "9CE", "ACE", "BCE", "CCE", "DCE", "ECE", "FCE",
1386   "0DE", "1DE", "2DE", "3DE", "4DE", "5DE", "6DE", "7DE",
1387   "8DE", "9DE", "ADE", "BDE", "CDE", "DDE", "EDE", "FDE",
1388   "0EE", "1EE", "2EE", "3EE", "4EE", "5EE", "6EE", "7EE",
1389   "8EE", "9EE", "AEE", "BEE", "CEE", "DEE", "EEE", "FEE",
1390   "0FE", "1FE", "2FE", "3FE", "4FE", "5FE", "6FE", "7FE",
1391   "8FE", "9FE", "AFE", "BFE", "CFE", "DFE", "EFE", "FFE",
1392   "00F", "10F", "20F", "30F", "40F", "50F", "60F", "70F",
1393   "80F", "90F", "A0F", "B0F", "C0F", "D0F", "E0F", "F0F",
1394   "01F", "11F", "21F", "31F", "41F", "51F", "61F", "71F",
1395   "81F", "91F", "A1F", "B1F", "C1F", "D1F", "E1F", "F1F",
1396   "02F", "12F", "22F", "32F", "42F", "52F", "62F", "72F",
1397   "82F", "92F", "A2F", "B2F", "C2F", "D2F", "E2F", "F2F",
1398   "03F", "13F", "23F", "33F", "43F", "53F", "63F", "73F",
1399   "83F", "93F", "A3F", "B3F", "C3F", "D3F", "E3F", "F3F",
1400   "04F", "14F", "24F", "34F", "44F", "54F", "64F", "74F",
1401   "84F", "94F", "A4F", "B4F", "C4F", "D4F", "E4F", "F4F",
1402   "05F", "15F", "25F", "35F", "45F", "55F", "65F", "75F",
1403   "85F", "95F", "A5F", "B5F", "C5F", "D5F", "E5F", "F5F",
1404   "06F", "16F", "26F", "36F", "46F", "56F", "66F", "76F",
1405   "86F", "96F", "A6F", "B6F", "C6F", "D6F", "E6F", "F6F",
1406   "07F", "17F", "27F", "37F", "47F", "57F", "67F", "77F",
1407   "87F", "97F", "A7F", "B7F", "C7F", "D7F", "E7F", "F7F",
1408   "08F", "18F", "28F", "38F", "48F", "58F", "68F", "78F",
1409   "88F", "98F", "A8F", "B8F", "C8F", "D8F", "E8F", "F8F",
1410   "09F", "19F", "29F", "39F", "49F", "59F", "69F", "79F",
1411   "89F", "99F", "A9F", "B9F", "C9F", "D9F", "E9F", "F9F",
1412   "0AF", "1AF", "2AF", "3AF", "4AF", "5AF", "6AF", "7AF",
1413   "8AF", "9AF", "AAF", "BAF", "CAF", "DAF", "EAF", "FAF",
1414   "0BF", "1BF", "2BF", "3BF", "4BF", "5BF", "6BF", "7BF",
1415   "8BF", "9BF", "ABF", "BBF", "CBF", "DBF", "EBF", "FBF",
1416   "0CF", "1CF", "2CF", "3CF", "4CF", "5CF", "6CF", "7CF",
1417   "8CF", "9CF", "ACF", "BCF", "CCF", "DCF", "ECF", "FCF",
1418   "0DF", "1DF", "2DF", "3DF", "4DF", "5DF", "6DF", "7DF",
1419   "8DF", "9DF", "ADF", "BDF", "CDF", "DDF", "EDF", "FDF",
1420   "0EF", "1EF", "2EF", "3EF", "4EF", "5EF", "6EF", "7EF",
1421   "8EF", "9EF", "AEF", "BEF", "CEF", "DEF", "EEF", "FEF",
1422   "0FF", "1FF", "2FF", "3FF", "4FF", "5FF", "6FF", "7FF",
1423   "8FF", "9FF", "AFF", "BFF", "CFF", "DFF", "EFF", "FFF"
1424 };
1425 
1426 /** Append a single character to an output buffer.
1427  * @param[in,out] buf_p Buffer to append to.
1428  * @param[in] c Character to append.
1429  */
1430 static void
addc(struct BufData * buf_p,int c)1431 addc(struct BufData *buf_p, int c)
1432 {
1433   int overflow = 0;
1434 
1435   if (buf_p->limit == 0) { /* We've gone past the limit... */
1436     buf_p->overflow++;
1437     overflow++;
1438   } else if (buf_p->limit > 0) /* update the limit */
1439     buf_p->limit--;
1440 
1441   if (buf_p->buf_loc >= buf_p->buf_size) { /* We've gone past buffer */
1442     buf_p->buf_overflow++;
1443     overflow++;
1444   }
1445 
1446   if (!overflow) /* add the character to the buffer */
1447     buf_p->buf[buf_p->buf_loc++] = c;
1448 }
1449 
1450 /** Append a string to an output buffer.
1451  * @param[in,out] buf_p Buffer to append to.
1452  * @param[in] s_len Length of string to append.
1453  * @param[in] s String to append.
1454  */
1455 static void
adds(struct BufData * buf_p,int s_len,const char * s)1456 adds(struct BufData *buf_p, int s_len, const char *s)
1457 {
1458   int overflow = 0;
1459 
1460   /* while the string exists and has non-zero length */
1461   while (s_len && *s)
1462   {
1463     /* poor man's inlining; see addc(), above */
1464     if (buf_p->limit == 0) { /* We've gone past the limit... */
1465       buf_p->overflow++;
1466       overflow++;
1467     } else if (buf_p->limit > 0) /* update the limit */
1468       buf_p->limit--;
1469 
1470     if (buf_p->buf_loc >= buf_p->buf_size) { /* We've gone past buffer */
1471       buf_p->buf_overflow++;
1472       overflow++;
1473     }
1474 
1475     if (!overflow) /* add the character to the buffer */
1476       buf_p->buf[buf_p->buf_loc++] = *s;
1477 
1478     s++; /* advance to next character */
1479     if (s_len > 0) /* update string length left to copy */
1480       s_len--;
1481   }
1482 }
1483 
1484 /** Add certain padding to an output buffer.
1485  * @param[in,out] buf_p Buffer to append to.
1486  * @param[in] padlen Length of padding to add.
1487  * @param[in] pad Padding string (at least PAD_LENGTH bytes long).
1488  */
1489 static void
do_pad(struct BufData * buf_p,int padlen,char * pad)1490 do_pad(struct BufData *buf_p, int padlen, char *pad)
1491 {
1492   /* do chunks of PAD_LENGTH first */
1493   for (; padlen > PAD_LENGTH; padlen -= PAD_LENGTH)
1494     adds(buf_p, PAD_LENGTH, pad);
1495 
1496   /* add any left-over padding */
1497   adds(buf_p, padlen, pad);
1498 }
1499 
1500 /** Return length of string, up to a maximum.
1501  * @param[in] str String to find length for.
1502  * @param[in] maxlen Maximum value to return.
1503  * @return Minimum of \a maxlen and length of \a str.
1504  */
1505 static int
my_strnlen(const char * str,int maxlen)1506 my_strnlen(const char *str, int maxlen)
1507 {
1508   int len = 0;
1509 
1510   while (*str++ && maxlen--)
1511     len++;
1512 
1513   return len;
1514 }
1515 
1516 /** Workhorse printing function.
1517  * @param[in] dest Client to format the message.
1518  * @param[in,out] buf_p Description of output buffer.
1519  * @param[in] fmt Message format string.
1520  * @param[in] vp Variable-length argument list for format string.
1521  */
1522 static void
doprintf(struct Client * dest,struct BufData * buf_p,const char * fmt,va_list vp)1523 doprintf(struct Client *dest, struct BufData *buf_p, const char *fmt,
1524 	 va_list vp)
1525 {
1526   enum {
1527     FLAG,	/* Gathering flags */
1528     WIDTH,	/* Gathering field width */
1529     DOT,	/* Found a dot */
1530     PREC,	/* Gathering field precision */
1531     OPT,	/* Gathering field options (l, h, q, etc.) */
1532     SPEC	/* Looking for field specifier */
1533   } state = FLAG;
1534   struct FieldData fld_s = FIELDDATA_INIT;
1535   const char *fstart = 0;
1536 
1537   for (; *fmt; fmt++) {
1538     /* If it's not %, or if it's %%, append it to the string */
1539     if (*fmt != '%' || (*fmt == '%' && *++fmt == '%')) {
1540       addc(buf_p, *fmt); /* add the character to the string */
1541 
1542       continue; /* go to the next character */
1543     }
1544 
1545     state = FLAG; /* initialize our field data */
1546     fld_s.flags = 0;
1547     fld_s.base = BASE_DECIMAL;
1548     fld_s.width = 0;
1549     fld_s.prec = -1;
1550     fstart = fmt;
1551 
1552     for (; *fmt; fmt++) {
1553       switch (*fmt) {
1554       case '-': /* Deal with a minus flag */
1555 	if (state == FLAG)
1556 	  fld_s.flags |= FLAG_MINUS;
1557 	else if (state == PREC) { /* precisions may not be negative */
1558 	  fld_s.prec = -1;
1559 	  state = OPT; /* prohibit further precision wrangling */
1560 	}
1561 	continue;
1562 
1563       case '+': /* Deal with a plus flag */
1564 	if (state == FLAG)
1565 	  fld_s.flags |= FLAG_PLUS;
1566 	continue;
1567 
1568       case ' ': /* Deal with a space flag */
1569 	if (state == FLAG)
1570 	  fld_s.flags |= FLAG_SPACE;
1571 	continue;
1572 
1573       case '#': /* Deal with the so-called "alternate" flag */
1574 	if (state == FLAG)
1575 	  fld_s.flags |= FLAG_ALT;
1576 	continue;
1577 
1578       case ':': /* Deal with the colon flag */
1579 	if (state == FLAG)
1580 	  fld_s.flags |= FLAG_COLON;
1581 	continue;
1582 
1583       case '0': /* Deal with a zero flag */
1584 	if (state == FLAG) {
1585 	  fld_s.flags |= FLAG_ZERO;
1586 	  continue;
1587 	}
1588 	/*FALLTHROUGH*/
1589       case '1':  case '2':  case '3':  case '4':  case '5':
1590       case '6':  case '7':  case '8':  case '9':
1591 	if (state == FLAG) /* switch to the WIDTH state if needed? */
1592 	  state = WIDTH;
1593 	else if (state != WIDTH && state != PREC)
1594 	  continue; /* don't process it any more */
1595 
1596 	/* convert number */
1597 	if (state == WIDTH) {
1598 	  if (fld_s.width < WIDTH_MAX) /* prevent overflow */
1599 	    fld_s.width = fld_s.width * 10 + (*fmt - '0');
1600 	} else {
1601 	  if (fld_s.prec < WIDTH_MAX) /* prevent overflow */
1602 	    fld_s.prec = fld_s.prec * 10 + (*fmt - '0');
1603 	}
1604 	continue;
1605 
1606       case '.': /* We found a '.'; go to precision state */
1607 	if (state <= DOT) {
1608 	  state = PREC;
1609 	  fld_s.prec = 0;
1610 	}
1611 	continue;
1612 
1613       case '*': /* Grab an argument containing a width or precision */
1614 	if (state <= WIDTH && fld_s.width <= 0) {
1615 	  fld_s.width = (short)va_arg(vp, int); /* Get argument */
1616 
1617 	  state = DOT; /* '.' better be next */
1618 
1619 	  if (fld_s.width < 0) { /* deal with negative width */
1620 	    fld_s.flags |= FLAG_MINUS;
1621 	    fld_s.width = -fld_s.width;
1622 	  }
1623 	} else if (state == PREC && fld_s.prec <= 0) {
1624 	  fld_s.prec = (short)va_arg(vp, int); /* Get argument */
1625 
1626 	  state = OPT; /* No more precision stuff */
1627 
1628 	  if (fld_s.prec < 0) /* deal with negative precision */
1629 	    fld_s.prec = -1;
1630 	}
1631 	continue;
1632 
1633       case 'h': /* it's a short */
1634 	if (state <= OPT) {
1635 	  state = OPT;
1636 	  if (fld_s.flags & TYPE_SHORT) /* We support 'hh' */
1637 	    fld_s.flags |= TYPE_CHAR;
1638 	  else if (!(fld_s.flags & TYPE_MASK))
1639 	    fld_s.flags |= TYPE_SHORT;
1640 	}
1641 	continue;
1642 
1643       case 'l': /* it's a long */
1644 	if (state <= OPT) {
1645 	  state = OPT;
1646 	  if (fld_s.flags & TYPE_LONG) /* We support 'll' */
1647 	    fld_s.flags |= TYPE_QUAD | TYPE_LONGDOUBLE;
1648 	  else if (!(fld_s.flags & TYPE_MASK))
1649 	    fld_s.flags |= TYPE_LONG;
1650 	}
1651 	continue;
1652 
1653       case 'q':  case 'L': /* it's a quad or long double */
1654 	if (state <= OPT) {
1655 	  state = OPT;
1656 	  if (!(fld_s.flags & TYPE_MASK))
1657 	    fld_s.flags |= TYPE_QUAD | TYPE_LONGDOUBLE;
1658 	}
1659 	continue;
1660 
1661       case 'j': /* it's an intmax_t */
1662 	if (state <= OPT) {
1663 	  state = OPT;
1664 	  if (!(fld_s.flags & TYPE_MASK))
1665 	    fld_s.flags |= TYPE_INTMAX;
1666 	}
1667 	continue;
1668 
1669       case 't': /* it's a ptrdiff_t */
1670 	if (state <= OPT) {
1671 	  state = OPT;
1672 	  if (!(fld_s.flags & TYPE_MASK))
1673 	    fld_s.flags |= TYPE_PTRDIFF;
1674 	}
1675 	continue;
1676 
1677       case 'z':  case 'Z': /* it's a size_t */
1678 	if (state <= OPT) {
1679 	  state = OPT;
1680 	  if (!(fld_s.flags & TYPE_MASK))
1681 	    fld_s.flags |= TYPE_SIZE;
1682 	}
1683 	continue;
1684 
1685       case 'T': /* it's a time_t */
1686 	if (state <= OPT) {
1687 	  state = OPT;
1688 	  if (!(fld_s.flags & TYPE_MASK))
1689 	    fld_s.flags |= TYPE_TIME;
1690 	}
1691 	continue;
1692 
1693       case 's': /* convert a string */
1694 	fld_s.flags &= ~(FLAG_PLUS | FLAG_SPACE | FLAG_ALT | FLAG_ZERO |
1695 			 FLAG_COLON | TYPE_MASK);
1696 	fld_s.flags |= ARG_PTR | CONV_STRING;
1697 	break;
1698 
1699       case 'd':  case 'i':
1700 	fld_s.flags &= ~(FLAG_COLON);
1701 	fld_s.flags |= ARG_INT | CONV_INT;
1702 	break;
1703 
1704       case 'X': /* uppercase hexadecimal */
1705 	fld_s.flags |= INFO_UPPERCASE;
1706 	/*FALLTHROUGH*/
1707       case 'o':  case 'x': /* octal or hexadecimal */
1708 	if (*fmt == 'o')
1709 	  fld_s.base = BASE_OCTAL;
1710 	else
1711 	  fld_s.base = BASE_HEX;
1712 	/*FALLTHROUGH*/
1713       case 'u': /* Unsigned int */
1714 	fld_s.flags &= ~(FLAG_PLUS | FLAG_SPACE | FLAG_COLON);
1715 	fld_s.flags |= INFO_UNSIGNED | ARG_INT | CONV_INT;
1716 	break;
1717 
1718 	/* Don't support floating point at this time; it's too complicated */
1719 /*        case 'E':  case 'G':  case 'A': */
1720 /*  	fld_s.flags |= INFO_UPPERCASE; */
1721 	/*FALLTHROUGH*/
1722 /*        case 'e':  case 'f':  case 'g':  case 'a': */
1723 /*  	fld_s.flags |= ARG_FLOAT | CONV_FLOAT; */
1724 /*  	break; */
1725 
1726       case 'c': /* character */
1727 	fld_s.flags &= ~(FLAG_PLUS | FLAG_SPACE | FLAG_ALT | FLAG_ZERO |
1728 			 FLAG_COLON | TYPE_MASK);
1729 	fld_s.flags |= INFO_UNSIGNED | ARG_INT | TYPE_CHAR | CONV_CHAR;
1730 	fld_s.prec = -1;
1731 	break;
1732 
1733       case 'p': /* display a pointer */
1734 	fld_s.flags &= ~(FLAG_PLUS | FLAG_SPACE | FLAG_COLON | TYPE_MASK);
1735 	fld_s.flags |= (FLAG_ALT | FLAG_ZERO | TYPE_POINTER | ARG_PTR |
1736 			CONV_INT | INFO_UNSIGNED);
1737 	fld_s.prec = (SIZEOF_VOID_P * 2); /* number of characters */
1738 	fld_s.base = BASE_HEX;
1739 	break;
1740 
1741       case 'n': /* write back a character count */
1742 	if (fld_s.flags & TYPE_CHAR) /* eg, %hhn */
1743 	  *((char *)va_arg(vp, int *)) = TOTAL(buf_p);
1744 	else if (fld_s.flags & TYPE_SHORT) /* eg, %hn */
1745 	  *((short *)va_arg(vp, int *)) = TOTAL(buf_p);
1746 	else if (fld_s.flags & TYPE_QUAD) /* eg, %qn */
1747 	  *((int64_t *)va_arg(vp, int64_t *)) = TOTAL(buf_p);
1748 	else if (fld_s.flags & TYPE_LONG) /* eg, %ln */
1749 	  *((long *)va_arg(vp, long *)) = TOTAL(buf_p);
1750 	else if (fld_s.flags & TYPE_INTMAX) /* eg, %jn */
1751 	  *((_large_t *)va_arg(vp, _large_t *)) = TOTAL(buf_p);
1752 	else if (fld_s.flags & TYPE_PTRDIFF) /* eg, %tn */
1753 	  *((ptrdiff_t *)va_arg(vp, ptrdiff_t *)) = TOTAL(buf_p);
1754 	else if (fld_s.flags & TYPE_SIZE) /* eg, %zn */
1755 	  *((size_t *)va_arg(vp, size_t *)) = TOTAL(buf_p);
1756 	else if (fld_s.flags & TYPE_TIME) /* eg, %Tn */
1757 	  *((time_t *)va_arg(vp, time_t *)) = TOTAL(buf_p);
1758 	else /* eg, %n */
1759 	  *((int *)va_arg(vp, int *)) = TOTAL(buf_p);
1760 	fld_s.flags = 0; /* no further processing required */
1761 	break;
1762 
1763       case 'm': /* write out a string describing an errno error */
1764 	fld_s.flags &= ~(FLAG_PLUS | FLAG_SPACE | FLAG_ALT | FLAG_ZERO |
1765 			 FLAG_COLON | TYPE_MASK);
1766 	fld_s.flags |= CONV_STRING;
1767 	fld_s.value.v_ptr = (void *)strerror(errno);
1768 	break;
1769 
1770       case 'v': /* here's the infamous %v... */
1771 	fld_s.flags &= ~(FLAG_PLUS | FLAG_SPACE | FLAG_ALT | FLAG_ZERO |
1772 			 FLAG_COLON | TYPE_MASK);
1773 	fld_s.flags |= ARG_PTR | CONV_VARARGS;
1774 	break;
1775 
1776       case 'C': /* convert a client name... */
1777 	fld_s.flags &= ~(FLAG_PLUS | FLAG_SPACE | FLAG_ZERO | TYPE_MASK);
1778 	fld_s.flags |= ARG_PTR | CONV_CLIENT;
1779 	break;
1780 
1781       case 'H': /* convert a channel name... */
1782 	fld_s.flags &= ~(FLAG_PLUS | FLAG_SPACE | FLAG_ALT | FLAG_ZERO |
1783 			 FLAG_COLON | TYPE_MASK);
1784 	fld_s.flags |= ARG_PTR | CONV_CHANNEL;
1785 	break;
1786 
1787       default: /* Unsupported, display a message and the entire format */
1788 	adds(buf_p, -1, "(Unsupported: %");
1789 	adds(buf_p, fmt - fstart + 1, fstart);
1790 	addc(buf_p, ')');
1791 	fld_s.flags = 0; /* no further processing required */
1792 	break;
1793       } /* switch (*fmt) { */
1794 
1795       break;
1796     } /* for (; *fmt; fmt++) { */
1797 
1798     if (!*fmt) /* hit the end */
1799       break;
1800     else if (!(fld_s.flags & (ARG_MASK | CONV_MASK))) /* is it done? */
1801       continue;
1802 
1803     if ((fld_s.flags & ARG_MASK) == ARG_INT) { /* grab an integer argument */
1804       if (fld_s.flags & INFO_UNSIGNED) { /* go direct if unsigned */
1805 	if (fld_s.flags & TYPE_CHAR) /* eg, %hhu */
1806 	  fld_s.value.v_int = (unsigned char)va_arg(vp, unsigned int);
1807 	else if (fld_s.flags & TYPE_SHORT) /* eg, %hu */
1808 	  fld_s.value.v_int = (unsigned short)va_arg(vp, unsigned int);
1809 	else if (fld_s.flags & TYPE_QUAD) /* eg, %qu */
1810 	  fld_s.value.v_int = va_arg(vp, uint64_t);
1811 	else if (fld_s.flags & TYPE_LONG) /* eg, %lu */
1812 	  fld_s.value.v_int = va_arg(vp, unsigned long);
1813 	else if (fld_s.flags & TYPE_INTMAX) /* eg, %ju */
1814 	  fld_s.value.v_int = va_arg(vp, _large_t);
1815 	else if (fld_s.flags & TYPE_PTRDIFF) /* eg, %tu */
1816 	  fld_s.value.v_int = va_arg(vp, ptrdiff_t);
1817 	else if (fld_s.flags & TYPE_SIZE) /* eg, %zu */
1818 	  fld_s.value.v_int = va_arg(vp, size_t);
1819 	else if (fld_s.flags & TYPE_TIME) /* eg, %Tu */
1820 	  fld_s.value.v_int = va_arg(vp, time_t);
1821 	else if (fld_s.flags & TYPE_POINTER) /* eg, %p */
1822 	  fld_s.value.v_int = va_arg(vp, _pointer_t);
1823 	else /* eg, %u */
1824 	  fld_s.value.v_int = va_arg(vp, unsigned int);
1825       } else {
1826 	_large_t signed_int; /* temp. store the signed integer */
1827 
1828 	if (fld_s.flags & TYPE_CHAR) /* eg, %hhd */
1829 	  signed_int = (char)va_arg(vp, unsigned int);
1830 	else if (fld_s.flags & TYPE_SHORT) /* eg, %hd */
1831 	  signed_int = (short)va_arg(vp, unsigned int);
1832 	else if (fld_s.flags & TYPE_QUAD) /* eg, %qd */
1833 	  signed_int = va_arg(vp, int64_t);
1834 	else if (fld_s.flags & TYPE_LONG) /* eg, %ld */
1835 	  signed_int = va_arg(vp, long);
1836 	else if (fld_s.flags & TYPE_INTMAX) /* eg, %jd */
1837 	  signed_int = va_arg(vp, _large_t);
1838 	else if (fld_s.flags & TYPE_PTRDIFF) /* eg, %td */
1839 	  signed_int = va_arg(vp, ptrdiff_t);
1840 	else if (fld_s.flags & TYPE_SIZE) /* eg, %zd */
1841 	  signed_int = va_arg(vp, size_t);
1842 	else if (fld_s.flags & TYPE_TIME) /* eg, %Td */
1843 	  signed_int = va_arg(vp, time_t);
1844 	else /* eg, %d */
1845 	  signed_int = va_arg(vp, int);
1846 
1847 	if (signed_int < 0) { /* Now figure out if it's negative... */
1848 	  fld_s.flags |= INFO_NEGATIVE;
1849 	  fld_s.value.v_int = -signed_int; /* negate safely (I hope) */
1850 	} else
1851 	  fld_s.value.v_int = signed_int;
1852       }
1853     } else if ((fld_s.flags & ARG_MASK) == ARG_FLOAT) { /* extract a float */
1854       if (fld_s.flags & TYPE_LONGDOUBLE) /* eg, %Lf */
1855 	fld_s.value.v_float = va_arg(vp, long double);
1856       else /* eg, %f */
1857 	fld_s.value.v_float = va_arg(vp, double);
1858     } else if ((fld_s.flags & ARG_MASK) == ARG_PTR) { /* pointer argument */
1859       fld_s.value.v_ptr = va_arg(vp, void *);
1860     }
1861 
1862     /* We've eaten the arguments, we have all the information we need for
1863      * the conversion.  Time to actually *do* the conversion
1864      */
1865     if ((fld_s.flags & CONV_MASK) == CONV_INT) {
1866       /* convert an integer */
1867       char intbuf[INTBUF_LEN], **table = 0, *tstr;
1868       int ibuf_loc = INTBUF_LEN, ilen, zlen = 0, plen = 0, elen = 0;
1869 
1870       if (fld_s.base == BASE_OCTAL) /* select string table to use */
1871 	table = octal;
1872       else if (fld_s.base == BASE_DECIMAL)
1873 	table = decimal;
1874       else if (fld_s.base == BASE_HEX) { /* have to deal with upper case */
1875 	table = (fld_s.flags & INFO_UPPERCASE) ? HEX : hex;
1876 	if (fld_s.flags & FLAG_ALT)
1877 	  elen = 2; /* account for the length of 0x */
1878       }
1879 
1880       if (fld_s.prec < 0) { /* default precision is 1 */
1881 	if ((fld_s.flags & (FLAG_MINUS | FLAG_ZERO)) == FLAG_ZERO &&
1882 	    fld_s.width) {
1883 	  fld_s.prec = fld_s.width - elen;
1884 	  fld_s.width = 0;
1885 	} else
1886 	  fld_s.prec = 1;
1887       }
1888 
1889       /* If there's a sign flag, account for it */
1890       if (fld_s.flags & (FLAG_PLUS | FLAG_SPACE | INFO_NEGATIVE))
1891 	elen++;
1892 
1893       if (fld_s.base < 0) { /* non-binary base flagged by negative */
1894 	fld_s.base = -fld_s.base; /* negate it... */
1895 
1896 	while (fld_s.value.v_int) { /* and convert it */
1897 	  tstr = table[fld_s.value.v_int % fld_s.base]; /* which string? */
1898 	  fld_s.value.v_int /= fld_s.base; /* next value */
1899 
1900 	  ilen = 3; /* if we have to fill in zeros, here's how many */
1901 
1902 	  while (*tstr) { /* add string to intbuf; note growing backwards */
1903 	    intbuf[--ibuf_loc] = *(tstr++);
1904 	    ilen--;
1905 	  }
1906 
1907 	  if (fld_s.value.v_int > 0 && ilen) /* add zeros if needed */
1908 	    while (ilen--)
1909 	      intbuf[--ibuf_loc] = '0';
1910 	}
1911       } else { /* optimize for powers of 2 */
1912 	while (fld_s.value.v_int) { /* which string? */
1913 	  tstr = table[(fld_s.value.v_int & ((1 << fld_s.base) - 1))];
1914 	  fld_s.value.v_int >>= fld_s.base; /* next value */
1915 
1916 	  ilen = 3; /* if we have to fill in zeros, here's how many */
1917 
1918 	  while (*tstr) { /* add string to intbuf; note growing backwards */
1919 	    intbuf[--ibuf_loc] = *(tstr++);
1920 	    ilen--;
1921 	  }
1922 
1923 	  if (fld_s.value.v_int > 0 && ilen) /* add zeros if needed */
1924 	    while (ilen--)
1925 	      intbuf[--ibuf_loc] = '0';
1926 	}
1927       }
1928 
1929       ilen = INTBUF_LEN - ibuf_loc; /* how many chars did we add? */
1930 
1931       if (fld_s.prec > ilen) /* do we need any leading zeros? */
1932 	zlen = fld_s.prec - ilen;
1933 
1934       if (fld_s.base == BASE_OCTAL && zlen == 0 && fld_s.flags & FLAG_ALT)
1935 	zlen++; /* factor in a leading zero for %#o */
1936 
1937       if (fld_s.width > ilen + zlen + elen) /* calculate space padding */
1938 	plen = fld_s.width - (ilen + zlen + elen);
1939 
1940       if (plen > 0 && !(fld_s.flags & FLAG_MINUS))
1941 	do_pad(buf_p, plen, spaces); /* pre-padding */
1942 
1943       if (fld_s.flags & INFO_NEGATIVE) /* leading signs */
1944 	addc(buf_p, '-');
1945       else if (fld_s.flags & FLAG_PLUS)
1946 	addc(buf_p, '+');
1947       else if (fld_s.flags & FLAG_SPACE)
1948 	addc(buf_p, ' ');
1949 
1950       if ((fld_s.flags & FLAG_ALT) && fld_s.base == BASE_HEX) { /* hex 0x */
1951 	addc(buf_p, '0');
1952 	addc(buf_p, fld_s.flags & INFO_UPPERCASE ? 'X' : 'x');
1953       }
1954 
1955       if (zlen > 0) /* leading zeros */
1956 	do_pad(buf_p, zlen, zeros);
1957 
1958       adds(buf_p, ilen, intbuf + ibuf_loc); /* add the integer string */
1959 
1960       if (plen > 0 &&  (fld_s.flags & FLAG_MINUS))
1961 	do_pad(buf_p, plen, spaces); /* post-padding */
1962 
1963       /* Don't support floating point at this time; it's too complicated */
1964 /*      } else if ((fld_s.flags & CONV_MASK) == CONV_FLOAT) { */
1965       /* convert a float */
1966     } else if ((fld_s.flags & CONV_MASK) == CONV_CHAR) {
1967       if (fld_s.width > 0 && !(fld_s.flags & FLAG_MINUS))
1968 	do_pad(buf_p, fld_s.width - 1, spaces); /* pre-padding */
1969 
1970       addc(buf_p, fld_s.value.v_int); /* add the character */
1971 
1972       if (fld_s.width > 0 &&  (fld_s.flags & FLAG_MINUS))
1973 	do_pad(buf_p, fld_s.width - 1, spaces); /* post-padding */
1974     } else if ((fld_s.flags & CONV_MASK) == CONV_STRING ||
1975 	       fld_s.value.v_ptr == 0) { /* spaces or null pointers */
1976       int slen, plen;
1977       char *str = (char*) fld_s.value.v_ptr;
1978 
1979       if (!str) /* NULL pointers print "(null)" */
1980 	str = "(null)";
1981 
1982       slen = my_strnlen(str, fld_s.prec); /* str lengths and pad lengths */
1983       plen = (fld_s.width - slen <= 0 ? 0 : fld_s.width - slen);
1984 
1985       if (plen > 0 && !(fld_s.flags & FLAG_MINUS))
1986 	do_pad(buf_p, plen, spaces); /* pre-padding */
1987 
1988       adds(buf_p, slen, str); /* add the string */
1989 
1990       if (plen > 0 &&  (fld_s.flags & FLAG_MINUS))
1991 	do_pad(buf_p, plen, spaces); /* post-padding */
1992     } else if ((fld_s.flags & CONV_MASK) == CONV_VARARGS) {
1993       struct BufData buf_s = BUFDATA_INIT;
1994       struct VarData *vdata = (struct VarData*) fld_s.value.v_ptr;
1995       int plen, tlen;
1996 
1997       buf_s.buf = buf_p->buf + buf_p->buf_loc;
1998       buf_s.buf_size = buf_p->buf_size - buf_p->buf_loc;
1999       buf_s.limit = fld_s.prec;
2000 
2001       doprintf(dest, &buf_s, vdata->vd_format, vdata->vd_args);
2002 
2003       plen = (fld_s.width <= buf_s.buf_loc ? 0 :
2004 	      fld_s.width - buf_s.buf_loc);
2005 
2006       if (plen > 0) {
2007 	if (fld_s.flags & FLAG_MINUS) { /* left aligned... */
2008 	  buf_p->buf_loc += buf_s.buf_loc; /* remember the modifications */
2009 	  buf_p->buf_overflow += buf_s.buf_overflow;
2010 
2011 	  do_pad(buf_p, plen, spaces); /* and do the post-padding */
2012 	} else { /* right aligned... */
2013 	  /* Ok, first, see if we'll have *anything* left after padding */
2014 	  if (plen > buf_s.buf_size) {
2015 	    /* nope, good, this is easy: everything overflowed buffer */
2016 	    do_pad(buf_p, plen, spaces);
2017 
2018 	    buf_s.buf_overflow += buf_s.buf_loc; /* update buf counts */
2019 	    buf_s.buf_loc = 0;
2020 	    buf_p->buf_overflow += buf_s.buf_overflow;
2021 	  } else {
2022 	    /* first figure out how much we're going to save */
2023 	    tlen = SNP_MIN(buf_s.buf_loc, buf_s.buf_size - plen);
2024 
2025 	    memmove(buf_s.buf + plen, buf_s.buf, tlen); /* save it... */
2026 	    do_pad(buf_p, plen, spaces); /* add spaces... */
2027 
2028 	    buf_s.buf_overflow += buf_s.buf_loc - tlen; /* update buf counts */
2029 	    buf_s.buf_loc = tlen;
2030 	    buf_p->buf_overflow += buf_s.buf_overflow;
2031 	    buf_p->buf_loc += buf_s.buf_loc;
2032 	  }
2033 	}
2034       } else {
2035 	buf_p->buf_loc += buf_s.buf_loc; /* no padding, but remember mods */
2036 	buf_p->buf_overflow += buf_s.buf_overflow;
2037       }
2038 
2039       vdata->vd_chars = buf_s.buf_loc; /* return relevant data */
2040       vdata->vd_overflow = SNP_MAX(buf_s.buf_overflow, buf_s.overflow);
2041     } else if ((fld_s.flags & CONV_MASK) == CONV_CLIENT) {
2042       struct Client *cptr = (struct Client*) fld_s.value.v_ptr;
2043       const char *str1 = 0, *str2 = 0, *str3 = 0;
2044       int slen1 = 0, slen2 = 0, slen3 = 0, elen = 0, plen = 0;
2045 
2046       /* &me is used if it's not a definite server */
2047       if (dest && (IsServer(dest) || IsMe(dest))) {
2048 	if (IsServer(cptr) || IsMe(cptr))
2049 	  str1 = cli_yxx(cptr);
2050 	else {
2051 	  str1 = cli_yxx(cli_user(cptr)->server);
2052 	  str2 = cli_yxx(cptr);
2053 	}
2054 	fld_s.flags &= ~(FLAG_ALT | FLAG_COLON);
2055       } else {
2056 	str1 = *cli_name(cptr) ? cli_name(cptr) : "*";
2057 	if (!IsServer(cptr) && !IsMe(cptr) && fld_s.flags & FLAG_ALT) {
2058 	  assert(0 != cli_user(cptr));
2059 	  assert(0 != *(cli_name(cptr)));
2060 	  str2 = cli_user(cptr)->username;
2061 	  str3 = cli_user(cptr)->host;
2062 	} else
2063 	  fld_s.flags &= ~FLAG_ALT;
2064       }
2065 
2066       if (fld_s.flags & FLAG_COLON)
2067 	elen++; /* account for : */
2068 
2069       slen1 = my_strnlen(str1, fld_s.prec < 0 ? -1 : fld_s.prec - elen);
2070       if (fld_s.flags & FLAG_ALT)
2071 	elen++; /* account for ! */
2072       if (str2 && (fld_s.prec < 0 || fld_s.prec - (slen1 + elen) > 0))
2073 	slen2 = my_strnlen(str2, fld_s.prec < 0 ? -1 : fld_s.prec -
2074 			   (slen1 + elen));
2075       if (fld_s.flags & FLAG_ALT)
2076 	elen++; /* account for @ */
2077       if (str3 && (fld_s.prec < 0 || fld_s.prec - (slen1 + slen2 + elen) > 0))
2078 	slen3 = my_strnlen(str3, fld_s.prec < 0 ? -1 : fld_s.prec -
2079 			   (slen1 + slen2 + elen));
2080       plen = (fld_s.width - (slen1 + slen2 + slen3 + elen) <= 0 ? 0 :
2081 	      fld_s.width - (slen1 + slen2 + slen3 + elen));
2082 
2083       if (plen > 0 && !(fld_s.flags & FLAG_MINUS))
2084 	do_pad(buf_p, plen, spaces); /* pre-padding */
2085 
2086       if (fld_s.flags & FLAG_COLON)
2087 	addc(buf_p, ':');
2088       adds(buf_p, slen1, str1);
2089       if (fld_s.flags & FLAG_ALT)
2090 	addc(buf_p, '!');
2091       if (str2)
2092 	adds(buf_p, slen2, str2);
2093       if (fld_s.flags & FLAG_ALT)
2094 	addc(buf_p, '@');
2095       if (str3)
2096 	adds(buf_p, slen3, str3);
2097 
2098       if (plen > 0 &&  (fld_s.flags & FLAG_MINUS))
2099 	do_pad(buf_p, plen, spaces); /* post-padding */
2100     } else if ((fld_s.flags & CONV_MASK) == CONV_CHANNEL) {
2101       struct Channel *chan = (struct Channel *)fld_s.value.v_ptr;
2102       char *str = chan->chname;
2103       int slen, plen;
2104 
2105       slen = my_strnlen(str, fld_s.prec); /* str lengths and pad lengths */
2106       plen = (fld_s.width - slen <= 0 ? 0 : fld_s.width - slen);
2107 
2108       if (plen > 0 && !(fld_s.flags & FLAG_MINUS))
2109 	do_pad(buf_p, plen, spaces); /* pre-padding */
2110 
2111       adds(buf_p, slen, str); /* add the string */
2112 
2113       if (plen > 0 &&  (fld_s.flags & FLAG_MINUS))
2114 	do_pad(buf_p, plen, spaces); /* post-padding */
2115     }
2116   } /* for (; *fmt; fmt++) { */
2117 }
2118 
2119 /* ircd_snprintf() has a big Doxygen comment in the header file. */
2120 int
ircd_snprintf(struct Client * dest,char * buf,size_t buf_len,const char * format,...)2121 ircd_snprintf(struct Client *dest, char *buf, size_t buf_len,
2122 	      const char *format, ...)
2123 {
2124   struct BufData buf_s = BUFDATA_INIT;
2125   va_list args;
2126 
2127   if (!format)
2128     return 0;
2129 
2130   buf_s.buf = buf; /* initialize buffer settings */
2131   buf_s.buf_size = buf_len - 1;
2132   buf_s.limit = -1;
2133 
2134   va_start(args, format);
2135   doprintf(dest, &buf_s, format, args); /* fill the buffer */
2136   va_end(args);
2137 
2138   buf_s.buf[buf_s.buf_loc] = '\0'; /* terminate buffer */
2139 
2140   return TOTAL(&buf_s);
2141 }
2142 
2143 /** Like ircd_snprintf() but with a va_list argument list.
2144  * @param[in] dest Client receiving of message.
2145  * @param[out] buf Output buffer for formatted message.
2146  * @param[in] buf_len Number of bytes that can be written to \a buf.
2147  * @param[in] format Format string for message.
2148  * @param[in] args Variable-length argument list for format string.
2149  * @return Number of bytes that would be written to \a buf without truncation.
2150  */
2151 int
ircd_vsnprintf(struct Client * dest,char * buf,size_t buf_len,const char * format,va_list args)2152 ircd_vsnprintf(struct Client *dest, char *buf, size_t buf_len,
2153 	       const char *format, va_list args)
2154 {
2155   struct BufData buf_s = BUFDATA_INIT;
2156 
2157   if (!format)
2158     return 0;
2159 
2160   buf_s.buf = buf; /* initialize buffer settings */
2161   buf_s.buf_size = buf_len - 1;
2162   buf_s.limit = -1;
2163 
2164   doprintf(dest, &buf_s, format, args); /* fill the buffer */
2165 
2166   buf_s.buf[buf_s.buf_loc] = '\0'; /* terminate buffer */
2167 
2168   return TOTAL(&buf_s);
2169 }
2170