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