Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
numeric.cpp
Go to the documentation of this file.
1
29#include "def.h" // for Def
30#include "diagnostic.h" // for issue_diag()
31#include "path.h" // for get_pathname()
32#include "scanner.h" // for scanner
33
34#include <cassert> // for assert()
35#include <cstdlib> // for atoi()
36#include <fstream> // for ofstream
37
38
39static const char lc_name[] = "LC_NUMERIC";
40
41
42void Def::process_numeric ()
43{
44 issue_diag (I_STAGE, false, 0, "processing %s section\n", lc_name);
45
46 // nesting level
47 int nesting_level = 0;
48
49 num_def_found_ = true;
50
51 while ((next = scanner_.next_token()).token != Scanner::tok_numeric) {
52
53 switch (next.token) {
54
56 next = scanner_.next_token();
57 if (next.token == Scanner::tok_numeric) {
58 // end of numeric block
59 if (nesting_level == 0)
60 return;
61
62 nesting_level--;
63 scanner_.close ();
64 } else
65 issue_diag (E_SYNTAX, true, &next,
66 "wrong section name in END directive\n");
67
68 break;
69
70 case Scanner::tok_copy: {
71 next = scanner_.next_token();
72 if (next.token != Scanner::tok_string)
73 issue_diag (E_SYNTAX, true, &next,
74 "expected string following \"copy\" directive\n");
75
76 // bump up the nesting level
77 nesting_level++;
78
79 issue_diag (I_STAGE, false, 0, "processing copy directive\n");
80
81 // open the file
82 scanner_.open (get_pathname (strip_quotes (next.name), next.file));
83
84 // get comment char and escape char;
85 // these informations are stored by the scanner
86 while ((next = scanner_.next_token ()).token
88 // the LC_IDENTIFICATION section may also have a
89 // LC_NUMERIC token that will mess up the parsing
90 if (next.token == Scanner::tok_ident) {
91 while ((next = scanner_.next_token()).token
93 next = scanner_.next_token();
94 }
95 }
96
97 break;
98 }
99
101 next = scanner_.next_token();
102 num_st_.decimal_point = convert_string (next.name);
103 num_st_.wdecimal_point = convert_wstring (next);
104 break;
105
107 next = scanner_.next_token();
108 num_st_.thousands_sep = convert_string (next.name);
109 num_st_.wthousands_sep = convert_wstring (next);
110 break;
111
113 // convert the grouping digits from ascii to integers before
114 // adding them to the grouping string
115 num_st_.grouping.clear();
116 while ((next = scanner_.next_token()).token
118 num_st_.grouping += std::atoi(next.name.c_str());
119 break;
120
122 next = scanner_.next_token();
123 num_st_.truename = convert_string (next.name);
124 num_st_.wtruename = convert_wstring (next);
125 break;
126
128 next = scanner_.next_token();
129 num_st_.falsename = convert_string (next.name);
130 num_st_.wfalsename = convert_wstring (next);
131 break;
132
133 default:
134 break;
135 }
136 }
137}
138
139
140void Def::write_numeric (std::string dir_name)
141{
142 assert (!dir_name.empty ());
143
144 if (num_written_)
145 return;
146
147 if (!num_def_found_) {
148 issue_diag (I_SKIP, false, 0,
149 "%s section not found, skipping\n", lc_name);
150 return;
151 }
152
153 (dir_name += _RWSTD_PATH_SEP) += lc_name;
154
155 issue_diag (I_OPENWR, false, 0, "writing %s\n", dir_name.c_str ());
156
157 std::ofstream out (dir_name.c_str (), std::ios::binary);
158 out.exceptions (std::ios::failbit | std::ios::badbit);
159
160 // calculate the offsets of members of the num_punct struct
161
162 // start with wide strings to simplify dealing with their alignment
163 num_punct_out_.decimal_point_off [1] = 0;
164
165 num_punct_out_.thousands_sep_off [1] =
166 unsigned (num_punct_out_.decimal_point_off [1]
167 + (num_st_.wdecimal_point.size () + 1) * sizeof (wchar_t));
168
169 num_punct_out_.decimal_point_off [0] =
170 unsigned (num_punct_out_.thousands_sep_off [1]
171 + (num_st_.wthousands_sep.size() + 1) * sizeof (wchar_t));
172
173 num_punct_out_.thousands_sep_off [0] =
174 unsigned (num_punct_out_.decimal_point_off [0]
175 + num_st_.decimal_point.size () + 1);
176
177 num_punct_out_.grouping_off =
178 unsigned (num_punct_out_.thousands_sep_off [0]
179 + num_st_.thousands_sep.size () + 1);
180
181 num_punct_out_.punct_ext_off =
182 unsigned (num_punct_out_.grouping_off
183 + num_st_.grouping.size () + 1);
184
185 // compute the alignment requirement of any offset member
186 const std::size_t align = sizeof num_punct_out_.punct_ext_off;
187
188 // align the offset of the extension struct on the required boundary
189 const std::size_t misalign = num_punct_out_.punct_ext_off % align;
190
191 // compute the amount of padding between the two structs
192 const std::size_t pad = misalign ? align - misalign : 0;
193
194 num_punct_out_.punct_ext_off += unsigned (pad);
195
196 // calculate the offsets of members of the numeric extension struct
197
198 num_out_.truename_off [1] = 0;
199
200 num_out_.falsename_off [1] =
201 unsigned (num_out_.truename_off [1]
202 + (num_st_.wtruename.size() + 1) * sizeof (wchar_t));
203
204 num_out_.truename_off [0] =
205 unsigned (num_out_.falsename_off [1]
206 + (num_st_.wfalsename.size() + 1) * sizeof (wchar_t));
207
208 num_out_.falsename_off [0] =
209 unsigned (num_out_.truename_off [0]
210 + num_st_.truename.size() + 1);
211
212 num_out_.codeset_off =
213 unsigned (num_out_.falsename_off [0]
214 + num_st_.falsename.size() + 1);
215
216 num_out_.charmap_off =
217 unsigned (num_out_.codeset_off
218 + charmap_.get_code_set_name().size() + 1);
219
220 issue_diag (I_WRITE, false, 0,
221 "%s layout:\n"
222 "__rw_punct_t {\n"
223 " decimal_point_off[] = { %u, %u }\n"
224 " thousand_sep_off[] = { %u, %u }\n"
225 " grouping_off = %u\n"
226 " ext_off = %u\n"
227 "}\n__rw_numpunct_t {\n"
228 " falsename_off[] = { %u, %u }\n"
229 " truename_off[] = { %u, %u }\n"
230 " codeset_off = %u\n"
231 " charmap_off = %u\n"
232 "}\n",
233 lc_name,
234 num_punct_out_.decimal_point_off [0],
235 num_punct_out_.decimal_point_off [1],
236 num_punct_out_.thousands_sep_off [0],
237 num_punct_out_.thousands_sep_off [1],
238 num_punct_out_.grouping_off,
239 num_punct_out_.punct_ext_off,
240 num_out_.falsename_off [0],
241 num_out_.falsename_off [1],
242 num_out_.truename_off [0],
243 num_out_.truename_off [1],
244 num_out_.codeset_off,
245 num_out_.charmap_off);
246
247 // write the num_punct struct
248 out.write ((char*)&num_punct_out_, sizeof (num_punct_out_));
249
250 // write out the strings in the num_punct struct
251 out.write ((const char*)num_st_.wdecimal_point.c_str (),
252 (num_st_.wdecimal_point.size() + 1) * sizeof (wchar_t));
253 out.write ((const char*)num_st_.wthousands_sep.c_str(),
254 (num_st_.wthousands_sep.size() + 1) * sizeof(wchar_t));
255
256 out << num_st_.decimal_point << std::ends
257 << num_st_.thousands_sep << std::ends
258 << num_st_.grouping << std::ends;
259
260 // pad the structure up to the next alignment boundary
261 out.write ("\0\0\0\0\0\0\0\0", pad);
262
263 // write the numeric offset extension struct
264 out.write ((char*)&num_out_, sizeof (num_out_));
265
266 // write all the wide character strings
267 out.write ((const char*)num_st_.wtruename.c_str(),
268 (num_st_.wtruename.size() + 1) * sizeof (wchar_t));
269 out.write ((const char*)num_st_.wfalsename.c_str(),
270 (num_st_.wfalsename.size() + 1) * sizeof (wchar_t));
271
272
273 // write the narrow strings and codeset name
274 out << num_st_.truename << std::ends
275 << num_st_.falsename << std::ends
276 << charmap_.get_code_set_name() << std::ends
277 << charmap_.get_charmap_name() << std::ends;
278
279 out.close();
280}
const int out
#define assert(expr)
Definition _cassert.h:40
#define _RWSTD_PATH_SEP
Definition _config.h:297
const std::string & get_code_set_name() const
Definition charmap.h:112
std::string get_charmap_name() const
Definition charmap.cpp:475
void write_numeric(std::string dir_name)
Definition numeric.cpp:140
void open(std::string, char='#', char='\\')
Definition scanner.cpp:142
void close()
Definition scanner.cpp:169
token_t next_token()
Definition scanner.cpp:352
@ tok_thousands_sep
Definition scanner.h:132
@ tok_end
Definition scanner.h:66
@ tok_decimal_point
Definition scanner.h:131
@ tok_numeric
Definition scanner.h:56
@ tok_string
Definition scanner.h:99
@ tok_truename
Definition scanner.h:134
@ tok_grouping
Definition scanner.h:133
@ tok_copy
Definition scanner.h:166
@ tok_nl
Definition scanner.h:168
@ tok_falsename
Definition scanner.h:135
@ tok_ident
Definition scanner.h:60
std::string strip_quotes(const std::string &str)
Definition def.h:604
bool issue_diag(int type, bool, const Scanner::token_t *token, const char *fmt,...)
@ I_OPENWR
Definition diagnostic.h:83
@ I_WRITE
Definition diagnostic.h:85
@ I_SKIP
Definition diagnostic.h:86
@ I_STAGE
Definition diagnostic.h:81
@ E_SYNTAX
Definition diagnostic.h:49
std::string get_pathname(const std::string &fname, const std::string &other)
Definition path.cpp:129
std::string name
Definition scanner.h:178
token_id token
Definition scanner.h:179
const char * file
Definition scanner.h:186