1 // $Id: platform.cpp,v 1.47 2004/03/23 14:03:56 ericb Exp $
2 //
3 // This software is subject to the terms of the IBM Jikes Compiler
4 // License Agreement available at the following URL:
5 // http://ibm.com/developerworks/opensource/jikes.
6 // Copyright (C) 2000, 2004 IBM Corporation and others. All Rights Reserved.
7 // You must accept the terms of that agreement to use this software.
8 //
9 //
10 // NOTE: The code for accurate conversions between floating point
11 // and decimal strings, in double.h, double.cpp, platform.h, and
12 // platform.cpp, is adapted from dtoa.c. The original code can be
13 // found at http://netlib2.cs.utk.edu/fp/dtoa.c.
14 //
15 // The code in dtoa.c is copyrighted as follows:
16 //****************************************************************
17 //*
18 //* The author of this software is David M. Gay.
19 //*
20 //* Copyright (c) 1991, 2000, 2001 by Lucent Technologies.
21 //*
22 //* Permission to use, copy, modify, and distribute this software for any
23 //* purpose without fee is hereby granted, provided that this entire notice
24 //* is included in all copies of any software which is or includes a copy
25 //* or modification of this software and in all copies of the supporting
26 //* documentation for such software.
27 //*
28 //* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
29 //* WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY
30 //* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
31 //* OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
32 //*
33 //***************************************************************/
34 //
35 //
36
37 #include "platform.h"
38 #include "long.h"
39 #include "double.h"
40
41 #ifdef HAVE_JIKES_NAMESPACE
42 namespace Jikes { // Open namespace Jikes block
43 #endif
44
45 // Define the PathSeparator() function with the proper
46 // impl for each platform.
47
48 #ifdef HAVE_PATHNAME_STYLE_DOS
PathSeparator()49 char PathSeparator() { return U_SEMICOLON; } // ";"
50 #else
51 char PathSeparator() { return U_COLON; } // ":"
52 #endif // ! HAVE_PATHNAME_STYLE_DOS
53
54
55 // Define the SystemMkdir() function with the proper
56 // impl for each platform.
57
SystemMkdir(char * dirname)58 int SystemMkdir(char* dirname)
59 {
60 #ifdef HAVE_GLIBC_MKDIR
61 return mkdir(dirname, S_IRWXU | S_IRWXG | S_IRWXO);
62 #endif // HAVE_GLIBC_MKDIR
63
64 #ifdef HAVE_LIBC5_MKDIR
65 reteurn mkdir(dirname, S_IRWXU);
66 #endif // HAVE_LIBC5_MKDIR
67
68 #ifdef HAVE_WIN32_MKDIR
69 return mkdir(dirname);
70 #endif // HAVE_WIN32_MKDIR
71
72 #ifdef HAVE_MAC_MKDIR
73 return mkdir(dirname, 0);
74 #endif // HAVE_MAC_MKDIR
75 assert(false);
76 return 0;
77 }
78
79 //
80 // The configure script checks each of these to see if we need our own
81 // implementation.
82 //
83 #ifndef HAVE_WCSLEN
wcslen(const wchar_t * cs)84 size_t wcslen(const wchar_t* cs)
85 {
86 int n = 0;
87 while (*cs++)
88 n++;
89 return n;
90 }
91 #endif // HAVE_WCSLEN
92
93 #ifndef HAVE_WCSCPY
wcscpy(wchar_t * s,const wchar_t * ct)94 wchar_t* wcscpy(wchar_t* s, const wchar_t* ct)
95 {
96 wchar_t* ptr;
97 for (ptr = s; *ct; ptr++, ct++)
98 *ptr = *ct;
99 *ptr = U_NULL;
100 return s;
101 }
102 #endif // HAVE_WCSCPY
103
104 #ifndef HAVE_WCSNCPY
wcsncpy(wchar_t * s,const wchar_t * ct,size_t n)105 wchar_t* wcsncpy(wchar_t* s, const wchar_t* ct, size_t n)
106 {
107 wchar_t* ptr;
108 for (ptr = s; *ct && n-- > 0; ptr++, ct++)
109 *ptr = *ct;
110 while (n-- > 0)
111 *ptr++ = U_NULL;
112 return s;
113 }
114 #endif // HAVE_WCSNCPY
115
116 #ifndef HAVE_WCSCAT
wcscat(wchar_t * s,const wchar_t * ct)117 wchar_t* wcscat(wchar_t* s, const wchar_t* ct)
118 {
119 wchar_t* ptr = s;
120 while (*ptr)
121 ptr++;
122 wcscpy(ptr, ct);
123 return s;
124 }
125 #endif // HAVE_WCSCAT
126
127 #ifndef HAVE_WCSCMP
wcscmp(const wchar_t * cs,const wchar_t * ct)128 int wcscmp(const wchar_t* cs, const wchar_t* ct)
129 {
130 while (*cs == *ct && *cs && *ct)
131 {
132 cs++;
133 ct++;
134 }
135 return (*cs == *ct ? 0 : (*cs < *ct ? -1 : 1));
136 }
137 #endif // HAVE_WCSCMP
138
139 #ifndef HAVE_WCSNCMP
wcsncmp(const wchar_t * cs,const wchar_t * ct,size_t n)140 int wcsncmp(const wchar_t* cs, const wchar_t* ct, size_t n)
141 {
142 while (*cs == *ct && *cs && *ct && n-- > 0)
143 {
144 cs++;
145 ct++;
146 }
147 return (n <= 0 || *cs == *ct ? 0 : (*cs < *ct ? -1 : 1));
148 }
149 #endif // HAVE_WCSNCMP
150
151
152 //
153 // If the system runs out of memory, this function is invoked
154 // This is tricky because VC++ on windows uses a non standard
155 // implementation of the set_new_handler function.
156 //
157 #ifdef HAVE_VCPP_SET_NEW_HANDLER
OutOfMemory(size_t)158 int OutOfMemory(size_t)
159 #else
160 void OutOfMemory()
161 #endif // ! HAVE_VCPP_SET_NEW_HANDLER
162 {
163 fprintf(stderr, "***System Failure: Out of memory\n");
164 exit(1);
165 #ifdef HAVE_VCPP_SET_NEW_HANDLER
166 return 0;
167 #endif // HAVE_VCPP_SET_NEW_HANDLER
168 }
169
SetNewHandler()170 void SetNewHandler()
171 {
172 #ifdef HAVE_VCPP_SET_NEW_HANDLER
173 _set_new_handler(OutOfMemory);
174 #else
175 set_new_handler(OutOfMemory);
176 #endif // ! HAVE_VCPP_SET_NEW_HANDLER
177 }
178
179
180 //
181 // When using the ICC compiler on Win95 or OS/2, we need to disable
182 // testing for various floating point exceptions. Default behavior
183 // was causing problems reading some standard class files.
184 //
185 // We obviously don't need this on AIX (non x86), which uses xlC/ICC
186 //
FloatingPointCheck()187 void FloatingPointCheck()
188 {
189 #ifdef HAVE_ICC_FP_BUGS
190 _control87(EM_UNDERFLOW, EM_UNDERFLOW);
191 _control87(EM_ZERODIVIDE, EM_ZERODIVIDE);
192 _control87(EM_OVERFLOW, EM_OVERFLOW);
193 _control87(EM_INVALID, EM_INVALID);
194 #endif // HAVE_ICC_FP_BUGS
195 }
196
197
198 //
199 // This next set of functions may need some porting to work on various systems
200 //
SystemStat(const char * name,struct stat * stat_struct)201 int SystemStat(const char* name, struct stat* stat_struct)
202 {
203 int result = ::stat(name, stat_struct);
204 #ifdef HAVE_SYS_CYGWIN_H
205 //
206 // Up through cygwin 1.3.10, the hash function which determines inodes
207 // was not strong enough, so java/net and java/nio occasionally get the
208 // same inode without this hack.
209 //
210 if (result == 0)
211 stat_struct -> st_ino += name[strlen(name) - 1];
212 #endif // HAVE_SYS_CYGWIN_H
213 return result;
214 }
215
SystemFopen(const char * name,const char * mode)216 FILE* SystemFopen(const char* name, const char* mode)
217 {
218 return fopen(name, mode);
219 }
220
SystemFread(char * ptr,size_t element_size,size_t count,FILE * stream)221 size_t SystemFread(char* ptr, size_t element_size, size_t count, FILE* stream)
222 {
223 return fread(ptr, element_size, count, stream);
224 }
225
SystemIsDirectory(char * name)226 int SystemIsDirectory(char* name)
227 {
228 struct stat status;
229 return ((SystemStat(name, &status) == 0 &&
230 (status.st_mode & JIKES_STAT_S_IFDIR)) ? 1 : 0);
231 }
232
SystemMkdirhier(char * dirname)233 int SystemMkdirhier(char* dirname)
234 {
235 if (SystemIsDirectory(dirname))
236 return 0;
237
238 for (char* ptr = dirname; *ptr; ptr++)
239 {
240 char delimiter = *ptr;
241 if (delimiter == U_SLASH)
242 {
243 *ptr = U_NULL;
244 if (! SystemIsDirectory(dirname))
245 SystemMkdir(dirname);
246 *ptr = delimiter;
247 }
248 }
249 SystemMkdir(dirname);
250 return (! SystemIsDirectory(dirname));
251 }
252
253
254 // Create the specified directory and also any missing parent directories.
SystemMkdirhierForFile(char * filename)255 int SystemMkdirhierForFile(char* filename)
256 {
257 for (int i = strlen(filename); i >= 0; i--)
258 {
259 if (filename[i] == U_SLASH)
260 {
261 int result = 0;
262 filename[i] = U_NULL;
263 if (! SystemIsDirectory(filename))
264 {
265 Ostream() << "making directory " << filename << "\n";
266 result = SystemMkdirhier(filename);
267 }
268 filename[i] = U_SLASH;
269 return result;
270 }
271 }
272 return 0;
273 }
274
275
276 // FIXME: These next two should definitely be inlined; but when I
277 // add the "inline" keyword , I get linker problems.
278
279
280 // Given three strings, return a newly-allocated string which is their
281 // concatenation.
strcat3(const char * prefix,const char * middle,const char * suffix)282 char* strcat3(const char* prefix, const char* middle, const char* suffix)
283 {
284 int prefix_len = strlen(prefix);
285 int prefix_middle_len = prefix_len + strlen(middle);
286
287 char* result = new char[prefix_middle_len + strlen(suffix) + 1];
288 strcpy(result, prefix);
289 // The below is more efficient than this commented-out code.
290 // strcat(result, middle);
291 // strcat(result, suffix);
292 strcpy(result + prefix_len, middle);
293 strcpy(result + prefix_middle_len, suffix);
294 return result;
295 }
296
297 // It's inconceivable that this is the right way to go about this.
298 // One alternative is to use ConvertUnicodeToUtf8.
wstring2string(wchar_t * in)299 char* wstring2string(wchar_t* in)
300 {
301 char* result = new char[wcslen(in) + 1];
302 result[wcslen(in)] = 0;
303 for (size_t i=0; i<wcslen(in); i++) {
304 wchar_t ch = in[i];
305 result[i] = (ch >> 8 == 0 ? (char)ch : '?');
306 }
307 return result;
308 }
309
310
311 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
312 //
313 // End of platform specific defines in this file, the rest of the code
314 // in this file should work on any system
315 //
316 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
317
318
IntToString(i4 num)319 IntToString::IntToString(i4 num)
320 {
321 str = &info[TAIL_INDEX];
322 *str = U_NULL;
323 u4 n = num < 0 ? - num : num;
324 do
325 {
326 *--str = U_0 + n % 10;
327 n /= 10;
328 } while (n != 0);
329 if (num < 0)
330 *--str = U_MINUS;
331 }
332
IntToString(u4 num,int width)333 IntToString::IntToString(u4 num, int width)
334 {
335 str = &info[width];
336 *str = U_NULL;
337 do
338 {
339 char c = num & 0xf;
340 *--str = c < 10 ? U_0 + c : U_a - 10 + c;
341 num >>= 4;
342 } while (str != info);
343 }
344
345
IntToWstring(i4 num)346 IntToWstring::IntToWstring(i4 num)
347 {
348 wstr = &winfo[TAIL_INDEX];
349 *wstr = U_NULL;
350 u4 n = num < 0 ? - num : num;
351 do
352 {
353 *--wstr = U_0 + n % 10;
354 n /= 10;
355 } while (n != 0);
356 if (num < 0)
357 *--wstr = U_MINUS;
358 }
359
360
LongToString(const LongInt & num)361 LongToString::LongToString(const LongInt& num)
362 {
363 str = &info[TAIL_INDEX];
364 *str = U_NULL;
365 ULongInt n = num < 0 ? (ULongInt) - num : (ULongInt) num;
366 do
367 {
368 *--str = U_0 + (n % 10).LowWord();
369 n /= 10;
370 } while (n != 0);
371 if (num.HighWord() & 0x80000000)
372 *--str = U_MINUS;
373 base = str;
374 }
375
LongToString(const ULongInt & num)376 LongToString::LongToString(const ULongInt& num)
377 {
378 str = &info[TAIL_INDEX];
379 *str = U_NULL;
380 ULongInt n = num;
381 do
382 {
383 *--str = U_0 + (n % 10).LowWord();
384 n /= 10;
385 } while (n != 0);
386 base = str;
387 }
388
LongToString(const BaseLong & num,bool octal)389 LongToString::LongToString(const BaseLong& num, bool octal)
390 {
391 str = &info[TAIL_INDEX];
392 *str = U_NULL;
393 ULongInt value = num;
394 do
395 {
396 char c = value.LowWord() & (octal ? 7 : 0xf);
397 *--str = c < 10 ? U_0 + c : U_a - 10 + c;
398 value >>= (octal ? 3 : 4);
399 } while (value != 0);
400 base = str - 1;
401 if (! octal)
402 *base-- = U_x;
403 *base = U_0;
404 }
405
406
407 //
408 // Convert an double to its character string representation.
409 //
FloatToString(const IEEEfloat & f)410 FloatToString::FloatToString(const IEEEfloat& f)
411 {
412 int bbits, b2, b5, be, i,
413 j, j1, k, m2, m5, s2, s5;
414 bool neg, // f is negative
415 k_check, // need to check if k is near power of ten
416 spec_case, // f is normalized power of two
417 denorm, // f is denormalized
418 round; // round trailing 9's up
419 IEEEfloat fs, f1;
420 char* s;
421 char dig;
422
423 //
424 // Start with exceptional cases: zero, infinity, NaN
425 //
426 neg = f.IsNegative();
427 if (f.IsNaN())
428 {
429 strcpy(str, StringConstant::U8S_NaN);
430 length = strlen(str);
431 return;
432 }
433 else if (f.IsInfinite())
434 {
435 if (neg)
436 strcpy(str, StringConstant::U8S_neg_Infinity);
437 else
438 strcpy(str, StringConstant::U8S_pos_Infinity);
439 length = strlen(str);
440 return;
441 }
442 else if (f.IsZero())
443 {
444 if (neg)
445 strcpy(str, StringConstant::U8S_neg_Zero);
446 else
447 strcpy(str, StringConstant::U8S_pos_Zero);
448 length = strlen(str);
449 return;
450 }
451
452 //
453 // Create BigInt holding f.
454 // bbits = # significant bits in f
455 // be = log2(least significant bit)
456 // i = log2(most significant bit)
457 // f1 = mantissa of f
458 // Therefore, f == f1 * 2**i, and i == be + bbits - 1.
459 //
460 s = str;
461 BigInt b(f, be, bbits);
462 u4 x;
463 i = f.SplitInto(x);
464 f1 = IEEEfloat((i4) x) / (1 << IEEEfloat::FractSize());
465 denorm = i <= -IEEEfloat::Bias();
466 //
467 // log(x) ~=~ log(1.5) + (x-1.5)/1.5
468 // log10(x) = log(x) / log(10)
469 // ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
470 // log10(f) = log10(f1 * 2**i)
471 // = i*log10(2) + log10(f1)
472 //
473 // This suggests computing an approximation k to log10(f) by
474 //
475 // k = i*0.30103 + ( 0.17609125 + (f1-1.5)*0.28952965 );
476 //
477 // We want k to be too large rather than too small.
478 // The error in the first-order Taylor series approximation
479 // is in our favor, so we just round up the constant enough
480 // to compensate for any error in the multiplication of
481 // i by 0.30103; since |i| <= 152,
482 // and 152 * 0.30103 * 2^-23 ~=~ 5.5e-6,
483 // adding 1e-5 to the constant term more than suffices.
484 // Hence we adjust the constant term to 0.1761.
485 // (We could get a more accurate k by invoking log10,
486 // but this is probably not worthwhile.)
487 //
488 fs = IEEEfloat(i) * 0.30103f + 0.1761f + (f1 - 1.5f) * 0.28952965f;
489 k = fs.IntValue();
490 f1 = f.IsNegative() ? -f : f;
491 k_check = true;
492 if (fs < 0 && fs != k)
493 k--;
494 else if (k >= 0 && k <= 10)
495 {
496 if (f1 < IEEEfloat::tens[k])
497 k--;
498 k_check = false;
499 }
500
501 //
502 // We have an integer (no fraction) represented in 24 bits.
503 // For this special case, math on floats has no rounding errors.
504 //
505 if (be >= 0 && k <= 6)
506 {
507 fs = IEEEfloat::tens[k];
508 do
509 {
510 dig = (char) (f1 / fs).IntValue();
511 f1 -= fs * (i4) dig;
512 *s++ = U_0 + dig;
513 } while ((f1 *= 10) != 0);
514 Format(s, k, neg);
515 return;
516 }
517
518 //
519 // Begin work. Find S = 2**s2 * 5**s5, and b adjustment 2**b2 * 5**b5,
520 // that will be needed later on.
521 //
522 if (be <= 0)
523 {
524 b2 = 0;
525 s2 = -be;
526 }
527 else
528 {
529 b2 = be;
530 s2 = 0;
531 }
532 if (k >= 0)
533 {
534 b5 = 0;
535 s5 = k;
536 s2 += k;
537 }
538 else
539 {
540 b2 -= k;
541 b5 = -k;
542 s5 = 0;
543 }
544
545 m2 = b2;
546 m5 = b5;
547 i = denorm ? be + IEEEfloat::Bias() + IEEEfloat::FractSize()
548 : 2 + IEEEfloat::FractSize() - bbits;
549 b2 += i;
550 s2 += i;
551 BigInt mhi(1);
552 if (m2 > 0 && s2 > 0)
553 {
554 i = m2 < s2 ? m2 : s2;
555 b2 -= i;
556 m2 -= i;
557 s2 -= i;
558 }
559 if (b5 > 0)
560 {
561 if (m5 > 0)
562 {
563 mhi.pow5mult(m5);
564 b *= mhi;
565 }
566 if ((j = b5 - m5) != 0)
567 b.pow5mult(j);
568 }
569 BigInt S(1);
570 if (s5 > 0)
571 S.pow5mult(s5);
572 spec_case = false;
573 if (! (f.FractBits()) && f.Exponent())
574 {
575 b2++;
576 s2++;
577 spec_case = true;
578 }
579
580 // Arrange for convenient computation of quotients:
581 // shift left if necessary so divisor has 4 leading 0 bits.
582 //
583 // Perhaps we should just compute leading 28 bits of S once
584 // and for all and pass them and a shift to quorem, so it
585 // can do shifts and ors to compute the numerator for q.
586 //
587 if ((i = ((s5 ? 32 - S.hi0bits() : 1) + s2) & 0x1f) != 0)
588 i = 32 - i;
589 if (i > 4)
590 {
591 i -= 4;
592 b2 += i;
593 m2 += i;
594 s2 += i;
595 }
596 else if (i < 4)
597 {
598 i += 28;
599 b2 += i;
600 m2 += i;
601 s2 += i;
602 }
603 if (b2 > 0)
604 b <<= b2;
605 if (s2 > 0)
606 S <<= s2;
607 if (k_check && b.compareTo(S) < 0)
608 {
609 k--;
610 b *= 10;
611 mhi *= 10;
612 }
613 if (m2 > 0)
614 mhi <<= m2;
615 BigInt mlo(mhi);
616 if (spec_case)
617 mhi = mlo << 1;
618 round = false;
619 while (true)
620 {
621 dig = (char) b.quorem(S) + U_0;
622 //
623 // Do we have the shortest decimal string that will round to f?
624 //
625 j = b.compareTo(mlo);
626 BigInt delta = S - mhi;
627 j1 = delta.IsNegative() ? 1 : b.compareTo(delta);
628 if (j1 == 0 && ! (f.value.word & 1))
629 {
630 if (dig == U_9)
631 round = true;
632 else if (j > 0)
633 dig++;
634 *s++ = dig;
635 break;
636 }
637 if ((j < 0 || j == 0 && ! (f.value.word & 1)) && s != str)
638 {
639 if (! b.IsZero() && j1 > 0)
640 {
641 b <<= 1;
642 j1 = b.compareTo(S);
643 if ((j1 > 0 || j1 == 0 && dig & 1) && dig++ == U_9)
644 {
645 *s++ = U_9;
646 round = true;
647 break;
648 }
649 }
650 *s++ = dig;
651 break;
652 }
653 if (j1 > 0 && s != str)
654 {
655 if (dig == U_9)
656 {
657 *s++ = U_9;
658 round = true;
659 }
660 else
661 *s++ = dig + 1;
662 break;
663 }
664 *s++ = dig;
665 b *= 10;
666 mlo *= 10;
667 mhi *= 10;
668 }
669 if (round)
670 {
671 while (*--s == U_9)
672 if (s == str)
673 {
674 k++;
675 *s = U_0;
676 break;
677 }
678 ++*s++;
679 }
680 Format(s, k, neg);
681 }
682
Format(char * s,int exp,bool neg)683 void FloatToString::Format(char* s, int exp, bool neg)
684 {
685 //
686 // at this point, str contains just the precise digits in the answer,
687 // and s points to the slot just after the last digit
688 //
689 length = s - str + 1; // strlen(str) + '.'
690 bool eneg;
691 int i;
692 switch (exp)
693 {
694 case -3: case -2: case -1:
695 // remove final trailing 0, not needed in this format
696 if (*(s - 1) == U_0)
697 {
698 length--;
699 s--;
700 }
701 s--;
702 // add enough of leading "0.00"
703 length += -exp;
704 do
705 *(s + (neg ? 2 : 1) - exp) = *s;
706 while (s-- != str);
707 for (i = (neg ? 1 : 0); i < (neg ? 2 : 1) - exp; i++)
708 str[i] = U_0;
709 if (neg)
710 str[0] = U_MINUS;
711 str[neg ? 2 : 1] = U_DOT;
712 break;
713 case 0: case 1: case 2: case 3:
714 case 4: case 5: case 6:
715 while (length < exp + 3)
716 // add trailing '0's
717 str[length++ - 1] = U_0;
718 s = &str[length - 2];
719 do
720 *(s + (neg ? 2 : 1)) = *s;
721 while (s-- != str + exp + 1);
722 if (neg)
723 {
724 do
725 *(s + 1) = *s;
726 while (s-- != str);
727 str[0] = U_MINUS;
728 }
729 str[exp + (neg ? 2 : 1)] = U_DOT;
730 break;
731 default:
732 if (length == 2)
733 // add trailing '0', so at least one digit follows '.'
734 str[length++ - 1] = U_0;
735 eneg = exp < 0;
736 if (eneg)
737 {
738 length++; // exponent '-'
739 exp = -exp;
740 }
741 if (exp < 10)
742 length += 2; // 'E' + 1 digit exponent
743 else if (exp < 100)
744 length += 3; // 'E' + 2 digit exponent
745 else
746 assert (! "unexpected exponent");
747 s = &str[length + (neg ? 1 : 0)];
748 do
749 *--s = exp % 10 + U_0;
750 while ((exp /= 10) != 0);
751 if (eneg)
752 *--s = U_MINUS;
753 *--s = U_E;
754 --s;
755 do
756 *s = *(s - (neg ? 2 : 1)); // shift digits right, to add '.'
757 while (--s != str + (neg ? 2 : 1));
758 if (neg)
759 {
760 str[1] = str[0];
761 str[0] = U_MINUS;
762 }
763 str[neg ? 2 : 1] = U_DOT;
764 }
765 if (neg)
766 length++;
767 str[length] = U_NULL;
768 assert(length <= MAXIMUM_STR_LENGTH);
769 }
770
771
772 //
773 // Convert an double to its character string representation.
774 //
DoubleToString(const IEEEdouble & d)775 DoubleToString::DoubleToString(const IEEEdouble& d)
776 {
777 int bbits, b2, b5, be, i,
778 j, j1, k, m2, m5, s2, s5;
779 bool neg, // f is negative
780 k_check, // need to check if k is near power of ten
781 spec_case, // f is normalized power of two
782 denorm, // f is denormalized
783 round; // round trailing 9's up
784 IEEEdouble ds, d1;
785 char* s;
786 char dig;
787
788 //
789 // Start with exceptional cases: zero, infinity, NaN
790 //
791 neg = d.IsNegative();
792 if (d.IsNaN())
793 {
794 strcpy(str, StringConstant::U8S_NaN);
795 length = strlen(str);
796 return;
797 }
798 else if (d.IsInfinite())
799 {
800 if (neg)
801 strcpy(str, StringConstant::U8S_neg_Infinity);
802 else
803 strcpy(str, StringConstant::U8S_pos_Infinity);
804 length = strlen(str);
805 return;
806 }
807 else if (d.IsZero())
808 {
809 if (neg)
810 strcpy(str, StringConstant::U8S_neg_Zero);
811 else
812 strcpy(str, StringConstant::U8S_pos_Zero);
813 length = strlen(str);
814 return;
815 }
816
817 //
818 // Create BigInt holding d.
819 // bbits = # significant bits in d
820 // be = log2(least significant bit)
821 // i = log2(most significant bit)
822 // d1 = mantissa of d
823 // Therefore, d == d1 * 2**i, and i == be + bbits - 1.
824 //
825 s = str;
826 BigInt b(d, be, bbits);
827 LongInt x;
828 i = d.SplitInto(x);
829 d1 = IEEEdouble(x) /
830 IEEEdouble(LongInt(LongInt(1) << IEEEdouble::FractSize()));
831 denorm = i <= -IEEEdouble::Bias();
832 //
833 // log(x) ~=~ log(1.5) + (x-1.5)/1.5
834 // log10(x) = log(x) / log(10)
835 // ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
836 // log10(d) = log10(d2 * 2**i)
837 // = i*log10(2) + log10(d2)
838 //
839 // This suggests computing an approximation k to log10(d) by
840 //
841 // k = i*0.301029995663981
842 // + ( 0.176091259055681 + (d2-1.5)*0.289529654602168 );
843 //
844 // We want k to be too large rather than too small.
845 // The error in the first-order Taylor series approximation
846 // is in our favor, so we just round up the constant enough
847 // to compensate for any error in the multiplication of
848 // i by 0.301029995663981; since |i| <= 1077,
849 // and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
850 // adding 1e-13 to the constant term more than suffices.
851 // Hence we adjust the constant term to 0.1760912590558.
852 // (We could get a more accurate k by invoking log10,
853 // but this is probably not worthwhile.)
854 //
855 ds = IEEEdouble(i) * 0.301029995663981 + 0.1760912590558
856 + (d1 - 1.5) * 0.289529654602168;
857 k = ds.IntValue();
858 d1 = d.IsNegative() ? -d : d;
859 k_check = true;
860 if (ds < 0 && ds != k)
861 k--;
862 else if (k >= 0 && k <= 22)
863 {
864 if (d1 < IEEEdouble::tens[k])
865 k--;
866 k_check = false;
867 }
868
869 //
870 // We have an integer (no fraction) represented in 53 bits.
871 // For this special case, math on doubles has no rounding errors.
872 //
873 if (be >= 0 && k <= 14)
874 {
875 ds = IEEEdouble::tens[k];
876 do
877 {
878 dig = (char) (d1 / ds).IntValue();
879 d1 -= ds * (i4) dig;
880 *s++ = U_0 + dig;
881 } while ((d1 *= 10) != 0);
882 Format(s, k, neg);
883 return;
884 }
885
886 //
887 // Begin work. Find S = 2**s2 * 5**s5, and b adjustment 2**b2 * 5**b5,
888 // that will be needed later on.
889 //
890 if (be <= 0)
891 {
892 b2 = 0;
893 s2 = -be;
894 }
895 else
896 {
897 b2 = be;
898 s2 = 0;
899 }
900 if (k >= 0)
901 {
902 b5 = 0;
903 s5 = k;
904 s2 += k;
905 }
906 else
907 {
908 b2 -= k;
909 b5 = -k;
910 s5 = 0;
911 }
912
913 m2 = b2;
914 m5 = b5;
915 i = denorm ? be + IEEEdouble::Bias() + IEEEdouble::FractSize()
916 : 2 + IEEEdouble::FractSize() - bbits;
917 b2 += i;
918 s2 += i;
919 BigInt mhi(1);
920 if (m2 > 0 && s2 > 0)
921 {
922 i = m2 < s2 ? m2 : s2;
923 b2 -= i;
924 m2 -= i;
925 s2 -= i;
926 }
927 if (b5 > 0)
928 {
929 if (m5 > 0)
930 {
931 mhi.pow5mult(m5);
932 b *= mhi;
933 }
934 if ((j = b5 - m5) != 0)
935 b.pow5mult(j);
936 }
937 BigInt S(1);
938 if (s5 > 0)
939 S.pow5mult(s5);
940 spec_case = false;
941 if (! (d.FractBits()) && d.Exponent())
942 {
943 b2++;
944 s2++;
945 spec_case = true;
946 }
947
948 // Arrange for convenient computation of quotients:
949 // shift left if necessary so divisor has 4 leading 0 bits.
950 //
951 // Perhaps we should just compute leading 28 bits of S once
952 // and for all and pass them and a shift to quorem, so it
953 // can do shifts and ors to compute the numerator for q.
954 //
955 if ((i = ((s5 ? 32 - S.hi0bits() : 1) + s2) & 0x1f) != 0)
956 i = 32 - i;
957 if (i > 4)
958 {
959 i -= 4;
960 b2 += i;
961 m2 += i;
962 s2 += i;
963 }
964 else if (i < 4)
965 {
966 i += 28;
967 b2 += i;
968 m2 += i;
969 s2 += i;
970 }
971 if (b2 > 0)
972 b <<= b2;
973 if (s2 > 0)
974 S <<= s2;
975 if (k_check && b.compareTo(S) < 0)
976 {
977 k--;
978 b *= 10;
979 mhi *= 10;
980 }
981 if (m2 > 0)
982 mhi <<= m2;
983 BigInt mlo(mhi);
984 if (spec_case)
985 mhi = mlo << 1;
986 round = false;
987 while (true)
988 {
989 dig = (char) b.quorem(S) + U_0;
990 //
991 // Do we have the shortest decimal string that will round to d?
992 //
993 j = b.compareTo(mlo);
994 BigInt delta = S - mhi;
995 j1 = delta.IsNegative() ? 1 : b.compareTo(delta);
996 if (j1 == 0 && ! (d.LowWord() & 1))
997 {
998 if (dig == U_9)
999 round = true;
1000 else if (j > 0)
1001 dig++;
1002 *s++ = dig;
1003 break;
1004 }
1005 if ((j < 0 || j == 0 && ! (d.LowWord() & 1)) && s != str)
1006 {
1007 if (! b.IsZero() && j1 > 0)
1008 {
1009 b <<= 1;
1010 j1 = b.compareTo(S);
1011 if ((j1 > 0 || j1 == 0 && dig & 1) && dig++ == U_9)
1012 {
1013 *s++ = U_9;
1014 round = true;
1015 break;
1016 }
1017 }
1018 *s++ = dig;
1019 break;
1020 }
1021 if (j1 > 0 && s != str)
1022 {
1023 if (dig == U_9)
1024 {
1025 *s++ = U_9;
1026 round = true;
1027 }
1028 else
1029 *s++ = dig + 1;
1030 break;
1031 }
1032 *s++ = dig;
1033 b *= 10;
1034 mlo *= 10;
1035 mhi *= 10;
1036 }
1037 if (round)
1038 {
1039 while (*--s == U_9)
1040 if (s == str)
1041 {
1042 k++;
1043 *s = U_0;
1044 break;
1045 }
1046 ++*s++;
1047 }
1048 Format(s, k, neg);
1049 }
1050
Format(char * s,int exp,bool neg)1051 void DoubleToString::Format(char* s, int exp, bool neg)
1052 {
1053 //
1054 // at this point, str contains just the precise digits in the answer,
1055 // and s points to the slot just after the last digit
1056 //
1057 length = s - str + 1; // strlen(str) + '.'
1058 bool eneg;
1059 int i;
1060 switch (exp)
1061 {
1062 case -3: case -2: case -1:
1063 // remove final trailing 0, not needed in this format
1064 if (*(s - 1) == U_0)
1065 {
1066 length--;
1067 s--;
1068 }
1069 s--;
1070 // add enough of leading "0.00"
1071 length += -exp;
1072 do
1073 *(s + (neg ? 2 : 1) - exp) = *s;
1074 while (s-- != str);
1075 for (i = (neg ? 1 : 0); i < (neg ? 2 : 1) - exp; i++)
1076 str[i] = U_0;
1077 if (neg)
1078 str[0] = U_MINUS;
1079 str[neg ? 2 : 1] = U_DOT;
1080 break;
1081 case 0: case 1: case 2: case 3:
1082 case 4: case 5: case 6:
1083 while (length < exp + 3)
1084 // add trailing '0's
1085 str[length++ - 1] = U_0;
1086 s = &str[length - 2];
1087 do
1088 *(s + (neg ? 2 : 1)) = *s;
1089 while (s-- != str + exp + 1);
1090 if (neg)
1091 {
1092 do
1093 *(s + 1) = *s;
1094 while (s-- != str);
1095 str[0] = U_MINUS;
1096 }
1097 str[exp + (neg ? 2 : 1)] = U_DOT;
1098 break;
1099 default:
1100 if (length == 2)
1101 // add trailing '0', so at least one digit follows '.'
1102 str[length++ - 1] = U_0;
1103 eneg = exp < 0;
1104 if (eneg)
1105 {
1106 length++; // exponent '-'
1107 exp = -exp;
1108 }
1109 if (exp < 10)
1110 length += 2; // 'E' + 1 digit exponent
1111 else if (exp < 100)
1112 length += 3; // 'E' + 2 digit exponent
1113 else if (exp < 1000)
1114 length += 4; // 'E' + 3 digit exponent
1115 else
1116 assert (! "unexpected exponent");
1117 s = &str[length + (neg ? 1 : 0)];
1118 do
1119 *--s = exp % 10 + U_0;
1120 while ((exp /= 10) != 0);
1121 if (eneg)
1122 *--s = U_MINUS;
1123 *--s = U_E;
1124 --s;
1125 do
1126 *s = *(s - (neg ? 2 : 1)); // shift digits right, to add '.'
1127 while (--s != str + (neg ? 2 : 1));
1128 if (neg)
1129 {
1130 str[1] = str[0];
1131 str[0] = U_MINUS;
1132 }
1133 str[neg ? 2 : 1] = U_DOT;
1134 }
1135 if (neg)
1136 length++;
1137 str[length] = U_NULL;
1138 assert(length <= MAXIMUM_STR_LENGTH);
1139 }
1140
1141
operator <<(LongInt a)1142 Ostream& Ostream::operator<<(LongInt a)
1143 {
1144 if (os -> flags() & os -> dec)
1145 {
1146 LongToString long_int(a);
1147 *os << long_int.String();
1148 }
1149 else if (os -> flags() & os -> oct)
1150 {
1151 LongToString long_int(a, true);
1152 *os << (os -> flags() & os -> showbase
1153 ? long_int.StringWithBase() : long_int.String());
1154 }
1155 else if (os -> flags() & os -> hex)
1156 {
1157 LongToString long_int(a, false);
1158 *os << (os -> flags() & os -> showbase
1159 ? long_int.StringWithBase() : long_int.String());
1160 }
1161 else
1162 {
1163 os -> flush();
1164 assert(false && "invalid format for printing signed long");
1165 }
1166
1167 return *this;
1168 }
1169
operator <<(ULongInt a)1170 Ostream& Ostream::operator<<(ULongInt a)
1171 {
1172 if (os -> flags() & os -> dec)
1173 {
1174 LongToString ulong_int(a);
1175 *os << ulong_int.String();
1176 }
1177 else if (os -> flags() & os -> oct)
1178 {
1179 LongToString ulong_int(a, true);
1180 *os << (os -> flags() & os -> showbase
1181 ? ulong_int.StringWithBase() : ulong_int.String());
1182 }
1183 else if (os -> flags() & os -> hex)
1184 {
1185 LongToString ulong_int(a, false);
1186 *os << (os -> flags() & os -> showbase
1187 ? ulong_int.StringWithBase() : ulong_int.String());
1188 }
1189 else
1190 {
1191 os -> flush();
1192 assert(false && "invalid format for printing unsigned long");
1193 }
1194
1195 return *this;
1196 }
1197
1198 //
1199 // Punctuation and operators
1200 //
1201 const wchar_t StringConstant::US_AND[] = {U_AM, U_NU}; // L"&"
1202 const wchar_t StringConstant::US_AND_AND[] = {U_AM, U_AM, U_NU}; // L"&&"
1203 const wchar_t StringConstant::US_AND_EQUAL[] = {U_AM, U_EQ, U_NU}; // L"&="
1204 const wchar_t StringConstant::US_AT[] = {U_AT, U_NU}; // L"@"
1205 const wchar_t StringConstant::US_COLON[] = {U_CO, U_NU}; // L":"
1206 const wchar_t StringConstant::US_COMMA[] = {U_CM, U_NU}; // L","
1207 const wchar_t StringConstant::US_DIVIDE[] = {U_SL, U_NU}; // L"/"
1208 const wchar_t StringConstant::US_DIVIDE_EQUAL[] = {U_SL, U_EQ, U_NU}; // L"/="
1209 const wchar_t StringConstant::US_DOT[] = {U_DO, U_NU}; // L"."
1210 const wchar_t StringConstant::US_DOT_DOT_DOT[] = {
1211 U_DO, U_DO, U_DO, U_NU}; // L"..."
1212 const wchar_t StringConstant::US_EMPTY[] = {U_NU}; // L""
1213 const wchar_t StringConstant::US_EOF[] = {U_E, U_O, U_F, U_NU}; // L"EOF"
1214 const wchar_t StringConstant::US_EQUAL[] = {U_EQ, U_NU}; // L"="
1215 const wchar_t StringConstant::US_EQUAL_EQUAL[] = {U_EQ, U_EQ, U_NU}; // L"=="
1216 const wchar_t StringConstant::US_GREATER[] = {U_GT, U_NU}; // L">"
1217 const wchar_t StringConstant::US_GREATER_EQUAL[] = {U_GT, U_EQ, U_NU}; // L">="
1218 const wchar_t StringConstant::US_LBRACE[] = {U_OS, U_NU}; // L"{"
1219 const wchar_t StringConstant::US_LBRACKET[] = {U_LB, U_NU}; // L"["
1220 const wchar_t StringConstant::US_LEFT_SHIFT[] = {U_LT, U_LT, U_NU}; // L"<<"
1221 const wchar_t StringConstant::US_LEFT_SHIFT_EQUAL[] = {
1222 U_LT, U_LT, U_EQ, U_NU}; // L"<<="
1223 const wchar_t StringConstant::US_LESS[] = {U_LT, U_NU}; // L"<"
1224 const wchar_t StringConstant::US_LESS_EQUAL[] = {U_LT, U_EQ, U_NU}; // L"<="
1225 const wchar_t StringConstant::US_LPAREN[] = {U_LP, U_NU}; // L"("
1226 const wchar_t StringConstant::US_MINUS[] = {U_MI, U_NU}; // L"-"
1227 const wchar_t StringConstant::US_MINUS_EQUAL[] = {U_MI, U_EQ, U_NU}; // L"-="
1228 const wchar_t StringConstant::US_MINUS_MINUS[] = {U_MI, U_MI, U_NU}; // L"--"
1229 const wchar_t StringConstant::US_MULTIPLY[] = {U_ST, U_NU}; // L"*"
1230 const wchar_t StringConstant::US_MULTIPLY_EQUAL[] = {
1231 U_ST, U_EQ, U_NU}; // L"*="
1232 const wchar_t StringConstant::US_NOT[] = {U_EX, U_NU}; // L"!"
1233 const wchar_t StringConstant::US_NOT_EQUAL[] = {U_EX, U_EQ, U_NU}; // L"!="
1234 const wchar_t StringConstant::US_OR[] = {U_BA, U_NU}; // L"|"
1235 const wchar_t StringConstant::US_OR_EQUAL[] = {U_BA, U_EQ, U_NU}; // L"|="
1236 const wchar_t StringConstant::US_OR_OR[] = {U_BA, U_BA, U_NU}; // L"||"
1237 const wchar_t StringConstant::US_PLUS[] = {U_PL, U_NU}; // L"+"
1238 const wchar_t StringConstant::US_PLUS_EQUAL[] = {U_PL, U_EQ, U_NU}; // L"+="
1239 const wchar_t StringConstant::US_PLUS_PLUS[] = {U_PL, U_PL, U_NU}; // L"++"
1240 const wchar_t StringConstant::US_QUESTION[] = {U_QU, U_NU}; // L"?"
1241 const wchar_t StringConstant::US_RBRACE[] = {U_CS, U_NU}; // L"}"
1242 const wchar_t StringConstant::US_RBRACKET[] = {U_RB, U_NU}; // L"]"
1243 const wchar_t StringConstant::US_REMAINDER[] = {U_PE, U_NU}; // L"%"
1244 const wchar_t StringConstant::US_REMAINDER_EQUAL[] = {
1245 U_PE, U_EQ, U_NU}; // L"%="
1246 const wchar_t StringConstant::US_RIGHT_SHIFT[] = {U_GT, U_GT, U_NU}; // L">>"
1247 const wchar_t StringConstant::US_RIGHT_SHIFT_EQUAL[] = {
1248 U_GT, U_GT, U_EQ, U_NU}; // L">>="
1249 const wchar_t StringConstant::US_RPAREN[] = {U_RP, U_NU}; // L")"
1250 const wchar_t StringConstant::US_SEMICOLON[] = {U_SC, U_NU}; // L";"
1251 const wchar_t StringConstant::US_TWIDDLE[] = {U_TI, U_NU}; // L"~"
1252 const wchar_t StringConstant::US_UNSIGNED_RIGHT_SHIFT[] = {
1253 U_GT, U_GT, U_GT, U_NU}; // L">>>"
1254 const wchar_t StringConstant::US_UNSIGNED_RIGHT_SHIFT_EQUAL[] = {
1255 U_GT, U_GT, U_GT, U_EQ, U_NU}; // L">>>="
1256 const wchar_t StringConstant::US_XOR[] = {U_CA, U_NU}; // L"^"
1257 const wchar_t StringConstant::US_XOR_EQUAL[] = {U_CA, U_EQ, U_NU}; // L"^="
1258
1259 //
1260 // Common constant pool entries
1261 //
1262 const wchar_t StringConstant::US_DS[] = {U_DS, U_NU}; // L"$"
1263 const wchar_t StringConstant::US_LB_RB[] = {U_LB, U_RB, U_NU}; // L"[]"
1264 const wchar_t StringConstant::US_MI[] = {U_MI, U_NU}; // L"-"
1265 const wchar_t StringConstant::US_SC[] = {U_SC, U_NU}; // L";"
1266 const wchar_t StringConstant::US_SL[] = {U_SL, U_NU}; // L"/"
1267 const wchar_t StringConstant::US_jar[] = {U_j, U_a, U_r, U_NU}; // L"jar"
1268 const wchar_t StringConstant::US_java_SL_io[] = {
1269 U_j, U_a, U_v, U_a, U_SL, U_i, U_o, U_NU}; // L"java/io"
1270 const wchar_t StringConstant::US_java_SL_lang[] = {
1271 U_j, U_a, U_v, U_a, U_SL, U_l, U_a, U_n, U_g, U_NU}; // L"java/lang"
1272 const wchar_t StringConstant::US_java_SL_lang_SL_annotation[] = {
1273 U_j, U_a, U_v, U_a, U_SL, U_l, U_a, U_n, U_g, U_SL,
1274 U_a, U_n, U_n, U_o, U_t, U_a, U_t, U_i, U_o, U_n,
1275 U_NU}; // L"java/lang/annotation"
1276 const wchar_t StringConstant::US_java_SL_util[] = {
1277 U_j, U_a, U_v, U_a, U_SL, U_u, U_t, U_i, U_l, U_NU}; // L"java/util"
1278 const wchar_t StringConstant::US_zip[] = {U_z, U_i, U_p, U_NU}; // L"zip"
1279
1280 //
1281 // Java keywords.
1282 //
1283 const wchar_t StringConstant::US_abstract[] = {
1284 U_a, U_b, U_s, U_t, U_r, U_a, U_c, U_t, U_NU}; // L"abstract"
1285 const wchar_t StringConstant::US_assert[] = {
1286 U_a, U_s, U_s, U_e, U_r, U_t, U_NU}; // L"assert"
1287 const wchar_t StringConstant::US_boolean[] = {
1288 U_b, U_o, U_o, U_l, U_e, U_a, U_n, U_NU}; // L"boolean"
1289 const wchar_t StringConstant::US_break[] = {
1290 U_b, U_r, U_e, U_a, U_k, U_NU}; // L"break"
1291 const wchar_t StringConstant::US_byte[] = {
1292 U_b, U_y, U_t, U_e, U_NU}; // L"byte"
1293 const wchar_t StringConstant::US_case[] = {
1294 U_c, U_a, U_s, U_e, U_NU}; // L"case"
1295 const wchar_t StringConstant::US_catch[] = {
1296 U_c, U_a, U_t, U_c, U_h, U_NU}; // L"catch"
1297 const wchar_t StringConstant::US_char[] = {
1298 U_c, U_h, U_a, U_r, U_NU}; // L"char"
1299 const wchar_t StringConstant::US_class[] = {
1300 U_c, U_l, U_a, U_s, U_s, U_NU}; // L"class"
1301 const wchar_t StringConstant::US_const[] = {
1302 U_c, U_o, U_n, U_s, U_t, U_NU}; // L"const"
1303 const wchar_t StringConstant::US_continue[] = {
1304 U_c, U_o, U_n, U_t, U_i, U_n, U_u, U_e, U_NU}; // L"continue"
1305 const wchar_t StringConstant::US_default[] = {
1306 U_d, U_e, U_f, U_a, U_u, U_l, U_t, U_NU}; // L"default"
1307 const wchar_t StringConstant::US_do[] = {U_d, U_o, U_NU}; // L"do"
1308 const wchar_t StringConstant::US_double[] = {
1309 U_d, U_o, U_u, U_b, U_l, U_e, U_NU}; // L"double"
1310 const wchar_t StringConstant::US_else[] = {
1311 U_e, U_l, U_s, U_e, U_NU}; // L"else"
1312 const wchar_t StringConstant::US_enum[] = {
1313 U_e, U_n, U_u, U_m, U_NU}; // L"enum"
1314 const wchar_t StringConstant::US_extends[] = {
1315 U_e, U_x, U_t, U_e, U_n, U_d, U_s, U_NU}; // L"extends"
1316 const wchar_t StringConstant::US_false[] = {
1317 U_f, U_a, U_l, U_s, U_e, U_NU}; // L"false"
1318 const wchar_t StringConstant::US_final[] = {
1319 U_f, U_i, U_n, U_a, U_l, U_NU}; // L"final"
1320 const wchar_t StringConstant::US_finally[] = {
1321 U_f, U_i, U_n, U_a, U_l, U_l, U_y, U_NU}; // L"finally"
1322 const wchar_t StringConstant::US_float[] = {
1323 U_f, U_l, U_o, U_a, U_t, U_NU}; // L"float"
1324 const wchar_t StringConstant::US_for[] = {U_f, U_o, U_r, U_NU}; // L"for"
1325 const wchar_t StringConstant::US_goto[] = {
1326 U_g, U_o, U_t, U_o, U_NU}; // L"goto"
1327 const wchar_t StringConstant::US_if[] = {U_i, U_f, U_NU}; // L"if"
1328 const wchar_t StringConstant::US_implements[] = {
1329 U_i, U_m, U_p, U_l, U_e, U_m, U_e, U_n, U_t, U_s, U_NU}; // L"implements"
1330 const wchar_t StringConstant::US_import[] = {
1331 U_i, U_m, U_p, U_o, U_r, U_t, U_NU}; // L"import"
1332 const wchar_t StringConstant::US_instanceof[] = {
1333 U_i, U_n, U_s, U_t, U_a, U_n, U_c, U_e, U_o, U_f, U_NU}; // L"instanceof"
1334 const wchar_t StringConstant::US_int[] = {U_i, U_n, U_t, U_NU}; // L"int"
1335 const wchar_t StringConstant::US_interface[] = {
1336 U_i, U_n, U_t, U_e, U_r, U_f, U_a, U_c, U_e, U_NU}; // L"interface"
1337 const wchar_t StringConstant::US_long[] = {
1338 U_l, U_o, U_n, U_g, U_NU}; // L"long"
1339 const wchar_t StringConstant::US_native[] = {
1340 U_n, U_a, U_t, U_i, U_v, U_e, U_NU}; // L"native"
1341 const wchar_t StringConstant::US_new[] = {U_n, U_e, U_w, U_NU}; // L"new"
1342 const wchar_t StringConstant::US_null[] = {
1343 U_n, U_u, U_l, U_l, U_NU}; // L"null"
1344 const wchar_t StringConstant::US_package[] = {
1345 U_p, U_a, U_c, U_k, U_a, U_g, U_e, U_NU}; // L"package"
1346 const wchar_t StringConstant::US_private[] = {
1347 U_p, U_r, U_i, U_v, U_a, U_t, U_e, U_NU}; // L"private"
1348 const wchar_t StringConstant::US_protected[] = {
1349 U_p, U_r, U_o, U_t, U_e, U_c, U_t, U_e, U_d, U_NU}; // L"protected"
1350 const wchar_t StringConstant::US_public[] = {
1351 U_p, U_u, U_b, U_l, U_i, U_c, U_NU}; // L"public"
1352 const wchar_t StringConstant::US_return[] = {
1353 U_r, U_e, U_t, U_u, U_r, U_n, U_NU}; // L"return"
1354 const wchar_t StringConstant::US_short[] = {
1355 U_s, U_h, U_o, U_r, U_t, U_NU}; // L"short"
1356 const wchar_t StringConstant::US_static[] = {
1357 U_s, U_t, U_a, U_t, U_i, U_c, U_NU}; // L"static"
1358 const wchar_t StringConstant::US_strictfp[] = {
1359 U_s, U_t, U_r, U_i, U_c, U_t, U_f, U_p, U_NU}; // L"strictfp"
1360 const wchar_t StringConstant::US_super[] = {
1361 U_s, U_u, U_p, U_e, U_r, U_NU}; // L"super"
1362 const wchar_t StringConstant::US_switch[] = {
1363 U_s, U_w, U_i, U_t, U_c, U_h, U_NU}; // L"switch"
1364 const wchar_t StringConstant::US_synchronized[] = {
1365 U_s, U_y, U_n, U_c, U_h, U_r, U_o, U_n, U_i, U_z, U_e, U_d,
1366 U_NU}; // L"synchronized"
1367 const wchar_t StringConstant::US_this[] = {
1368 U_t, U_h, U_i, U_s, U_NU}; // L"this"
1369 const wchar_t StringConstant::US_throw[] = {
1370 U_t, U_h, U_r, U_o, U_w, U_NU}; // L"throw"
1371 const wchar_t StringConstant::US_throws[] = {
1372 U_t, U_h, U_r, U_o, U_w, U_s, U_NU}; // L"throws"
1373 const wchar_t StringConstant::US_transient[] = {
1374 U_t, U_r, U_a, U_n, U_s, U_i, U_e, U_n, U_t, U_NU}; // L"transient"
1375 const wchar_t StringConstant::US_true[] = {
1376 U_t, U_r, U_u, U_e, U_NU}; // L"true"
1377 const wchar_t StringConstant::US_try[] = {U_t, U_r, U_y, U_NU}; // L"try"
1378 const wchar_t StringConstant::US_void[] = {
1379 U_v, U_o, U_i, U_d, U_NU}; // L"void"
1380 const wchar_t StringConstant::US_volatile[] = {
1381 U_v, U_o, U_l, U_a, U_t, U_i, U_l, U_e, U_NU}; // L"volatile"
1382 const wchar_t StringConstant::US_while[] = {
1383 U_w, U_h, U_i, U_l, U_e, U_NU}; // L"while"
1384
1385 //
1386 // Miscellaneous strings.
1387 //
1388 const char StringConstant::U8S_help_header[] =
1389 "Jikes Compiler - " JIKES_VERSION_STRING
1390 "\nCopyright (C) IBM Corporation 1997-2003, 2004.\n"
1391 "- Licensed Materials - Program Property of IBM - All Rights Reserved.\n";
1392 const char StringConstant::U8S_command_format[] =
1393 "use: jikes [options] [@files] file.java...\n";
1394
1395 //
1396 // Constant pool entries.
1397 //
1398 const char StringConstant::U8S_AnnotationDefault[] = {
1399 U_A, U_n, U_n, U_o, U_t, U_a, U_t, U_i, U_o, U_n,
1400 U_D, U_e, U_f, U_a, U_u, U_l, U_t, U_NU}; // "AnnotationDefault
1401 const char StringConstant::U8S_Code[] = {U_C, U_o, U_d, U_e, U_NU}; // "Code"
1402 const char StringConstant::U8S_ConstantValue[] = {
1403 U_C, U_o, U_n, U_s, U_t, U_a, U_n, U_t,
1404 U_V, U_a, U_l, U_u, U_e, U_NU}; // "ConstantValue"
1405 const char StringConstant::U8S_Deprecated[] = {
1406 U_D, U_e, U_p, U_r, U_e, U_c, U_a, U_t, U_e, U_d, U_NU}; // "Deprecated"
1407 const char StringConstant::U8S_EnclosingMethod[] = {
1408 U_E, U_n, U_c, U_l, U_o, U_s, U_i, U_n, U_g,
1409 U_M, U_e, U_t, U_h, U_o, U_d, U_NU}; // "EnclosingMethod"
1410 const char StringConstant::U8S_Exceptions[] = {
1411 U_E, U_x, U_c, U_e, U_p, U_t, U_i, U_o, U_n, U_s, U_NU}; // "Exceptions"
1412 const char StringConstant::U8S_InnerClasses[] = {
1413 U_I, U_n, U_n, U_e, U_r,
1414 U_C, U_l, U_a, U_s, U_s, U_e, U_s, U_NU}; // "InnerClasses"
1415 const char StringConstant::U8S_LineNumberTable[] = {
1416 U_L, U_i, U_n, U_e, U_N, U_u, U_m, U_b, U_e, U_r,
1417 U_T, U_a, U_b, U_l, U_e, U_NU}; // "LineNumberTable"
1418 const char StringConstant::U8S_LocalVariableTable[] = {
1419 U_L, U_o, U_c, U_a, U_l, U_V, U_a, U_r, U_i, U_a, U_b, U_l, U_e,
1420 U_T, U_a, U_b, U_l, U_e, U_NU}; // "LocalVariableTable"
1421 const char StringConstant::U8S_LocalVariableTypeTable[] = {
1422 U_L, U_o, U_c, U_a, U_l, U_V, U_a, U_r, U_i, U_a, U_b, U_l, U_e,
1423 U_T, U_y, U_p, U_e, U_T, U_a, U_b, U_l, U_e,
1424 U_NU}; // "LocalVariableTypeTable"
1425 const char StringConstant::U8S_RuntimeInvisibleAnnotations[] = {
1426 U_R, U_u, U_n, U_t, U_i, U_m, U_e,
1427 U_I, U_n, U_v, U_i, U_s, U_i, U_b, U_l, U_e,
1428 U_A, U_n, U_n, U_o, U_t, U_a, U_t, U_i, U_o, U_n, U_s,
1429 U_NU}; // 'RuntimeInvisibleAnnotations"
1430 const char StringConstant::U8S_RuntimeVisibleAnnotations[] = {
1431 U_R, U_u, U_n, U_t, U_i, U_m, U_e, U_V, U_i, U_s, U_i, U_b, U_l, U_e,
1432 U_A, U_n, U_n, U_o, U_t, U_a, U_t, U_i, U_o, U_n, U_s,
1433 U_NU}; // 'RuntimeVisibleAnnotations"
1434 const char StringConstant::U8S_RuntimeInvisibleParameterAnnotations[] = {
1435 U_R, U_u, U_n, U_t, U_i, U_m, U_e,
1436 U_I, U_n, U_v, U_i, U_s, U_i, U_b, U_l, U_e,
1437 U_P, U_a, U_r, U_a, U_m, U_e, U_t, U_e, U_r,
1438 U_A, U_n, U_n, U_o, U_t, U_a, U_t, U_i, U_o, U_n, U_s,
1439 U_NU}; // 'RuntimeInvisibleParameterAnnotations"
1440 const char StringConstant::U8S_RuntimeVisibleParameterAnnotations[] = {
1441 U_R, U_u, U_n, U_t, U_i, U_m, U_e, U_V, U_i, U_s, U_i, U_b, U_l, U_e,
1442 U_P, U_a, U_r, U_a, U_m, U_e, U_t, U_e, U_r,
1443 U_A, U_n, U_n, U_o, U_t, U_a, U_t, U_i, U_o, U_n, U_s,
1444 U_NU}; // 'RuntimeVisibleParameterAnnotations"
1445 const char StringConstant::U8S_Signature[] = {
1446 U_S, U_i, U_g, U_n, U_a, U_t, U_u, U_r, U_e, U_NU}; // "Signature"
1447 const char StringConstant::U8S_SourceFile[] = {
1448 U_S, U_o, U_u, U_r, U_c, U_e, U_F, U_i, U_l, U_e, U_NU}; // "SourceFile"
1449 const char StringConstant::U8S_StackMap[] = {
1450 U_S, U_t, U_a, U_c, U_k, U_M, U_a, U_p, U_NU}; // "StackMap"
1451 const char StringConstant::U8S_Synthetic[] = {
1452 U_S, U_y, U_n, U_t, U_h, U_e, U_t, U_i, U_c, U_NU}; // "Synthetic"
1453
1454 //
1455 // ASCII file names.
1456 //
1457 const char StringConstant::U8S_DO_class[] = {
1458 U_DO, U_c, U_l, U_a, U_s, U_s, U_NU}; // ".class"
1459 const char StringConstant::U8S_DO_java[] = {
1460 U_DO, U_j, U_a, U_v, U_a, U_NU}; // ".java"
1461 const char StringConstant::U8S_DO_tok[] = {
1462 U_DO, U_t, U_o, U_k, U_NU}; // ".tok"
1463 const char StringConstant::U8S_DO_u[] = {U_DO, U_u, U_NU}; // ".u"
1464 const char StringConstant::U8S_LP[] = {U_LP, U_NU}; // "("
1465 const char StringConstant::U8S_RP[] = {U_RP, U_NU}; // ")"
1466 const char StringConstant::U8S_SL[] = {U_SL, U_NU}; // "/"
1467
1468 //
1469 // Convert number to string.
1470 //
1471 const char StringConstant::U8S_NaN[] = {U_N, U_a, U_N, U_NU}; // "NaN"
1472 const char StringConstant::U8S_pos_Infinity[] = {
1473 U_I, U_n, U_f, U_i, U_n, U_i, U_t, U_y, U_NU}; // "Infinity"
1474 const char StringConstant::U8S_neg_Infinity[] = {
1475 U_MINUS, U_I, U_n, U_f, U_i, U_n, U_i, U_t, U_y, U_NU}; // "-Infinity"
1476 const char StringConstant::U8S_pos_Zero[] = {U_0, U_DOT, U_0, U_NU}; // "0.0"
1477 const char StringConstant::U8S_neg_Zero[] = {
1478 U_MINUS, U_0, U_DOT, U_0, U_NU}; // "-0.0"
1479
1480 Ostream Coutput;
1481
1482 #ifdef HAVE_JIKES_NAMESPACE
1483 } // Close namespace Jikes block
1484 #endif
1485