src/Format.h

changeset 113
4d4c43eca4d7
parent 110
7a7a53f1d51b
child 115
9be16e1c1e44
equal deleted inserted replaced
112:def56932f938 113:4d4c43eca4d7
33 #include "Containers.h" 33 #include "Containers.h"
34 34
35 class FormatArgument 35 class FormatArgument
36 { 36 {
37 public: 37 public:
38 FormatArgument (const String& a) : 38 FormatArgument (const String& a) : mText (a) {}
39 mText (a) {} 39 FormatArgument (char a) : mText (a) {}
40 40 FormatArgument (int a) : mText (String::FromNumber (a)) {}
41 FormatArgument (char a) : 41 FormatArgument (long a) : mText (String::FromNumber (a)) {}
42 mText (a) {} 42 FormatArgument (const char* a) : mText (a) {}
43
44 FormatArgument (int a) :
45 mText (String::FromNumber (a)) {}
46
47 FormatArgument (long a) :
48 mText (String::FromNumber (a)) {}
49
50 FormatArgument (const char* a) :
51 mText (a) {}
52 43
53 FormatArgument (void* a) 44 FormatArgument (void* a)
54 { 45 {
55 mText.SPrintf ("%p", a); 46 mText.SPrintf ("%p", a);
56 } 47 }
87 } 78 }
88 79
89 private: 80 private:
90 String mText; 81 String mText;
91 }; 82 };
92
93 template<class T> String custom_format (T a, const char* fmtstr)
94 {
95 String out;
96 out.SPrintf (fmtstr, a);
97 return out;
98 }
99
100 String FormatArgs (const List<FormatArgument>& args);
101 void PrintArgs (FILE* fp, const List<FormatArgument>& args);
102 void DoError (String msg);
103
104 #ifndef IN_IDE_PARSER
105 # define Format(...) FormatArgs ({__VA_ARGS__})
106 # define PrintTo(A, ...) PrintArgs (A, {__VA_ARGS__})
107 # define Print(...) PrintArgs (stdout, {__VA_ARGS__})
108 # define Error(...) DoError (Format (__VA_ARGS__))
109 #else
110 String Format (void, ...);
111 void PrintTo (FILE* fp, ...);
112 void Print (void, ...);
113 void Error (void, ...);
114 #endif
115 83
116 #ifndef IN_IDE_PARSER 84 #ifndef IN_IDE_PARSER
117 # ifdef DEBUG 85 # ifdef DEBUG
118 # define devf(...) PrintTo (stderr, __VA_ARGS__) 86 # define devf(...) PrintTo (stderr, __VA_ARGS__)
119 # define dvalof( A ) PrintTo (stderr, "value of '%1' = %2\n", #A, A) 87 # define dvalof( A ) PrintTo (stderr, "value of '%1' = %2\n", #A, A)
127 95
128 // print the value of @a 96 // print the value of @a
129 void dvalof (void a); 97 void dvalof (void a);
130 #endif // IN_IDE_PARSER 98 #endif // IN_IDE_PARSER
131 99
100
101 /**
102 * Formats the given string with the given args.
103 *
104 * @param fmtstr Formatter string to process.
105 * @param args Args to format with the string.
106 * @see format()
107 */
108 String FormatArgs (const String& fmtstr, const std::vector<String>& args);
109
110 /**
111 * Expands the given arguments into a vector of strings.
112 *
113 * @param data Where to insert the strings.
114 * @param arg First argument to process
115 * @param rest... Rest of the arguments.
116 */
117 template<typename T, typename... RestTypes>
118 void ExpandFormatArguments (std::vector<String>& data, const T& arg, const RestTypes& ... rest)
119 {
120 data.push_back (FormatArgument (arg).AsString());
121 ExpandFormatArguments (data, rest...);
122 }
123
124 /**
125 * This is an overload of @c ExpandFormatArguments for end-of-args support.
126 */
127 static void ExpandFormatArguments (std::vector<String>& data) __attribute__ ( (unused));
128 static void ExpandFormatArguments (std::vector<String>& data)
129 {
130 (void) data;
131 }
132
133 /**
134 * Formats the given formatter string and args and returns the string.
135 * This is essentially a modernized sprintf.
136 *
137 * Args in the format string take the form %n where n is a digit. The argument
138 * will be expanded to the nth argument passed. This is essentially Qt's
139 * QString::arg() syntax. Note: %0 is invalid.
140 *
141 * Arguments can be passed a modifier which takes the form of a character
142 * just before the digit. Currently supported modifiers are s, d and x.
143 *
144 * - s: The argument will expand into "s" if it would've not expanded into "1"
145 * otherwise. If it would have expanded into "1" it will expand into an
146 * empty string.
147 *
148 * - d: The argument expands into the numeric form of the first character of
149 * its previous expansion. Use this to get numeric forms of @c char
150 * arguments.
151 *
152 * - x: The numeric argument will be represented in hexadecimal notation. This
153 * will work if the argument is a string representing a number. If the
154 * argument did not expand into a number in the first place, 0 is used
155 * (and 0x0 is printed).
156 *
157 * @param fmtstr Formatter string to process
158 * @param raw_args Arguments for the formatter string.
159 * @return the formatted string.
160 * @see Print
161 * @see PrintTo
162 */
163 template<typename... argtypes>
164 String Format (const String& fmtstr, const argtypes&... raw_args)
165 {
166 std::vector<String> args;
167 ExpandFormatArguments (args, raw_args...);
168 assert (args.size() == sizeof... (raw_args));
169 return FormatArgs (fmtstr, args);
170 }
171
172 /**
173 * This is an overload of @c Format where no arguments are supplied.
174 * @return the formatter string as-is.
175 */
176 static String Format (const String& fmtstr) __attribute__ ( (unused));
177 static String Format (const String& fmtstr)
178 {
179 return fmtstr;
180 }
181
182 /**
183 * Processes the given formatter string using @c Format and prints it to the
184 * specified file pointer.
185 *
186 * @param fp File pointer to print the formatted string to
187 * @param fmtstr Formatter string for @c Format
188 * @param args Arguments for @c fmtstr
189 */
190 template<typename... argtypes>
191 void PrintTo (FILE* fp, const String& fmtstr, const argtypes&... args)
192 {
193 fprintf (fp, "%s", Format (fmtstr, args...).c_str());
194 }
195
196 /**
197 * Processes the given formatter string using @c Format and prints the result to
198 * @c stdout.
199 *
200 * @param fmtstr Formatter string for @c Format
201 * @param args Arguments for @c fmtstr
202 */
203 template<typename... argtypes>
204 void Print (const String& fmtstr, const argtypes&... args)
205 {
206 PrintTo (stdout, fmtstr, args...);
207 }
208
209 /**
210 * Throws an std::runtime_error with the processed formatted string. The program
211 * execution terminates after a call to this function as the exception is first
212 * caught in @c main which prints the error to stderr and then exits.
213 *
214 * @param fmtstr The formatter string of the error.
215 * @param args The args to the formatter string.
216 * @see Format
217 */
218 template<typename... argtypes>
219 void Error (const String& fmtstr, const argtypes&... args)
220 {
221 Error (Format (fmtstr, args...));
222 }
223
224 /**
225 * An overload of @c Error with no string formatting in between.
226 *
227 * @param msg The error message.
228 */
229 void Error (String msg);
230
132 #endif // BOTC_FORMAT_H 231 #endif // BOTC_FORMAT_H

mercurial