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