Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
ctype.cpp
Go to the documentation of this file.
1
29#include "def.h" // for Def
30#include "diagnostic.h" // for issue_diag()
31#include "loc_exception.h" // for loc_exception
32#include "path.h" // for get_pathname()
33#include "scanner.h" // for scanner
34
35#include <cassert> // for assert()
36#include <cctype> // for isdigit(), ...
37#include <cstdio> // for sprintf()
38#include <cstdlib> // for strtol()
39#include <cstring> // for memset(), strchr()
40#include <fstream> // for ofstream
41#include <locale> // for ctype_base::mask
42
43
44static const char lc_name[] = "LC_CTYPE";
45
46
47static wchar_t
48convert_literal_to_ucs4 (Scanner::token_t& t)
49{
50 if ( t.name.size() < 4 || t.name [0] != '<' || t.name [1] != 'U') {
51 issue_diag (E_CVT, true, &t,
52 "Symbol could not be converted to UCS-4 value"
53 "(literal form should have been <Uxxxxxxxx>)");
54 }
55
56 long w = std::strtol (t.name.substr (2, t.name.size ()).c_str (),
57 0, 16);
58 if (w > _RWSTD_WCHAR_MAX) {
59 // issue_diag intercepted in process_transliteration_statement
60 // but will render -w switch useless; just throw here
61 throw loc_exception ("symbol could not be converted to UCS-4 "
62 "value (value outside wchar_t range)");
63 }
64
65 return wchar_t (w);
66}
67
68
69bool Def::get_n_val (const Scanner::token_t &tok, unsigned char &val)
70{
71 bool got_val = true;
72
73 n_cmap_iter n_cmap_pos;
74
75 switch (tok.token) {
76
78 n_cmap_pos = charmap_.get_n_cmap ().find (tok.name);
79 if (charmap_.get_n_cmap ().end () != n_cmap_pos)
80 val = n_cmap_pos->second;
81 else
82 got_val = false;
83 break;
84
86 if (charmap_.mbcharlen (tok.name) == 1)
87 val = scanner_.convert_escape (tok.name.c_str ());
88 else
89 got_val = false;
90 break;
91
92 default:
93 val = tok.name [0];
94 }
95
96 return got_val;
97}
98
99
100bool Def::get_w_val (const Scanner::token_t &tok, wchar_t &val)
101{
102 bool got_val = true;
103
104 w_cmap_iter w_cmap_pos;
105
106 switch (tok.token) {
107
109 w_cmap_pos = charmap_.get_w_cmap ().find (tok.name);
110 if (charmap_.get_w_cmap ().end () != w_cmap_pos)
111 val = w_cmap_pos->second;
112 else
113 got_val = false;
114 break;
115
117 return charmap_.convert_to_wc ("", tok.name, val);
118
119 default:
120 val = wchar_t (tok.name [0]);
121 }
122
123 return got_val;
124}
125
126
127// process absolute ellipsis
128std::size_t Def::
129process_abs_ellipsis (const Scanner::token_t &nextnext,
130 std::ctype_base::mask m)
131{
132 std::size_t nchars = 0;
133
134 typedef unsigned char UChar;
135
136 // first we need to handle narrow chars if the range is a range
137 // of narrow characters
138 UChar first;
139 UChar last;
140
141 // check to see if the start value is in the narrow map
142 // if it is then we have to add some values to the narrow mask_tab
143 if (get_n_val (next, first) && get_n_val (nextnext, last)) {
144 // both the start value and end value are in the mask table
145 // so add the mask to the narrow table from start value
146 // to end_value. Make sure that start < end
147 if (last < first)
148 issue_diag (E_RANGE, true, &next,
149 "illegal range [%u, %u] in LC_CTYPE definition\n",
150 last, first);
151
152 for (unsigned val = first; val <= last; ++val)
153 ctype_out_.mask_tab [val] |= m;
154
155 nchars += last - first;
156 }
157
158 wchar_t wfirst;
159 wchar_t wlast;
160
161 if (get_w_val (next, wfirst) && get_w_val (nextnext, wlast)) {
162
163 for (wchar_t val = wfirst; val != wlast; ) {
164
165 const mask_iter mask_pos = mask_.find (val);
166
167 if (mask_pos == mask_.end ())
168 mask_.insert (std::make_pair (val, m));
169 else
170 mask_pos->second |= m;
171
172 val = charmap_.increment_wchar (val);
173
174 ++nchars;
175 }
176
177 // now add the end_value
178 mask_iter mask_pos = mask_.find (wlast);
179 if(mask_pos == mask_.end ())
180 mask_.insert (std::make_pair (wlast, m));
181 else {
182 mask_pos->second |= m;
183 }
184 }
185 else {
187 issue_diag (W_RANGE, false,
188 &next, "beginning or endpoint of range "
189 "was not found in the character map; "
190 "ignoring range\n") || warnings_occurred_;
191 }
192
193 next = scanner_.next_token ();
194
195 return nchars;
196}
197
198
199// process hexadecimal symbolic ellipsis, decimal symbolic ellipsis,
200// and double increment hexadecimal symbolic ellipsis
201std::size_t Def::
202process_sym_ellipsis (const std::string& start_sym,
203 const std::string& end_sym,
205 std::ctype_base::mask m)
206{
207 // number of characters in the range
208 std::size_t nchars = 0;
209
210 // first, get the alphabetic beginning of the sym name
211 std::size_t idx = 0;
212 std::string begin;
213
214 const int base =
216 || type == Scanner::tok_dbl_ellipsis ? 16 : 10;
217
218 if (16 == base) {
219 // append all characters until the first hex digit
220 while (idx < start_sym.size () && !std::isxdigit (start_sym [idx]))
221 begin += start_sym [idx++];
222 }
223 else {
224 // append all characters until the first decimal digit
225 while (idx < start_sym.size () && !std::isdigit (start_sym [idx]))
226 begin += start_sym [idx++];
227 }
228
229 std::string num_str; // the numeric portion of the sym name
230
231 // get the numeric portion of the sym_name, this is the portion
232 // that will be different for each sym_name within the ellipsis
233 while (idx < start_sym.size () && start_sym [idx] != '>')
234 num_str += start_sym [idx++];
235
236 std::size_t num_len = num_str.size();
237
238 // convert the numeric string to a long
239
240 unsigned long num = std::strtoul (num_str.c_str(), (char**)0, base);
241
242 // now create the symbolic name
243 char next_num [32];
244 std::string sym_name;
245 do {
246 int len;
247
248 if (16 == base) {
249 len = std::sprintf (next_num, "%lX", num++);
250
251 if (type == Scanner::tok_dbl_ellipsis)
252 num++;
253 }
254 else {
255 len = std::sprintf (next_num, "%lu", num++);
256 }
257
258 sym_name = begin;
259
260 sym_name.append (num_len - len, '0');
261
262 sym_name += next_num;
263 sym_name += '>';
264
265 next.name = sym_name;
266 unsigned char n_val;
267 // if the value is <= UCHARMAX then we will add mask to the
268 // mask_tab table
269 if (get_n_val (next, n_val)) {
270 ctype_out_.mask_tab [n_val] |= m;
271 }
272
273 wchar_t w_val;
274 if (get_w_val (next, w_val)) {
275 // add the mask to the mask map
276 mask_iter mask_pos = mask_.find (w_val);
277 if (mask_pos != mask_.end())
278 mask_pos->second |= m;
279 else {
280 mask_.insert (std::make_pair (w_val, m));
281 }
282 }
283 else {
284 // if the value is not in the charmap
285 // then we cannot continue (???)
286
287 /*
288 warnings_occurred_ =
289 issue_diag (W_SYM, false,
290 &next, "symbolic name %s "
291 "was not found in the character map; "
292 "ignoring character\n", next.name.c_str())
293 || warnings_occurred_;
294 */
295 }
296
297 ++nchars;
298
299 } while (sym_name != end_sym);
300
301 next = scanner_.next_token ();
302
303 return nchars;
304}
305
306
307// process_mask is called from process_ctype when process_ctype reaches
308// a mask defintion (ie. upper, lower, digit). It processes each token
309// until a new line is reached (which designates the end of the mask
310// definition). If the token is a symbolic name then it looks up the name
311// in the cmap map to find the value of the character, otherwise it uses
312// the value of the character and adds the character to the mask map (if
313// the character is not alreay there) with the current mask.
314void Def::
315process_mask (std::ctype_base::mask m, const char *name)
316{
317 issue_diag (I_STAGE, false, 0, "processing %s class\n", name);
318
319 next = scanner_.next_token ();
320
321 Scanner::token_t nextnext = scanner_.next_token ();
322
323 std::size_t nchars = 0;
324
325 typedef unsigned char UChar;
326
327 for ( ; next.token != Scanner::tok_nl; ) {
328
329 switch (nextnext.token) {
330
332
333 // if there are ellipses then include all characters
334 // in between the values that surround the ellipsis
335
336 // the next token will be the end of the range
337 nextnext = scanner_.next_token ();
338 nchars += process_abs_ellipsis (nextnext, m);
339 break;
340 }
341
345
346 const Scanner::token_id id = nextnext.token;
347 // the next token will be the end of the range
348 nextnext = scanner_.next_token ();
349 nchars += process_sym_ellipsis (next.name, nextnext.name, id, m);
350 break;
351 }
352
353 case Scanner::tok_nl:
356
357 UChar n_val;
358 // if the value is <= UCHARMAX then add this mask
359 // to the mask table
360 if (get_n_val (next, n_val)) {
361 ctype_out_.mask_tab [n_val] |= m;
362 ++nchars;
363 }
364
365 wchar_t w_val;
366 if (get_w_val (next, w_val)) {
367 // add the mask to the mask map
368 const mask_iter mask_pos = mask_.find (w_val);
369 if (mask_pos == mask_.end ())
370 mask_.insert (std::make_pair (w_val, m));
371 else {
372 mask_pos->second |= m;
373 }
374
375 ++nchars;
376 }
377 else {
378 // if the value is not in the charmap
379 // then we cannot continue (???)
380 /*
381 warnings_occurred_ =
382 issue_diag (W_SYM, false,
383 &next, "symbolic name %s "
384 "was not found in the character map; "
385 "ignoring character\n", next.name.c_str())
386 || warnings_occurred_;
387 */
388 }
389 next = nextnext;
390
391 break;
392 }
393
394 default: {
395 // the ctype category definition contains non-symbolic characters
396 // the actual value of the characters will be used. This is
397 // unportable
399 issue_diag (W_SYM, false, &next,
400 "non-symbolic character %s found in ctype "
401 "definition.\n", next.name.c_str())
403 if (next.name.size () != 1)
405 issue_diag (W_SYM, false, &next,
406 "non-symbolic character %s in ctype "
407 "definition is longer than one char in "
408 "length. Ignoring character\n",
409 next.name.c_str()) || warnings_occurred_;
410 else {
411 ctype_out_.mask_tab [UChar (next.name [0])] |= m;
412 wchar_t mb_val = wchar_t (UChar (next.name [0]));
413 mask_iter mask_pos = mask_.find (mb_val);
414 if (mask_pos != mask_.end())
415 mask_pos->second |= m;
416 else
417 mask_.insert (std::make_pair (mb_val, m));
418 ++nchars;
419 }
420 next = nextnext;
421 }
422
423 }
424
425 // if we are not at the newline get the next token
426 if (Scanner::tok_nl != next.token)
427 nextnext = scanner_.next_token ();
428 }
429
430 issue_diag (I_STAGE, false, 0,
431 "done processing %s class (%lu characters)\n",
432 name, nchars);
433}
434
435
436// process_upper_lower processes the toupper and tolower ctype categories
437// These categories consist of pairs of characters in the format '(<a>,<b>)'
438void Def::
439process_upper_lower (Scanner::token_id tok)
440{
442
443 const char* const name =
444 Scanner::tok_toupper == tok ? "upper" : "lower";
445
446 issue_diag (I_STAGE, false, 0, "processing ctype to%s map\n", name);
447
448 std::size_t nchars = 0;
449
450 // process the toupper and tolower ctype categories
451
452 next = scanner_.next_token();
453 for (; next.token != Scanner::tok_nl; ) {
454
455 std::string sym, sym2;
456
457 // seperate the symbolic names in the toupper or tolower pair
458 // and place the result in sym and sym2
459 strip_pair(next.name, sym, sym2);
460
461 // first process toupper or tolower for the narrow characters
462 const n_cmap_iter sym1_pos = charmap_.get_n_cmap().find (sym);
463 const n_cmap_iter sym2_pos = charmap_.get_n_cmap().find (sym2);
464 if ( sym1_pos != charmap_.get_n_cmap().end()
465 && sym2_pos != charmap_.get_n_cmap().end()) {
466 if (tok == Scanner::tok_toupper)
467 ctype_out_.toupper_tab [sym1_pos->second] = sym2_pos->second;
468 else
469 ctype_out_.tolower_tab [sym1_pos->second] = sym2_pos->second;
470
471 ++nchars;
472 }
473
474 // now process toupper or tolower fot the wide characters
475 const w_cmap_iter wsym1_pos = charmap_.get_w_cmap().find (sym);
476 const w_cmap_iter wsym2_pos = charmap_.get_w_cmap().find (sym2);
477 if (wsym1_pos == charmap_.get_w_cmap().end ())
479 issue_diag (W_SYM, false, &next,
480 "unknown symbol name %s found in "
481 "%s definition\n", sym.c_str (), lc_name)
483 else if (wsym2_pos == charmap_.get_w_cmap().end())
485 issue_diag (W_SYM, false, &next,
486 "unknown symbol name %s found in "
487 "%s definition\n",
488 sym2.c_str (), lc_name)
490 else {
491 if (tok == Scanner::tok_toupper)
492 upper_.insert (std::make_pair (wsym1_pos->second,
493 wsym2_pos->second));
494 else
495 lower_.insert (std::make_pair (wsym1_pos->second,
496 wsym2_pos->second));
497
498 ++nchars;
499 }
500 next = scanner_.next_token();
501 }
502
503 issue_diag (I_STAGE, false, 0,
504 "done processing to%s map (%lu characters)\n", name, nchars);
505}
506
507
508void Def::
509process_xlit_statement (std::size_t &nchars)
510{
511 // convert the name we have for a symbolic name
512 std::string sym_s (next.name);
513 wchar_t sym_w;
514 try {
515 sym_w = convert_literal_to_ucs4 (next);
516 }
517 catch (loc_exception&) {
518 scanner_.ignore_line ();
519 return;
520 }
521 catch (...) {
522 throw;
523 }
524
525 // add a new element to the transliteration map
526 std::pair<xlit_map_t::iterator, bool> res =
527 xlit_map_.insert (std::make_pair(sym_w, std::list<std::string>()));
528 if (res.second == false) {
529 scanner_.ignore_line ();
530 return;
531 }
532
533 xlit_map_t::iterator& it = res.first;
534 next = scanner_.next_token ();
535 while (next.token != Scanner::tok_nl) {
536
537 switch (next.token) {
539 // convert this symbol to a string with the external encoding
540 w_cmap_iter w_pos = charmap_.get_w_cmap().find (next.name);
541 if (w_pos != charmap_.get_w_cmap().end()) {
542 it->second.push_back(convert_to_ext(w_pos->second));
543 ++nchars;
544 }
545 break;
546 }
547 case Scanner::tok_string: {
548 // for empty names there is no processing
549 if (next.name.size () <= 2)
550 break;
551
552 // convert this symbol or string of symbols to a string
553 // with the external encoding
554
555 std::string enc = convert_string (next.name);
556 if (enc.empty())
557 break;
558 it->second.push_back (enc);
559 ++nchars;
560
561 break;
562 }
563 default:
564 issue_diag (W_SYNTAX, false, &next,
565 "ignoring unexpected token in "
566 "transliteration statement\n");
567 break;
568 }
569
570 next = scanner_.next_token ();
571 }
572
573 // if the transliteration statement contained only symbols undefined in
574 // the character map, dump this balast
575 if (it->second.empty ())
576 xlit_map_.erase (it);
577}
578
579
580void Def::
581process_xlit ()
582{
583 issue_diag (I_STAGE, false, 0, "processing transliteration\n");
584
585 std::size_t nchars = 0;
586
587 // used in processing the include directive
588 int nesting_level = 0;
589 std::list<std::string> file_list;
590
591 while (true) {
592 next = scanner_.next_token ();
593
594 switch (next.token) {
596
597 // extract all file names from the list
598 std::list<std::string> tmp_list;
599 while (next.token != Scanner::tok_nl) {
600 next = scanner_.next_token ();
601 if (next.token == Scanner::tok_string &&
602 next.name.size () > 2)
603 tmp_list.push_back (next.name);
604 }
605
606 // insert this list into the main list - at beginning
607 file_list.insert (file_list.begin (),
608 tmp_list.begin (), tmp_list.end ());
609
610 // get the top of the list
611 std::string fname (file_list.front ());
612 file_list.pop_front ();
613
614 // bump up the nesting level
615 nesting_level++;
616
617 // get the full path for the included file and open it
618 scanner_.open (get_pathname (strip_quotes (fname), next.file));
619
620 // get comment char and escape char;
621 // these informations are stored by the scanner
622 while ((next = scanner_.next_token ()).token
624
625 break;
626 }
628 process_xlit_statement (nchars);
629 break;
630 }
632 if (nesting_level == 0)
633 return;
634
635 // decrement nesting level, close opened file
636 nesting_level--;
637 scanner_.close ();
638
639 // check if the list of files is empty or not
640 if (file_list.empty ())
641 break;
642
643 // if not take the following file and open it
644 std::string fname (file_list.front ());
645 file_list.pop_front ();
646
647 // bump up the nesting level
648 nesting_level++;
649
650 // get the full path for the included file and open it
651 scanner_.open (get_pathname (strip_quotes (fname), next.file));
652
653 // get comment char and escape char;
654 // these informations are stored by the scanner
655 while ((next = scanner_.next_token ()).token
657
658 }
659 default:
660 break;
661 }
662 }
663
664 issue_diag (I_STAGE, false, 0, "done processing transliteration "
665 "(%lu tokens, %lu characters)");
666}
667
668
669void Def::
670process_ctype ()
671{
672 issue_diag (I_STAGE, false, 0, "processing %s section\n", lc_name);
673
674 ctype_def_found_ = true;
675
676 // used in processing the copy/include directive
677 int nesting_level = 0;
678
679 while ((next = scanner_.next_token()).token != Scanner::tok_ctype) {
680
681 switch(next.token) {
682
683 case Scanner::tok_copy: {
684 // when we see the copy directive in the ctype definition we
685 // are going to either create the shared database and create a
686 // symbolic link to it, or we are going to create a symbolic link
687 // to the already existing shared ctype database.
688
689 next = scanner_.next_token();
690 if (next.token != Scanner::tok_string)
691 issue_diag (E_SYNTAX, true, &next,
692 "expected string following \"copy\" directive\n");
693#if !defined (_WIN32) && !defined (__CYGWIN__)
694
695 ctype_symlink_ = true;
696
697 // first lets make sure that the ctype database for this
698 // locale hasn't already been generated
699 ctype_filename_ = output_name_;
700 // strip off the last directory
701 ctype_filename_ = ctype_filename_.substr
702 (0, ctype_filename_.rfind
703 (_RWSTD_PATH_SEP, ctype_filename_.length() - 1) + 1);
704 ctype_filename_ += strip_quotes(next.name);
705 ctype_filename_ += ".ctype.";
706 ctype_filename_ += charmap_.get_charmap_name();
707 std::ifstream f (ctype_filename_.c_str(), std::ios::binary);
708 if (f) {
709 // the database exists so simply create a sym link to it
710 ctype_written_ = true;
711 f.close();
712 continue;
713 }
714
715#endif // !_WIN32 && !__CYGWIN__
716
717 // bump up the nesting level
718 nesting_level++;
719
720 issue_diag (I_STAGE, false, 0, "processing copy directive\n");
721
722 // open the file
723 scanner_.open (get_pathname (strip_quotes (next.name), next.file));
724
725 // get comment char and escape char;
726 // these informations are stored by the scanner
727 while ((next = scanner_.next_token ()).token
729 // the LC_IDENTIFICATION section may also have a
730 // LC_CTYPE token that will mess up the parsing
731 if (next.token == Scanner::tok_ident) {
732 while ((next = scanner_.next_token()).token
733 != Scanner::tok_end );
734 next = scanner_.next_token();
735 }
736 }
737
738 break;
739 }
740 case Scanner::tok_nl:
741 break;
742
744 process_mask (std::ctype_base::upper, "upper");
745 break;
746
748 process_mask (std::ctype_base::lower, "lower");
749 break;
750
752 process_mask (std::ctype_base::alpha, "alpha");
753 break;
754
756 process_mask (std::ctype_base::digit, "digit");
757 break;
758
760 process_mask (std::ctype_base::space, "space");
761 break;
762
764 process_mask (std::ctype_base::cntrl, "cntrl");
765 break;
766
768 process_mask (std::ctype_base::punct, "punct");
769 break;
770
772 process_mask (std::ctype_base::graph, "graph");
773 break;
774
776 process_mask (std::ctype_base::print, "print");
777 break;
778
780 process_mask (std::ctype_base::xdigit, "xdigit");
781 break;
782
784 process_upper_lower (Scanner::tok_toupper);
785 break;
786
788 process_upper_lower (Scanner::tok_tolower);
789 break;
790
792 scanner_.ignore_line();
793 break;
794
796 process_xlit ();
797 break;
798
799 case Scanner::tok_end:
800 next = scanner_.next_token();
801 if (next.token == Scanner::tok_ctype) {
802 // end of ctype block
803 if (nesting_level == 0)
804 return;
805
806 nesting_level--;
807 scanner_.close ();
808 } else
809 issue_diag (E_SYNTAX, true, &next,
810 "wrong section name in END directive\n");
811
812 break;
813
814 default:
815 // ignore locale specific character classes because the c++
816 // library does not make use of them
817 scanner_.ignore_line();
818 break;
819
820 }
821 }
822}
823
824
826write_ctype (std::string dir_name)
827{
828 // dir_name cannot be empty
829 assert (!dir_name.empty());
830
831 if (ctype_filename_.empty ()) {
832 ctype_filename_ = dir_name + _RWSTD_PATH_SEP + lc_name;
833 ctype_symlink_ = false;
834 }
835
836 // if a CTYPE section was not found or ctype info has been already written
837 // in the database
838 if (ctype_def_found_ && !ctype_written_) {
839
840 issue_diag (I_OPENWR, false, 0,
841 "writing %s\n", ctype_filename_.c_str ());
842
843 std::ofstream out (ctype_filename_.c_str(), std::ios::binary);
844 out.exceptions (std::ios::failbit | std::ios::badbit);
845
846 // calculate the offsets for the wchar_t arrays
847 ctype_out_.wtoupper_off = 0;
848 ctype_out_.wtolower_off = unsigned (ctype_out_.wtoupper_off
849 + upper_.size() * sizeof (_RW::__rw_upper_elm));
850 ctype_out_.wmask_off = unsigned (ctype_out_.wtolower_off
851 + lower_.size() * sizeof (_RW::__rw_lower_elm));
852 ctype_out_.wmask_s = unsigned (mask_.size());
853
854 // calculate the offsets for the codeset name string and character
855 // map name string
856 ctype_out_.codeset_off = unsigned (ctype_out_.wmask_off
857 + mask_.size() * sizeof (_RW::__rw_mask_elm));
858 ctype_out_.charmap_off = unsigned (ctype_out_.codeset_off
859 + charmap_.get_code_set_name().size() + 1);
860
861 ctype_out_.mb_cur_max = charmap_.get_mb_cur_max();
862 std::size_t i;
863
864 for (i = 0; i <= UCHAR_MAX; i++) {
865 if(0 == ctype_out_.toupper_tab[i])
866 ctype_out_.toupper_tab[i] = (char)i;
867 if(0 == ctype_out_.tolower_tab[i])
868 ctype_out_.tolower_tab[i] = (char)i;
869 }
870
871 // write the ctype_out structure
872 out.write ((char*)&ctype_out_, sizeof(ctype_out_));
873
874 // print out the wide character arrays
875 for(upper_iter u_pos = upper_.begin(); u_pos != upper_.end(); u_pos++){
876 _RW::__rw_upper_elm elm = {u_pos->first, u_pos->second};
877 out.write((char*)&elm, sizeof(elm));
878 }
879 for(lower_iter l_pos = lower_.begin(); l_pos != lower_.end(); l_pos++){
880 _RW::__rw_lower_elm elm = {l_pos->first, l_pos->second};
881 out.write((char*)&elm, sizeof(elm));
882 }
883 for(mask_iter m_pos = mask_.begin(); m_pos != mask_.end(); m_pos++){
884 _RW::__rw_mask_elm elm = {m_pos->first, m_pos->second};
885 out.write((char*)&elm, sizeof(elm));
886 }
887
888 // write the code_set_name string and charmap string
889 out << charmap_.get_code_set_name() << std::ends
890 << charmap_.get_charmap_name() << std::ends;
891
892 }
893
894#if !defined (_WIN32) && !defined (__CYGWIN__)
895
896 if (ctype_symlink_) {
897
898 std::string xname (ctype_filename_);
899 if (xname [0] != _RWSTD_PATH_SEP) {
900 xname = std::string ("..");
901 xname += _RWSTD_PATH_SEP;
902 xname += ctype_filename_.substr (
903 ctype_filename_.rfind (_RWSTD_PATH_SEP) + 1,
904 ctype_filename_.size ());
905 }
906
907 std::string sname (lc_name);
908 create_symlink (output_name_, xname, sname);
909 return;
910 }
911
912#endif // !_WIN32 && !__CYGWIN__
913
914}
#define m
Definition 17.names.cpp:129
#define i
Definition 17.names.cpp:126
#define t
Definition 17.names.cpp:136
#define nchars
Definition 17.names.cpp:502
#define res
Definition 17.names.cpp:531
#define last
Definition 17.names.cpp:487
#define w
Definition 17.names.cpp:139
#define f
Definition 17.names.cpp:119
#define len
Definition 17.names.cpp:488
#define val
Definition 17.names.cpp:570
#define num
Definition 17.names.cpp:505
const int out
#define assert(expr)
Definition _cassert.h:40
unsigned short wchar_t
#define _RWSTD_PATH_SEP
Definition _config.h:297
bool convert_to_wc(const std::string &, const std::string &, wchar_t &)
Definition charmap.cpp:394
int get_mb_cur_max() const
Definition charmap.h:107
const std::string & get_code_set_name() const
Definition charmap.h:112
const std::map< std::string, unsigned char > & get_n_cmap() const
Definition charmap.h:59
std::string get_charmap_name() const
Definition charmap.cpp:475
const std::map< std::string, wchar_t > & get_w_cmap() const
Definition charmap.h:71
std::size_t mbcharlen(const std::string &) const
Definition charmap.cpp:241
wchar_t increment_wchar(wchar_t) const
Definition charmap.cpp:486
bool warnings_occurred_
Definition def.h:90
void write_ctype(std::string dir_name)
Definition ctype.cpp:826
void open(std::string, char='#', char='\\')
Definition scanner.cpp:142
void close()
Definition scanner.cpp:169
void ignore_line()
Definition scanner.cpp:135
unsigned long convert_escape(const char *, const char **=0, bool=false) const
Definition scanner.cpp:705
token_t next_token()
Definition scanner.cpp:352
@ tok_punct
Definition scanner.h:76
@ tok_cntrl
Definition scanner.h:75
@ tok_tolower
Definition scanner.h:79
@ tok_end
Definition scanner.h:66
@ tok_upper
Definition scanner.h:68
@ tok_sym_name
Definition scanner.h:161
@ tok_blank
Definition scanner.h:78
@ tok_lower
Definition scanner.h:69
@ tok_xdigit
Definition scanner.h:77
@ tok_include
Definition scanner.h:167
@ tok_string
Definition scanner.h:99
@ tok_xlit_start
Definition scanner.h:86
@ tok_space
Definition scanner.h:71
@ tok_print
Definition scanner.h:74
@ tok_digit
Definition scanner.h:70
@ tok_ctype
Definition scanner.h:53
@ tok_copy
Definition scanner.h:166
@ tok_abs_ellipsis
Definition scanner.h:103
@ tok_nl
Definition scanner.h:168
@ tok_char_value
Definition scanner.h:162
@ tok_toupper
Definition scanner.h:80
@ tok_alpha
Definition scanner.h:72
@ tok_xlit_end
Definition scanner.h:87
@ tok_ident
Definition scanner.h:60
@ tok_dec_ellipsis
Definition scanner.h:105
@ tok_graph
Definition scanner.h:73
@ tok_dbl_ellipsis
Definition scanner.h:106
@ tok_hex_ellipsis
Definition scanner.h:104
const char * name
Definition codecvt1.cpp:72
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
@ E_CVT
Definition diagnostic.h:43
@ W_SYM
Definition diagnostic.h:69
@ W_SYNTAX
Definition diagnostic.h:72
@ E_RANGE
Definition diagnostic.h:48
@ I_STAGE
Definition diagnostic.h:81
@ E_SYNTAX
Definition diagnostic.h:49
@ W_RANGE
Definition diagnostic.h:73
#define UCHAR_MAX
Definition limits.h:60
void create_symlink(const std::string &dir, const std::string &xname, const std::string &sname)
Definition path.cpp:75
std::string get_pathname(const std::string &fname, const std::string &other)
Definition path.cpp:129
unsigned char UChar
Definition collate.cpp:122
std::string name
Definition scanner.h:178
token_id token
Definition scanner.h:179
const char * file
Definition scanner.h:186