src/Format.cc

changeset 113
4d4c43eca4d7
parent 112
def56932f938
child 115
9be16e1c1e44
equal deleted inserted replaced
112:def56932f938 113:4d4c43eca4d7
31 #include "Format.h" 31 #include "Format.h"
32 #include "Lexer.h" 32 #include "Lexer.h"
33 33
34 // ============================================================================= 34 // =============================================================================
35 // 35 //
36 static void DrawPosition (const String& fmt, int pos) 36 static void FormatError (String fmtstr, const String errdescribe, int pos)
37 { 37 {
38 String rep (fmt); 38 fmtstr.Replace ("\n", " ");
39 rep.Replace ("\n", "↵"); 39 fmtstr.Replace ("\t", " ");
40 rep.Replace ("\t", "⇥"); 40 String errmsg ("With format string:\n" + fmtstr + "\n");
41
42 fprintf (stderr, "%s\n", rep.CString());
43 41
44 for (int x = 0; x < pos; ++x) 42 for (int x = 0; x < pos; ++x)
45 fprintf (stderr, "-"); 43 errmsg += "-";
46 44
47 fprintf (stderr, "^\n"); 45 errmsg += "^\n" + errdescribe;
46 throw std::logic_error (errmsg.STDString());
48 } 47 }
49 48
50 // ============================================================================= 49 // =============================================================================
51 // 50 //
52 String FormatArgs (const List<FormatArgument>& args) 51 String FormatArgs (const String& fmtstr, const std::vector<String>& args)
53 { 52 {
54 const String& fmtstr = args[0].AsString();
55 assert (args.Size() >= 1);
56
57 if (args.Size() == 1)
58 return args[0].AsString();
59
60 String fmt = fmtstr; 53 String fmt = fmtstr;
61 String out; 54 String out;
62 int pos = 0; 55 int pos = 0;
63 56
64 while ((pos = fmt.FirstIndexOf ("%", pos)) != -1) 57 while ((pos = fmt.FirstIndexOf ("%", pos)) != -1)
79 mod = fmt[pos + ofs]; 72 mod = fmt[pos + ofs];
80 ofs++; 73 ofs++;
81 } 74 }
82 75
83 if (!isdigit (fmt[pos + ofs])) 76 if (!isdigit (fmt[pos + ofs]))
84 { 77 FormatError (fmtstr, "bad format string, expected digit with optional "
85 fprintf (stderr, "bad format string, expected digit with optional " 78 "modifier after '%%'", pos);
86 "modifier after '%%':\n");
87 DrawPosition (fmt, pos);
88 return fmt;
89 }
90 79
91 int i = fmt[pos + ofs] - '0'; 80 int i = fmt[pos + ofs] - '0';
92 81
93 if (i >= args.Size()) 82 if (i > static_cast<signed> (args.size()))
94 { 83 FormatError (fmtstr, String ("Format argument #") + i + " used but not defined.", pos);
95 fprintf (stderr, "format arg #%d used but not defined: %s\n", i, fmtstr.CString());
96 return fmt;
97 }
98 84
99 String repl = args[i].AsString(); 85 String replacement = args[i - 1];
100 86
101 switch (mod) 87 switch (mod)
102 { 88 {
103 case 's': repl = (repl == "1") ? "" : "s"; break; 89 case 's': replacement = (replacement == "1") ? "" : "s"; break;
104 case 'd': repl.SPrintf ("%d", repl[0]); break; 90 case 'd': replacement.SPrintf ("%d", replacement[0]); break;
105 case 'x': repl.SPrintf ("0x%X", repl.ToLong()); break; 91 case 'x': replacement.SPrintf ("0x%X", replacement.ToLong()); break;
106 default: break; 92 default: break;
107 } 93 }
108 94
109 fmt.Replace (pos, 1 + ofs, repl); 95 fmt.Replace (pos, 1 + ofs, replacement);
110 pos += repl.Length(); 96 pos += replacement.Length();
111 } 97 }
112 98
113 return fmt; 99 return fmt;
114 } 100 }
115 101
116 // ============================================================================= 102 // =============================================================================
117 // 103 //
118 void PrintArgs (FILE* fp, const List<FormatArgument>& args) 104 void Error (String msg)
119 {
120 String out = FormatArgs (args);
121 fprintf (fp, "%s", out.CString());
122 }
123
124 // =============================================================================
125 //
126 void DoError (String msg)
127 { 105 {
128 Lexer* lx = Lexer::GetCurrentLexer(); 106 Lexer* lx = Lexer::GetCurrentLexer();
129 String fileinfo; 107 String fileinfo;
130 108
131 if (lx != null && lx->HasValidToken()) 109 if (lx != null && lx->HasValidToken())
132 { 110 {
133 Lexer::TokenInfo* tk = lx->Token(); 111 Lexer::TokenInfo* tk = lx->Token();
134 fileinfo = Format ("%1:%2:%3: ", tk->file, tk->line, tk->column); 112 fileinfo = Format ("%1:%2:%3: ", tk->file, tk->line, tk->column);
135 } 113 }
136 114
137 throw ScriptError (fileinfo + msg); 115 throw std::runtime_error (fileinfo + msg);
138 } 116 }

mercurial