20#define MAXIMUM_LEADBYTES 12
32static_assert(
sizeof(
NLS_FILE_HEADER) == 26,
"Wrong size for NLS_FILE_HEADER");
44 std::size_t comment_pos =
str.find_first_of(
';');
45 if (comment_pos != std::string::npos)
47 str.erase(comment_pos);
52 if (end_of_line != std::string::npos)
53 str.erase(end_of_line + 1);
58 }
while (
str.empty());
66 if (token_start == std::string::npos)
73 std::size_t token_end =
str.find_first_of(
whitespaces, token_start);
74 if (token_end == std::string::npos)
81 token =
str.substr(token_start, token_end);
93 if ((
val > std::numeric_limits<T>::max()) || (
val < std::numeric_limits<T>::min()))
94 throw std::invalid_argument(
token +
" does not fit range ["
95 + std::to_string(std::numeric_limits<T>::min()) +
":" + std::to_string(std::numeric_limits<T>::max()) +
"]");
102 std::cerr <<
"Error parsing line " <<
line_number <<
": " <<
err << std::endl;
110 std::cerr <<
"Usage: " <<
argv[0] <<
" <txt_in> <nls_out>" << std::endl;
115 if (!
input.is_open())
117 std::cerr <<
"Unable to open " <<
argv[1] << std::endl;
122 memset(&FileHeader, 0,
sizeof(FileHeader));
124 std::string curr_line;
128 std::cerr <<
"ERROR: File is empty" << std::endl;
134 if (
token !=
"CODEPAGE")
135 error(
"expected CODEPAGE, got \"" +
token +
"\" instead");
140 catch(
const std::invalid_argument& ia)
145 if (!curr_line.empty())
146 error(
"Garbage after CODEPAGE statement: \"" + curr_line +
"\"");
150 error(
"Nothing after CODEPAGE statement");
153 if (
token !=
"CPINFO")
154 error(
"Expected CPINFO, got \"" +
token +
"\" instead");
161 catch(
const std::invalid_argument& ia)
166 if (!curr_line.empty())
167 error(
"Garbage after CPINFO statement: \"" + curr_line +
"\"");
169 error(
"Expected 1 or 2 as max char size in CPINFO, got \"" + std::to_string(FileHeader.
MaximumCharacterSize) +
"\" instead");
171 error(
"Default MB character " + std::to_string(FileHeader.
DefaultChar) +
" doesn't fit in a 8-bit value");
174 bool has_mbtable =
false;
177 bool has_wctable =
false;
181 for (
int i = 0;
i < 65536;
i++)
187 for (
int i = 0;
i < 65536;
i++)
196 bool has_glyphs =
false;
203 if (
token ==
"ENDCODEPAGE")
205 if (!curr_line.empty())
206 error(
"Garbage after ENDCODEPAGE statement: \"" + curr_line +
"\"");
209 else if (
token ==
"MBTABLE")
216 catch(
const std::invalid_argument& ia)
221 error(
"MBTABLE can only be declared once");
223 error(
"MBTABLE size can't be larger than 256");
224 if (!curr_line.empty())
225 error(
"Garbage after MBTABLE statement: \"" + curr_line +
"\"");
231 error(
"Expected " + std::to_string(
table_size + 1) +
" more lines after MBTABLE token");
241 catch(
const std::invalid_argument& ia)
245 if (!curr_line.empty())
246 error(
"Garbage after MBTABLE entry: \"" + curr_line +
"\"");
250 else if (
token ==
"WCTABLE")
257 catch(
const std::invalid_argument& ia)
262 error(
"WCTABLE can only be declared once");
263 if (!curr_line.empty())
264 error(
"Garbage after WCTABLE statement: \"" + curr_line +
"\"");
266 error(
"WCTABLE size can't be larger than 65536");
275 error(
"Expected " + std::to_string(
table_size + 1) +
" more lines after WCTABLE token");
285 catch(
const std::invalid_argument& ia)
289 if (!curr_line.empty())
290 error(
"Garbage after WCTABLE entry: \"" + curr_line +
"\"");
300 error(
"Expected " + std::to_string(
table_size + 1) +
" more lines after WCTABLE token");
309 catch(
const std::invalid_argument& ia)
313 if (!curr_line.empty())
314 error(
"Garbage after MBTABLE entry: \"" + curr_line +
"\"");
315 wc_table_dbcs[wc] = mb;
319 else if (
token ==
"DBCSRANGE")
321 if (dbcs_range_count != 0)
322 error(
"DBCSRANGE can only be declared once");
326 tokenize(curr_line, dbcs_range_count);
328 catch(
const std::invalid_argument& ia)
334 if (!curr_line.empty())
335 error(
"Garbage after DBCSRANGE token");
337 std::size_t current_offset = 0;
339 uint16_t range_count = dbcs_range_count;
341 while (range_count--)
344 error(
"Expected new range after DBCSRANGE");
352 catch(
const std::invalid_argument& ia)
356 if (!curr_line.empty())
357 error(
"Garbage after DBCS range declaration");
359 if (RangeStart > RangeEnd)
360 error(
"Invalid range specified for DBCSRANGE");
362 FileHeader.
LeadByte[current_range*2] = RangeStart;
363 FileHeader.
LeadByte[current_range*2+1] = RangeEnd;
368 for (
uint8_t LeadByte = RangeStart; LeadByte <= RangeEnd; LeadByte++)
371 error(
"Expected new DBCSTABLE after DBCS range declaration");
374 if (
token !=
"DBCSTABLE")
375 error(
"Expected new DBCSTABLE after DBCS range declaration");
382 catch(
const std::invalid_argument& ia)
387 error(
"DBCSTABLE can't have more than 256 entries");
391 error(
"Expected " + std::to_string(
table_size + 1) +
" more lines after DBCSTABLE token");
401 catch(
const std::invalid_argument& ia)
405 if (!curr_line.empty())
406 error(
"Garbage after DBCSTABLE entry: \"" + curr_line +
"\"");
410 current_offset += 256;
412 lb_offsets[LeadByte] = current_offset;
416 else if (
token ==
"GLYPHTABLE")
423 catch(
const std::invalid_argument& ia)
428 error(
"GLYPHTABLE can only be declared once");
430 error(
"GLYPHTABLE size can't be larger than 256");
431 if (!curr_line.empty())
432 error(
"Garbage after GLYPHTABLE statement: \"" + curr_line +
"\"");
438 error(
"Expected " + std::to_string(
table_size + 1) +
" more lines after GLYPHTABLE token");
448 catch(
const std::invalid_argument& ia)
452 if (!curr_line.empty())
453 error(
"Garbage after GLYPHTABLE entry: \"" + curr_line +
"\"");
454 glyph_table[mb] = wc;
463 if (
token !=
"ENDCODEPAGE")
464 error(
"Expected last token to be \"ENDCODEPAGE\"");
470 error(
"File has no MBTABLE statement");
472 error(
"File has no WCTABLE statement");
477 for(
int i = 0;
i < 256;
i++)
479 if (glyph_table[
i] == 0)
480 glyph_table[
i] = mb_table[
i];
496 error(
"Default MB char is not translatable!");
508 std::ofstream output(
argv[2], std::ios_base::binary);
510 output.write(
reinterpret_cast<char*
>(&FileHeader),
sizeof(FileHeader));
514 + (has_glyphs ? 256 : 0)
516 + (dbcs_range_count ? 256 : 0)
520 output.write(
reinterpret_cast<char*
>(&wc_table_offset),
sizeof(wc_table_offset));
522 output.write(
reinterpret_cast<char*
>(mb_table),
sizeof(mb_table));
524 uint16_t glyph_table_size = has_glyphs ? 256 : 0;
525 output.write(
reinterpret_cast<char*
>(&glyph_table_size),
sizeof(glyph_table_size));
527 output.write(
reinterpret_cast<char*
>(glyph_table),
sizeof(glyph_table));
529 output.write(
reinterpret_cast<char*
>(&dbcs_range_count),
sizeof(dbcs_range_count));
530 if (dbcs_range_count)
532 output.write(
reinterpret_cast<char*
>(lb_offsets),
sizeof(lb_offsets));
540 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)