19#define MAXIMUM_LEADBYTES 12
31static_assert(
sizeof(
NLS_FILE_HEADER) == 26,
"Wrong size for NLS_FILE_HEADER");
43 std::size_t comment_pos =
str.find_first_of(
';');
44 if (comment_pos != std::string::npos)
46 str.erase(comment_pos);
51 if (end_of_line != std::string::npos)
52 str.erase(end_of_line + 1);
57 }
while (
str.empty());
65 if (token_start == std::string::npos)
72 std::size_t token_end =
str.find_first_of(
whitespaces, token_start);
73 if (token_end == std::string::npos)
80 token =
str.substr(token_start, token_end);
92 if ((
val > std::numeric_limits<T>::max()) || (
val < std::numeric_limits<T>::min()))
93 throw std::invalid_argument(
token +
" does not fit range ["
94 + std::to_string(std::numeric_limits<T>::min()) +
":" + std::to_string(std::numeric_limits<T>::max()) +
"]");
101 std::cerr <<
"Error parsing line " <<
line_number <<
": " <<
err << std::endl;
109 std::cerr <<
"Usage: " <<
argv[0] <<
" <txt_in> <nls_out>" << std::endl;
114 if (!
input.is_open())
116 std::cerr <<
"Unable to open " <<
argv[1] << std::endl;
121 memset(&FileHeader, 0,
sizeof(FileHeader));
123 std::string curr_line;
127 std::cerr <<
"ERROR: File is empty" << std::endl;
133 if (
token !=
"CODEPAGE")
134 error(
"expected CODEPAGE, got \"" +
token +
"\" instead");
139 catch(
const std::invalid_argument& ia)
144 if (!curr_line.empty())
145 error(
"Garbage after CODEPAGE statement: \"" + curr_line +
"\"");
149 error(
"Nothing after CODEPAGE statement");
152 if (
token !=
"CPINFO")
153 error(
"Expected CPINFO, got \"" +
token +
"\" instead");
160 catch(
const std::invalid_argument& ia)
165 if (!curr_line.empty())
166 error(
"Garbage after CPINFO statement: \"" + curr_line +
"\"");
168 error(
"Expected 1 or 2 as max char size in CPINFO, got \"" + std::to_string(FileHeader.
MaximumCharacterSize) +
"\" instead");
170 error(
"Default MB character " + std::to_string(FileHeader.
DefaultChar) +
" doesn't fit in a 8-bit value");
173 bool has_mbtable =
false;
176 bool has_wctable =
false;
180 for (
int i = 0;
i < 65536;
i++)
186 for (
int i = 0;
i < 65536;
i++)
195 bool has_glyphs =
false;
202 if (
token ==
"ENDCODEPAGE")
204 if (!curr_line.empty())
205 error(
"Garbage after ENDCODEPAGE statement: \"" + curr_line +
"\"");
208 else if (
token ==
"MBTABLE")
215 catch(
const std::invalid_argument& ia)
220 error(
"MBTABLE can only be declared once");
222 error(
"MBTABLE size can't be larger than 256");
223 if (!curr_line.empty())
224 error(
"Garbage after MBTABLE statement: \"" + curr_line +
"\"");
230 error(
"Expected " + std::to_string(
table_size + 1) +
" more lines after MBTABLE token");
240 catch(
const std::invalid_argument& ia)
244 if (!curr_line.empty())
245 error(
"Garbage after MBTABLE entry: \"" + curr_line +
"\"");
249 else if (
token ==
"WCTABLE")
256 catch(
const std::invalid_argument& ia)
261 error(
"WCTABLE can only be declared once");
262 if (!curr_line.empty())
263 error(
"Garbage after WCTABLE statement: \"" + curr_line +
"\"");
265 error(
"WCTABLE size can't be larger than 65536");
274 error(
"Expected " + std::to_string(
table_size + 1) +
" more lines after WCTABLE token");
284 catch(
const std::invalid_argument& ia)
288 if (!curr_line.empty())
289 error(
"Garbage after WCTABLE entry: \"" + curr_line +
"\"");
299 error(
"Expected " + std::to_string(
table_size + 1) +
" more lines after WCTABLE token");
308 catch(
const std::invalid_argument& ia)
312 if (!curr_line.empty())
313 error(
"Garbage after MBTABLE entry: \"" + curr_line +
"\"");
314 wc_table_dbcs[wc] = mb;
318 else if (
token ==
"DBCSRANGE")
320 if (dbcs_range_count != 0)
321 error(
"DBCSRANGE can only be declared once");
325 tokenize(curr_line, dbcs_range_count);
327 catch(
const std::invalid_argument& ia)
333 if (!curr_line.empty())
334 error(
"Garbage after DBCSRANGE token");
336 std::size_t current_offset = 0;
338 uint16_t range_count = dbcs_range_count;
340 while (range_count--)
343 error(
"Expected new range after DBCSRANGE");
351 catch(
const std::invalid_argument& ia)
355 if (!curr_line.empty())
356 error(
"Garbage after DBCS range declaration");
358 if (RangeStart > RangeEnd)
359 error(
"Invalid range specified for DBCSRANGE");
361 FileHeader.
LeadByte[current_range*2] = RangeStart;
362 FileHeader.
LeadByte[current_range*2+1] = RangeEnd;
367 for (
uint8_t LeadByte = RangeStart; LeadByte <= RangeEnd; LeadByte++)
370 error(
"Expected new DBCSTABLE after DBCS range declaration");
373 if (
token !=
"DBCSTABLE")
374 error(
"Expected new DBCSTABLE after DBCS range declaration");
381 catch(
const std::invalid_argument& ia)
386 error(
"DBCSTABLE can't have more than 256 entries");
390 error(
"Expected " + std::to_string(
table_size + 1) +
" more lines after DBCSTABLE token");
400 catch(
const std::invalid_argument& ia)
404 if (!curr_line.empty())
405 error(
"Garbage after DBCSTABLE entry: \"" + curr_line +
"\"");
409 current_offset += 256;
411 lb_offsets[LeadByte] = current_offset;
415 else if (
token ==
"GLYPHTABLE")
422 catch(
const std::invalid_argument& ia)
427 error(
"GLYPHTABLE can only be declared once");
429 error(
"GLYPHTABLE size can't be larger than 256");
430 if (!curr_line.empty())
431 error(
"Garbage after GLYPHTABLE statement: \"" + curr_line +
"\"");
437 error(
"Expected " + std::to_string(
table_size + 1) +
" more lines after GLYPHTABLE token");
447 catch(
const std::invalid_argument& ia)
451 if (!curr_line.empty())
452 error(
"Garbage after GLYPHTABLE entry: \"" + curr_line +
"\"");
453 glyph_table[mb] = wc;
462 if (
token !=
"ENDCODEPAGE")
463 error(
"Expected last token to be \"ENDCODEPAGE\"");
469 error(
"File has no MBTABLE statement");
471 error(
"File has no WCTABLE statement");
476 for(
int i = 0;
i < 256;
i++)
478 if (glyph_table[
i] == 0)
479 glyph_table[
i] = mb_table[
i];
495 error(
"Default MB char is not translatable!");
507 std::ofstream output(
argv[2], std::ios_base::binary);
509 output.write(
reinterpret_cast<char*
>(&FileHeader),
sizeof(FileHeader));
513 + (has_glyphs ? 256 : 0)
515 + (dbcs_range_count ? 256 : 0)
519 output.write(
reinterpret_cast<char*
>(&wc_table_offset),
sizeof(wc_table_offset));
521 output.write(
reinterpret_cast<char*
>(mb_table),
sizeof(mb_table));
523 uint16_t glyph_table_size = has_glyphs ? 256 : 0;
524 output.write(
reinterpret_cast<char*
>(&glyph_table_size),
sizeof(glyph_table_size));
526 output.write(
reinterpret_cast<char*
>(glyph_table),
sizeof(glyph_table));
528 output.write(
reinterpret_cast<char*
>(&dbcs_range_count),
sizeof(dbcs_range_count));
529 if (dbcs_range_count)
531 output.write(
reinterpret_cast<char*
>(lb_offsets),
sizeof(lb_offsets));
539 output.write(
reinterpret_cast<char*
>(&unknown_flag),
sizeof(unknown_flag));
unsigned short int uint16_t
GLenum GLenum GLenum input
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat token
#define MAXIMUM_LEADBYTES
static std::istream & get_clean_line(std::istream &stream, std::string &str)
static const char whitespaces[]
static void tokenize(std::string &str, std::string &token)