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