src/format.h

changeset 124
a7b769a0e537
parent 119
bdf8d46c145f
child 125
85814c0918c5
equal deleted inserted replaced
123:ad33901eb4f6 124:a7b769a0e537
32 #include "string.h" 32 #include "string.h"
33 #include "list.h" 33 #include "list.h"
34 34
35 class FormatArgument 35 class FormatArgument
36 { 36 {
37 public: 37 public:
38 FormatArgument (const String& a) : m_text (a) {} 38 FormatArgument (const String& a) : m_text (a) {}
39 FormatArgument (char a) : m_text (a) {} 39 FormatArgument (char a) : m_text (a) {}
40 FormatArgument (int a) : m_text (String::fromNumber (a)) {} 40 FormatArgument (int a) : m_text (String::fromNumber (a)) {}
41 FormatArgument (long a) : m_text (String::fromNumber (a)) {} 41 FormatArgument (long a) : m_text (String::fromNumber (a)) {}
42 FormatArgument (const char* a) : m_text (a) {} 42 FormatArgument (const char* a) : m_text (a) {}
43 43
44 FormatArgument (void* a) 44 FormatArgument (void* a)
45 {
46 m_text.sprintf ("%p", a);
47 }
48
49 FormatArgument (const void* a)
50 {
51 m_text.sprintf ("%p", a);
52 }
53
54 template<class T> FormatArgument (const List<T>& list)
55 {
56 if (list.isEmpty())
45 { 57 {
46 m_text.sprintf ("%p", a); 58 m_text = "{}";
59 return;
47 } 60 }
48 61
49 FormatArgument (const void* a) 62 m_text = "{ ";
63
64 for (const T& a : list)
50 { 65 {
51 m_text.sprintf ("%p", a); 66 if (&a != &list[0])
67 m_text += ", ";
68
69 m_text += FormatArgument (a).text();
52 } 70 }
53 71
54 template<class T> FormatArgument (const List<T>& list) 72 m_text += " }";
55 { 73 }
56 if (list.isEmpty()) 74
57 { 75 inline const String& text() const
58 m_text = "{}"; 76 {
59 return; 77 return m_text;
60 } 78 }
61 79
62 m_text = "{ "; 80 private:
63 81 String m_text;
64 for (const T& a : list)
65 {
66 if (&a != &list[0])
67 m_text += ", ";
68
69 m_text += FormatArgument (a).text();
70 }
71
72 m_text += " }";
73 }
74
75 inline const String& text() const
76 {
77 return m_text;
78 }
79
80 private:
81 String m_text;
82 }; 82 };
83 83
84 #ifndef IN_IDE_PARSER 84 #ifndef IN_IDE_PARSER
85 # ifdef DEBUG 85 # ifdef DEBUG
86 # define devf(...) PrintTo (stderr, __VA_ARGS__) 86 # define devf(...) PrintTo (stderr, __VA_ARGS__)
96 // print the value of @a 96 // print the value of @a
97 void dvalof (void a); 97 void dvalof (void a);
98 #endif // IN_IDE_PARSER 98 #endif // IN_IDE_PARSER
99 99
100 100
101 /** 101 //
102 * Formats the given string with the given args. 102 // Formats the given string with the given args.
103 * 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); 104 String formatArgs (const String& fmtstr, const std::vector<String>& args);
109 105
110 /** 106 //
111 * Expands the given arguments into a vector of strings. 107 // Expands the given arguments into a vector of strings.
112 * 108 //
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> 109 template<typename T, typename... RestTypes>
118 void expandFormatArguments (std::vector<String>& data, const T& arg, const RestTypes& ... rest) 110 void expandFormatArguments (std::vector<String>& data, const T& arg, const RestTypes& ... rest)
119 { 111 {
120 data.push_back (FormatArgument (arg).text()); 112 data.push_back (FormatArgument (arg).text());
121 expandFormatArguments (data, rest...); 113 expandFormatArguments (data, rest...);
122 } 114 }
123 115
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)); 116 static void expandFormatArguments (std::vector<String>& data) __attribute__ ( (unused));
128 static void expandFormatArguments (std::vector<String>& data) 117 static void expandFormatArguments (std::vector<String>& data)
129 { 118 {
130 (void) data; 119 (void) data;
131 } 120 }
132 121
133 /** 122 //
134 * Formats the given formatter string and args and returns the string. 123 // Formats the given formatter string and args and returns the string.
135 * This is essentially a modernized sprintf. 124 // This is essentially a modernized sprintf.
136 * 125 //
137 * Args in the format string take the form %n where n is a digit. The argument 126 // 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 127 // will be expanded to the nth argument passed. This is essentially Qt's
139 * QString::arg() syntax. Note: %0 is invalid. 128 // QString::arg() syntax. Note: %0 is invalid.
140 * 129 //
141 * Arguments can be passed a modifier which takes the form of a character 130 // 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. 131 // just before the digit. Currently supported modifiers are s, d and x.
143 * 132 //
144 * - s: The argument will expand into "s" if it would've not expanded into "1" 133 // - 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 134 // otherwise. If it would have expanded into "1" it will expand into an
146 * empty string. 135 // empty string.
147 * 136 //
148 * - d: The argument expands into the numeric form of the first character of 137 // - 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 138 // its previous expansion. Use this to get numeric forms of @c char
150 * arguments. 139 // arguments.
151 * 140 //
152 * - x: The numeric argument will be represented in hexadecimal notation. This 141 // - 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 142 // 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 143 // argument did not expand into a number in the first place, 0 is used
155 * (and 0x0 is printed). 144 // and 0x0 is printed.
156 * 145 //
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> 146 template<typename... argtypes>
164 String format (const String& fmtstr, const argtypes&... raw_args) 147 String format (const String& fmtstr, const argtypes&... raw_args)
165 { 148 {
166 std::vector<String> args; 149 std::vector<String> args;
167 expandFormatArguments (args, raw_args...); 150 expandFormatArguments (args, raw_args...);
168 assert (args.size() == sizeof... (raw_args)); 151 assert (args.size() == sizeof... (raw_args));
169 return formatArgs (fmtstr, args); 152 return formatArgs (fmtstr, args);
170 } 153 }
171 154
172 /** 155 //
173 * This is an overload of @c format where no arguments are supplied. 156 // This is an overload of format() where no arguments are supplied.
174 * @return the formatter string as-is. 157 // It returns the formatter string as-is.
175 */ 158 //
176 static String format (const String& fmtstr) __attribute__ ( (unused)); 159 static String format (const String& fmtstr) __attribute__ ( (unused));
177 static String format (const String& fmtstr) 160 static String format (const String& fmtstr)
178 { 161 {
179 return fmtstr; 162 return fmtstr;
180 } 163 }
181 164
182 /** 165 //
183 * Processes the given formatter string using @c format and prints it to the 166 // Processes the given formatter string using format() and prints it to the
184 * specified file pointer. 167 // specified file pointer.
185 * 168 //
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> 169 template<typename... argtypes>
191 void printTo (FILE* fp, const String& fmtstr, const argtypes&... args) 170 void printTo (FILE* fp, const String& fmtstr, const argtypes&... args)
192 { 171 {
193 fprintf (fp, "%s", format (fmtstr, args...).c_str()); 172 fprintf (fp, "%s", format (fmtstr, args...).c_str());
194 } 173 }
195 174
196 /** 175 //
197 * Processes the given formatter string using @c format and prints the result to 176 // Processes the given formatter string using format() and appends it to the
198 * @c stdout. 177 // specified file by name.
199 * 178 //
200 * @param fmtstr Formatter string for @c format 179 template<typename... argtypes>
201 * @param args Arguments for @c fmtstr 180 void printTo (const String& filename, const String& fmtstr, const argtypes&... args)
202 */ 181 {
182 FILE* fp = fopen (filename, "a");
183
184 if (fp != null)
185 {
186 fprintf (fp, "%s", format (fmtstr, args...).c_str());
187 fflush (fp);
188 fclose (fp);
189 }
190 }
191
192 //
193 // Processes the given formatter string using format() and prints the result to
194 // stdout.
195 //
203 template<typename... argtypes> 196 template<typename... argtypes>
204 void print (const String& fmtstr, const argtypes&... args) 197 void print (const String& fmtstr, const argtypes&... args)
205 { 198 {
206 printTo (stdout, fmtstr, args...); 199 printTo (stdout, fmtstr, args...);
207 } 200 }
208 201
209 /** 202 //
210 * Throws an std::runtime_error with the processed formatted string. The program 203 // 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 204 // 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. 205 // caught in main() which prints the error to stderr and then exits.
213 * 206 //
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> 207 template<typename... argtypes>
219 void error (const String& fmtstr, const argtypes&... args) 208 void error (const String& fmtstr, const argtypes&... args)
220 { 209 {
221 error (format (fmtstr, args...)); 210 error (format (fmtstr, args...));
222 } 211 }
223 212
224 /** 213 //
225 * An overload of @c Error with no string formatting in between. 214 // An overload of error() with no string formatting in between.
226 * 215 //
227 * @param msg The error message. 216 void error (const String& msg);
228 */
229 void error (String msg);
230 217
231 #endif // BOTC_FORMAT_H 218 #endif // BOTC_FORMAT_H

mercurial