Mon, 03 Mar 2014 17:02:38 +0200
- reserved 'constexpr' as a keyword because I know I will need it someday
88 | 1 | /* |
2 | Copyright 2012-2014 Santeri Piippo | |
3 | All rights reserved. | |
4 | ||
5 | Redistribution and use in source and binary forms, with or without | |
6 | modification, are permitted provided that the following conditions | |
7 | are met: | |
8 | ||
9 | 1. Redistributions of source code must retain the above copyright | |
10 | notice, this list of conditions and the following disclaimer. | |
11 | 2. Redistributions in binary form must reproduce the above copyright | |
12 | notice, this list of conditions and the following disclaimer in the | |
13 | documentation and/or other materials provided with the distribution. | |
14 | 3. The name of the author may not be used to endorse or promote products | |
15 | derived from this software without specific prior written permission. | |
16 | ||
17 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | |
18 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |
19 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | |
20 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |
21 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
22 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
23 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
24 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
25 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
26 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
27 | */ | |
28 | ||
29 | #include <cstdio> | |
30 | #include "Main.h" | |
31 | #include "Format.h" | |
32 | #include "Lexer.h" | |
33 | ||
34 | // ============================================================================= | |
35 | // | |
115
9be16e1c1e44
- reformatting... again
Teemu Piippo <crimsondusk64@gmail.com>
parents:
113
diff
changeset
|
36 | static void formatError (String fmtstr, const String errdescribe, int pos) |
88 | 37 | { |
115
9be16e1c1e44
- reformatting... again
Teemu Piippo <crimsondusk64@gmail.com>
parents:
113
diff
changeset
|
38 | fmtstr.replace ("\n", " "); |
9be16e1c1e44
- reformatting... again
Teemu Piippo <crimsondusk64@gmail.com>
parents:
113
diff
changeset
|
39 | fmtstr.replace ("\t", " "); |
113
4d4c43eca4d7
- now uses a variadic template formatter instead of a macro
Teemu Piippo <crimsondusk64@gmail.com>
parents:
112
diff
changeset
|
40 | String errmsg ("With format string:\n" + fmtstr + "\n"); |
88 | 41 | |
42 | for (int x = 0; x < pos; ++x) | |
113
4d4c43eca4d7
- now uses a variadic template formatter instead of a macro
Teemu Piippo <crimsondusk64@gmail.com>
parents:
112
diff
changeset
|
43 | errmsg += "-"; |
88 | 44 | |
113
4d4c43eca4d7
- now uses a variadic template formatter instead of a macro
Teemu Piippo <crimsondusk64@gmail.com>
parents:
112
diff
changeset
|
45 | errmsg += "^\n" + errdescribe; |
115
9be16e1c1e44
- reformatting... again
Teemu Piippo <crimsondusk64@gmail.com>
parents:
113
diff
changeset
|
46 | throw std::logic_error (errmsg.stdString()); |
88 | 47 | } |
48 | ||
49 | // ============================================================================= | |
50 | // | |
115
9be16e1c1e44
- reformatting... again
Teemu Piippo <crimsondusk64@gmail.com>
parents:
113
diff
changeset
|
51 | String formatArgs (const String& fmtstr, const std::vector<String>& args) |
88 | 52 | { |
53 | String fmt = fmtstr; | |
54 | String out; | |
55 | int pos = 0; | |
56 | ||
115
9be16e1c1e44
- reformatting... again
Teemu Piippo <crimsondusk64@gmail.com>
parents:
113
diff
changeset
|
57 | while ((pos = fmt.firstIndexOf ("%", pos)) != -1) |
88 | 58 | { |
59 | if (fmt[pos + 1] == '%') | |
60 | { | |
115
9be16e1c1e44
- reformatting... again
Teemu Piippo <crimsondusk64@gmail.com>
parents:
113
diff
changeset
|
61 | fmt.replace (pos, 2, "%"); |
88 | 62 | pos++; |
63 | continue; | |
64 | } | |
65 | ||
66 | int ofs = 1; | |
67 | char mod = '\0'; | |
68 | ||
69 | // handle modifiers | |
105
6dbac3305614
- highly reworked variable support, variable declarations now are declared with 'var', uses are prefixed with '$', merged constant handling into variables
Teemu Piippo <crimsondusk64@gmail.com>
parents:
88
diff
changeset
|
70 | if (fmt[pos + ofs] == 's' || fmt[pos + ofs] == 'x' || fmt[pos + ofs] == 'd') |
88 | 71 | { |
72 | mod = fmt[pos + ofs]; | |
73 | ofs++; | |
74 | } | |
75 | ||
76 | if (!isdigit (fmt[pos + ofs])) | |
115
9be16e1c1e44
- reformatting... again
Teemu Piippo <crimsondusk64@gmail.com>
parents:
113
diff
changeset
|
77 | formatError (fmtstr, "bad format string, expected digit with optional " |
113
4d4c43eca4d7
- now uses a variadic template formatter instead of a macro
Teemu Piippo <crimsondusk64@gmail.com>
parents:
112
diff
changeset
|
78 | "modifier after '%%'", pos); |
88 | 79 | |
80 | int i = fmt[pos + ofs] - '0'; | |
81 | ||
113
4d4c43eca4d7
- now uses a variadic template formatter instead of a macro
Teemu Piippo <crimsondusk64@gmail.com>
parents:
112
diff
changeset
|
82 | if (i > static_cast<signed> (args.size())) |
115
9be16e1c1e44
- reformatting... again
Teemu Piippo <crimsondusk64@gmail.com>
parents:
113
diff
changeset
|
83 | formatError (fmtstr, String ("Format argument #") + i + " used but not defined.", pos); |
88 | 84 | |
113
4d4c43eca4d7
- now uses a variadic template formatter instead of a macro
Teemu Piippo <crimsondusk64@gmail.com>
parents:
112
diff
changeset
|
85 | String replacement = args[i - 1]; |
88 | 86 | |
87 | switch (mod) | |
88 | { | |
113
4d4c43eca4d7
- now uses a variadic template formatter instead of a macro
Teemu Piippo <crimsondusk64@gmail.com>
parents:
112
diff
changeset
|
89 | case 's': replacement = (replacement == "1") ? "" : "s"; break; |
115
9be16e1c1e44
- reformatting... again
Teemu Piippo <crimsondusk64@gmail.com>
parents:
113
diff
changeset
|
90 | case 'd': replacement.sprintf ("%d", replacement[0]); break; |
9be16e1c1e44
- reformatting... again
Teemu Piippo <crimsondusk64@gmail.com>
parents:
113
diff
changeset
|
91 | case 'x': replacement.sprintf ("0x%X", replacement.toLong()); break; |
88 | 92 | default: break; |
93 | } | |
94 | ||
115
9be16e1c1e44
- reformatting... again
Teemu Piippo <crimsondusk64@gmail.com>
parents:
113
diff
changeset
|
95 | fmt.replace (pos, 1 + ofs, replacement); |
9be16e1c1e44
- reformatting... again
Teemu Piippo <crimsondusk64@gmail.com>
parents:
113
diff
changeset
|
96 | pos += replacement.length(); |
88 | 97 | } |
98 | ||
99 | return fmt; | |
100 | } | |
101 | ||
102 | // ============================================================================= | |
103 | // | |
115
9be16e1c1e44
- reformatting... again
Teemu Piippo <crimsondusk64@gmail.com>
parents:
113
diff
changeset
|
104 | void error (String msg) |
88 | 105 | { |
115
9be16e1c1e44
- reformatting... again
Teemu Piippo <crimsondusk64@gmail.com>
parents:
113
diff
changeset
|
106 | Lexer* lx = Lexer::getCurrentLexer(); |
88 | 107 | String fileinfo; |
108 | ||
115
9be16e1c1e44
- reformatting... again
Teemu Piippo <crimsondusk64@gmail.com>
parents:
113
diff
changeset
|
109 | if (lx != null && lx->hasValidToken()) |
88 | 110 | { |
115
9be16e1c1e44
- reformatting... again
Teemu Piippo <crimsondusk64@gmail.com>
parents:
113
diff
changeset
|
111 | Lexer::TokenInfo* tk = lx->token(); |
9be16e1c1e44
- reformatting... again
Teemu Piippo <crimsondusk64@gmail.com>
parents:
113
diff
changeset
|
112 | fileinfo = format ("%1:%2:%3: ", tk->file, tk->line, tk->column); |
88 | 113 | } |
114 | ||
113
4d4c43eca4d7
- now uses a variadic template formatter instead of a macro
Teemu Piippo <crimsondusk64@gmail.com>
parents:
112
diff
changeset
|
115 | throw std::runtime_error (fileinfo + msg); |
108
6409ece8297c
- refactored enums, macros split from Main.h to Macros.h
Teemu Piippo <crimsondusk64@gmail.com>
parents:
105
diff
changeset
|
116 | } |