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