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