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