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