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