home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 20 / AACD20.BIN / AACD / Programming / Jikes / Source / src / system.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2001-03-03  |  36.1 KB  |  951 lines

  1. // $Id: system.cpp,v 1.33 2001/01/10 16:49:45 mdejong 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://www.ibm.com/research/jikes.
  6. // Copyright (C) 1996, 1998, International Business Machines Corporation
  7. // and others.  All Rights Reserved.
  8. // You must accept the terms of that agreement to use this software.
  9. //
  10. #include "platform.h"
  11. #include "control.h"
  12. #include "semantic.h"
  13. #include "zip.h"
  14.  
  15. #ifdef    HAVE_JIKES_NAMESPACE
  16. namespace Jikes {    // Open namespace Jikes block
  17. #endif
  18.  
  19. //
  20. // Convert the null terminated Unicode string source into its Utf8
  21. // representation pointed to by target. The char string target is presumed
  22. // to have been allocated and to be large enough to accomodate the conversion.
  23. //
  24. int Control::ConvertUnicodeToUtf8(wchar_t *source, char *target)
  25. {
  26.     int length = 0;
  27.  
  28.     for (; *source; source++)
  29.     {
  30.         int ch = *source;
  31.  
  32.         if (ch == 0)
  33.         {
  34.              target[length++] = (char) 0xC0;
  35.              target[length++] = (char) 0x80;
  36.         }
  37.         else if (ch <= 0x007F)
  38.              target[length++] = (char) ch;
  39.         else if (ch <= 0x07FF)
  40.         {
  41.              target[length++] = (char) ((char) 0xC0 | (char) ((ch >> 6) & 0x001F)); // bits 6-10
  42.              target[length++] = (char) ((char) 0x80 | (char) (ch & 0x003F));        // bits 0-5
  43.         }
  44.         else
  45.         {
  46.              target[length++] = (char) ((char) 0xE0 | (char) ((ch >> 12) & 0x000F));
  47.              target[length++] = (char) ((char) 0x80 | (char) ((ch >> 6) & 0x003F));
  48.              target[length++] = (char) ((char) 0x80 | (char) (ch & 0x3F));
  49.         }
  50.     }
  51.     target[length] = U_NULL;
  52.  
  53.     return length;
  54. }
  55.  
  56.  
  57. //
  58. // Convert the Utf8 string of length len pointed to by source into its unicode
  59. // representation pointed to by target. The wchar_t string target is presumed
  60. // to have been allocated and to be large enough (at least len + 1) to accomodate
  61. // the conversion.
  62. //
  63. int Control::ConvertUtf8ToUnicode(wchar_t *target, const char *source, int len)
  64. {
  65.     wchar_t *ptr = target;
  66.     for (int i = 0; i < len; i++, ptr++)
  67.     {
  68.         u1 ch = source[i];
  69.  
  70.         if ((ch & 0x80) == 0)
  71.             *ptr = ch;
  72.         else if ((ch & 0xE0) == 0xC0)
  73.         {
  74.             *ptr = ch & 0x1F;
  75.             *ptr <<= 6;
  76.             i++;
  77.             ch = source[i] & 0x3F;
  78.             *ptr += ch;
  79.         }
  80.         else if ((ch & 0xF0) == 0xE0)
  81.         {
  82.             *ptr = ch & 0x0F;
  83.             *ptr <<= 6;
  84.             i++;
  85.             ch = source[i] & 0x3F;
  86.             *ptr += ch;
  87.  
  88.             *ptr <<= 6;
  89.             i++;
  90.             ch = source[i] & 0x3F;
  91.             *ptr += ch;
  92.         }
  93.         else
  94.         {
  95.             assert(! "valid character encoding: chaos, Damn, Caramba, Zut !!!\n");
  96.         }
  97.     }
  98.  
  99.     *ptr = U_NULL;
  100.  
  101.     return (ptr - target);
  102. }
  103.  
  104.  
  105. void Control::FindPathsToDirectory(PackageSymbol *package)
  106. {
  107.     if (package -> directory.Length() == 0)
  108.     {
  109.         PackageSymbol *owner_package = package -> owner;
  110.         if (owner_package) // package is a subpackage?
  111.         {
  112.             for (int i = 0; i < owner_package -> directory.Length(); i++)
  113.             {
  114.                 DirectorySymbol *owner_directory_symbol = owner_package -> directory[i],
  115.                                 *subdirectory_symbol = owner_directory_symbol -> FindDirectorySymbol(package -> Identity());
  116.                 if (! owner_directory_symbol -> IsZip())
  117.                 {
  118.                     if (! subdirectory_symbol)
  119.                     {
  120.                         int length = owner_directory_symbol -> DirectoryNameLength() + package -> Utf8NameLength() + 1; // +1 for '/'
  121.                         char *directory_name = new char[length + 1]; // +1 for '\0';
  122.  
  123.                         strcpy(directory_name, owner_directory_symbol -> DirectoryName());
  124.                         if (owner_directory_symbol -> DirectoryName()[owner_directory_symbol -> DirectoryNameLength() - 1] != U_SLASH)
  125.                             strcat(directory_name, StringConstant::U8S__SL);
  126.                         strcat(directory_name, package -> Utf8Name());
  127.  
  128.                         if (SystemIsDirectory(directory_name))
  129.                             subdirectory_symbol = owner_directory_symbol -> InsertDirectorySymbol(package -> Identity());
  130.  
  131.                         delete [] directory_name;
  132.                     }
  133.  
  134.                     if (subdirectory_symbol)
  135.                         subdirectory_symbol -> ReadDirectory();
  136.                 }
  137.  
  138.                 if (subdirectory_symbol)
  139.                     package -> directory.Next() = subdirectory_symbol;
  140.             }
  141.         }
  142.         else
  143.         {
  144.             //
  145.             // Recall that since classpath[0] contains the default directory, we always
  146.             // start searching at location 1.
  147.             //
  148.             for (int k = 1; k < classpath.Length(); k++)
  149.             {
  150.                 PathSymbol *path_symbol = classpath[k];
  151.                 DirectorySymbol *directory_symbol = path_symbol -> RootDirectory() -> FindDirectorySymbol(package -> Identity());
  152.                 if (! path_symbol -> IsZip())
  153.                 {
  154.                     if (! directory_symbol)
  155.                     {
  156.                         int length = path_symbol -> Utf8NameLength() + package -> Utf8NameLength() + 1; // +1 for '/'
  157.                         char *directory_name = new char[length + 1]; // +1 for '\0'
  158.                         strcpy(directory_name, path_symbol -> Utf8Name());
  159.                         char tail = path_symbol -> Utf8Name()[path_symbol -> Utf8NameLength() - 1];
  160.                         if (tail != U_SLASH && tail != U_BACKSLASH)
  161.                             strcat(directory_name, StringConstant::U8S__SL);
  162.                         strcat(directory_name, package -> Utf8Name());
  163.  
  164.                         if (SystemIsDirectory(directory_name))
  165.                             directory_symbol = path_symbol -> RootDirectory() -> InsertDirectorySymbol(package -> Identity());
  166.                         delete [] directory_name;
  167.                     }
  168.  
  169.                     if (directory_symbol)
  170.                         directory_symbol -> ReadDirectory();
  171.                 }
  172.  
  173.                 if (directory_symbol)
  174.                     package -> directory.Next() = directory_symbol;
  175.             }
  176.         }
  177.     }
  178.  
  179.     return;
  180. }
  181.  
  182.  
  183. void Control::ProcessGlobals()
  184. {
  185.     dot_name_symbol        = FindOrInsertName(US__DO, wcslen(US__DO));
  186.     dot_dot_name_symbol    = FindOrInsertName(US__DO__DO, wcslen(US__DO__DO));
  187.     length_name_symbol     = FindOrInsertName(US_length, wcslen(US_length));
  188.     init_name_symbol       = FindOrInsertName(US__LT_init_GT, wcslen(US__LT_init_GT));
  189.     clinit_name_symbol     = FindOrInsertName(US__LT_clinit_GT, wcslen(US__LT_clinit_GT));
  190.     block_init_name_symbol = FindOrInsertName(US_block_DOLLAR, wcslen(US_block_DOLLAR));
  191.     this0_name_symbol      = FindOrInsertName(US_this0, wcslen(US_this0));
  192.     clone_name_symbol      = FindOrInsertName(US_clone, wcslen(US_clone));
  193.     object_name_symbol     = FindOrInsertName(US_Object, wcslen(US_Object));
  194.     type_name_symbol       = FindOrInsertName(US_TYPE, wcslen(US_TYPE));
  195.     class_name_symbol      = FindOrInsertName(US__class_DOLLAR, wcslen(US__class_DOLLAR));
  196.     toString_name_symbol   = FindOrInsertName(US_toString, wcslen(US_toString));
  197.     append_name_symbol     = FindOrInsertName(US_append, wcslen(US_append));
  198.     forName_name_symbol    = FindOrInsertName(US_forName, wcslen(US_forName));
  199.     getMessage_name_symbol = FindOrInsertName(US_getMessage, wcslen(US_getMessage));
  200.  
  201.     ConstantValue_literal = Utf8_pool.FindOrInsert(U8S_ConstantValue, U8S_ConstantValue_length);
  202.     Exceptions_literal = Utf8_pool.FindOrInsert(U8S_Exceptions, U8S_Exceptions_length);
  203.     InnerClasses_literal = Utf8_pool.FindOrInsert(U8S_InnerClasses, U8S_InnerClasses_length);
  204.     Synthetic_literal = Utf8_pool.FindOrInsert(U8S_Synthetic, U8S_Synthetic_length);
  205.     Deprecated_literal = Utf8_pool.FindOrInsert(U8S_Deprecated, U8S_Deprecated_length);
  206.     LineNumberTable_literal = Utf8_pool.FindOrInsert(U8S_LineNumberTable, U8S_LineNumberTable_length);
  207.     LocalVariableTable_literal = Utf8_pool.FindOrInsert(U8S_LocalVariableTable, U8S_LocalVariableTable_length);
  208.     Code_literal = Utf8_pool.FindOrInsert(U8S_Code, U8S_Code_length);
  209.     Sourcefile_literal = Utf8_pool.FindOrInsert(U8S_Sourcefile, U8S_Sourcefile_length);
  210.  
  211.     null_literal = Utf8_pool.FindOrInsert(U8S_null, U8S_null_length);
  212.     this_literal = Utf8_pool.FindOrInsert(U8S_this, U8S_this_length);
  213.  
  214.     return;
  215. }
  216.  
  217.  
  218. void Control::InitClassInfo()
  219. {
  220.     if (! Class_type -> Bad())
  221.     {
  222.         //
  223.         // Search for relevant forName method
  224.         //
  225.         for (MethodSymbol *method = Class_type -> FindMethodSymbol(forName_name_symbol);
  226.              method;
  227.              method = method -> next_method)
  228.         {
  229.             char *signature = method -> SignatureString();
  230.  
  231.             if (strcmp(signature, StringConstant::U8S_LP_Ljava_SL_lang_SL_String_SC_RP_Ljava_SL_lang_SL_Class_SC) == 0)
  232.             {
  233.                 Class_forName_method = method;
  234.                 break;
  235.             }
  236.         }
  237.  
  238.         if (! Class_forName_method)
  239.         {
  240.             system_semantic -> ReportSemError(SemanticError::NON_STANDARD_LIBRARY_TYPE,
  241.                                               0,
  242.                                               0,
  243.                                               Class_type -> ContainingPackage() -> PackageName(),
  244.                                               Class_type -> ExternalName());
  245.         }
  246.     }
  247.  
  248.     return;
  249. }
  250.  
  251.  
  252. void Control::InitThrowableInfo()
  253. {
  254.     if (! Throwable_type -> Bad())
  255.     {
  256.         //
  257.         // Search for relevant getMessage method
  258.         //
  259.         for (MethodSymbol *method = Throwable_type -> FindMethodSymbol(getMessage_name_symbol);
  260.              method;
  261.              method = method -> next_method)
  262.         {
  263.             char *signature = method -> SignatureString();
  264.  
  265.             if (strcmp(signature, StringConstant::U8S_LP_RP_Ljava_SL_lang_SL_String_SC) == 0)
  266.             {
  267.                 Throwable_getMessage_method = method;
  268.                 break;
  269.             }
  270.         }
  271.  
  272.         if (! Throwable_getMessage_method)
  273.         {
  274.             system_semantic -> ReportSemError(SemanticError::NON_STANDARD_LIBRARY_TYPE,
  275.                                               0,
  276.                                               0,
  277.                                               Throwable_type -> ContainingPackage() -> PackageName(),
  278.                                               Throwable_type -> ExternalName());
  279.         }
  280.     }
  281.  
  282.     return;
  283. }
  284.  
  285.  
  286. void Control::InitNoClassDefFoundErrorInfo()
  287. {
  288.     if (! NoClassDefFoundError_type -> Bad())
  289.     {
  290.         //
  291.         // Search for relevant constructors
  292.         //
  293.         for (MethodSymbol *constructor = NoClassDefFoundError_type -> FindConstructorSymbol();
  294.              constructor;
  295.              constructor = constructor -> next_method)
  296.         {
  297.             char *signature = constructor -> SignatureString();
  298.  
  299.             if (strcmp(signature, StringConstant::U8S_LP_Ljava_SL_lang_SL_String_SC_RP_V) == 0)
  300.                 NoClassDefFoundError_InitWithString_method = constructor;
  301.         }
  302.  
  303.         if (! NoClassDefFoundError_InitWithString_method)
  304.         {
  305.             system_semantic -> ReportSemError(SemanticError::NON_STANDARD_LIBRARY_TYPE,
  306.                                               0,
  307.                                               0,
  308.                                               NoClassDefFoundError_type -> ContainingPackage() -> PackageName(),
  309.                                               NoClassDefFoundError_type -> ExternalName());
  310.         }
  311.     }
  312.  
  313.     return;
  314. }
  315.  
  316.  
  317. void Control::InitStringBufferInfo()
  318. {
  319.     if (! StringBuffer_type -> Bad())
  320.     {
  321.         //
  322.         // Search for relevant constructors
  323.         //
  324.         for (MethodSymbol *constructor = StringBuffer_type -> FindConstructorSymbol();
  325.              constructor;
  326.              constructor = constructor -> next_method)
  327.         {
  328.             char *signature = constructor -> SignatureString();
  329.  
  330.             if (strcmp(signature, StringConstant::U8S_LP_RP_V) == 0)
  331.                  StringBuffer_Init_method = constructor;
  332.             else if (strcmp(signature, StringConstant::U8S_LP_Ljava_SL_lang_SL_String_SC_RP_V) == 0)
  333.                  StringBuffer_InitWithString_method = constructor;
  334.         }
  335.  
  336.         //
  337.         // Search for relevant toString method
  338.         //
  339.         for (MethodSymbol *toString_method = StringBuffer_type -> FindMethodSymbol(toString_name_symbol);
  340.              toString_method;
  341.              toString_method = toString_method -> next_method)
  342.         {
  343.             if (strcmp(toString_method -> SignatureString(), StringConstant::U8S_LP_RP_Ljava_SL_lang_SL_String_SC) == 0)
  344.             {
  345.                 StringBuffer_toString_method = toString_method;
  346.                 break;
  347.             }
  348.         }
  349.  
  350.         //
  351.         // Search for relevant append method
  352.         //
  353.         for (MethodSymbol *append_method = StringBuffer_type -> FindMethodSymbol(append_name_symbol);
  354.              append_method;
  355.              append_method = append_method -> next_method)
  356.         {
  357.             char *signature = append_method -> SignatureString();
  358.  
  359.             if (strcmp(signature, StringConstant::U8S_LP_LB_C_RP_Ljava_SL_lang_SL_StringBuffer_SC) == 0)
  360.                  StringBuffer_append_char_array_method = append_method;
  361.             else if (strcmp(signature, StringConstant::U8S_LP_C_RP_Ljava_SL_lang_SL_StringBuffer_SC) == 0)
  362.                  StringBuffer_append_char_method = append_method;
  363.             else if (strcmp(signature, StringConstant::U8S_LP_Z_RP_Ljava_SL_lang_SL_StringBuffer_SC) == 0)
  364.                  StringBuffer_append_boolean_method = append_method;
  365.             else if (strcmp(signature, StringConstant::U8S_LP_I_RP_Ljava_SL_lang_SL_StringBuffer_SC) == 0)
  366.                  StringBuffer_append_int_method = append_method;
  367.             else if (strcmp(signature, StringConstant::U8S_LP_J_RP_Ljava_SL_lang_SL_StringBuffer_SC) == 0)
  368.                  StringBuffer_append_long_method = append_method;
  369.             else if (strcmp(signature, StringConstant::U8S_LP_F_RP_Ljava_SL_lang_SL_StringBuffer_SC) == 0)
  370.                  StringBuffer_append_float_method = append_method;
  371.             else if (strcmp(signature, StringConstant::U8S_LP_D_RP_Ljava_SL_lang_SL_StringBuffer_SC) == 0)
  372.                  StringBuffer_append_double_method = append_method;
  373.             else if (strcmp(signature, StringConstant::U8S_LP_Ljava_SL_lang_SL_String_SC_RP_Ljava_SL_lang_SL_StringBuffer_SC) == 0)
  374.                  StringBuffer_append_string_method = append_method;
  375.             else if (strcmp(signature, StringConstant::U8S_LP_Ljava_SL_lang_SL_Object_SC_RP_Ljava_SL_lang_SL_StringBuffer_SC) == 0)
  376.                  StringBuffer_append_object_method = append_method;
  377.         }
  378.  
  379.         if (! (StringBuffer_Init_method &&
  380.                StringBuffer_InitWithString_method &&
  381.                StringBuffer_toString_method &&
  382.                StringBuffer_append_char_array_method &&
  383.                StringBuffer_append_char_method &&
  384.                StringBuffer_append_boolean_method &&
  385.                StringBuffer_append_int_method &&
  386.                StringBuffer_append_long_method &&
  387.                StringBuffer_append_float_method &&
  388.                StringBuffer_append_double_method &&
  389.                StringBuffer_append_string_method &&
  390.                StringBuffer_append_object_method))
  391.         {
  392.             system_semantic -> ReportSemError(SemanticError::NON_STANDARD_LIBRARY_TYPE,
  393.                                               0,
  394.                                               0,
  395.                                               StringBuffer_type -> ContainingPackage() -> PackageName(),
  396.                                               StringBuffer_type -> ExternalName());
  397.         }
  398.     }
  399.  
  400.     return;
  401. }
  402.  
  403.  
  404. //
  405. // Create the unnamed package and set up global names.
  406. //
  407. void Control::ProcessUnnamedPackage()
  408. {
  409.     unnamed_package = external_table.InsertPackageSymbol(FindOrInsertName(US_EMPTY, wcslen(US_EMPTY)), NULL);
  410.  
  411.     //
  412.     // Create an entry for no_type. no_type is used primarily to signal an error
  413.     //
  414.     no_type = unnamed_package -> InsertSystemTypeSymbol(FindOrInsertName(US__QU__QU, wcslen(US__QU__QU)));
  415.     no_type -> SetSignature(Utf8_pool.FindOrInsert(U8S__DO, strlen(U8S__DO))); // give it some signature...
  416.     no_type -> outermost_type = no_type;
  417.     no_type -> SetOwner(unnamed_package);
  418.     no_type -> MarkBad();
  419.  
  420.     //
  421.     // Create an entry for the null type.
  422.     //
  423.     null_type = unnamed_package -> InsertSystemTypeSymbol(FindOrInsertName(US_null, wcslen(US_null)));
  424.     null_type -> outermost_type = null_type;
  425.     null_type -> SetOwner(unnamed_package);
  426.     null_type -> SetACC_PUBLIC();
  427.  
  428.     return;
  429. }
  430.  
  431.  
  432. void Control::ProcessPath()
  433. {
  434. #if defined(UNIX_FILE_SYSTEM) || defined(AMIGAOS_FILE_SYSTEM)
  435.     NameSymbol *dot_path_name_symbol = dot_name_symbol;
  436.  
  437.     //
  438.     // We need a place to start. Allocate a "." directory with no owner initially. (Hence, the null argument.)
  439.     // Allocate a "." path whose associated directory is the "." directory.
  440.     // Identify the "." path as the owner of the "." directory.
  441.     //
  442.     DirectorySymbol *default_directory = new DirectorySymbol(dot_name_symbol, NULL);
  443.     classpath.Next() = classpath_table.InsertPathSymbol(dot_path_name_symbol, default_directory);
  444.     default_directory -> ReadDirectory(); // Note that the default_directory is reset after it has been assigned the owner above.
  445.     system_directories.Next() = default_directory;
  446.  
  447.     system_table = new SystemTable();
  448.     struct stat status;
  449.     //FIXME: need to check for stat errors
  450.     if ((SystemStat(dot_name_symbol -> Utf8Name(), &status) == 0) && (status.st_mode & JIKES_STAT_S_IFDIR))
  451.         system_table -> InsertDirectorySymbol(status.st_dev, status.st_ino, default_directory);
  452.  
  453. #elif defined(WIN32_FILE_SYSTEM)
  454.  
  455.     char *main_current_directory = option.GetMainCurrentDirectory();
  456.     int dot_path_name_length = strlen(main_current_directory);
  457.     wchar_t *dot_path_name = new wchar_t[dot_path_name_length + 1];
  458.     for (int i = 0; i < dot_path_name_length; i++)
  459.         dot_path_name[i] = main_current_directory[i];
  460.     dot_path_name[dot_path_name_length] = U_NULL;
  461.     NameSymbol *dot_path_name_symbol = FindOrInsertName(dot_path_name, dot_path_name_length);
  462.     delete [] dot_path_name;
  463.  
  464.     //
  465.     // We need a place to start. Allocate a "." directory with no owner initially. (Hence, the null argument.)
  466.     // Allocate a "." path whose associated directory is the "." directory.
  467.     // Identify the "." path as the owner of the "." directory.
  468.     //
  469.     DirectorySymbol *default_directory = new DirectorySymbol(dot_name_symbol, NULL);
  470.     classpath.Next() = classpath_table.InsertPathSymbol(dot_path_name_symbol, default_directory);
  471.     default_directory -> ReadDirectory(); // Note that the default_directory is reset after it has been assigned the owner above.
  472.     system_directories.Next() = default_directory;
  473. #endif
  474.  
  475.     //
  476.     //
  477.     //
  478.     if (option.classpath)
  479.     {
  480.         int max_path_name_length = strlen(option.classpath) + 1; // The longest possible path name we can encounter
  481.         wchar_t *path_name = new wchar_t[max_path_name_length + 1]; // +1 for '\0'
  482.  
  483.         wchar_t *input_name = NULL;
  484. #ifdef WIN32_FILE_SYSTEM
  485.         char * full_directory_name = NULL;
  486. #endif
  487.  
  488.         for (char *path = option.classpath, *path_tail = &path[strlen(path)]; path < path_tail; path++)
  489.         {
  490. #ifdef WIN32_FILE_SYSTEM
  491.             delete [] full_directory_name;
  492.             delete [] input_name;
  493. #endif
  494.             char *head;
  495.             for (head = path; path < path_tail && *path != PathSeparator(); path++)
  496.                 ;
  497.             *path = U_NULL; // If a seperator was encountered, replace it by \0 to terminate the string.
  498.             int input_name_length = path - head;
  499.  
  500.             int path_name_length = input_name_length;
  501.             for (int i = 0; i < path_name_length; i++)
  502.                 path_name[i] = head[i];
  503.             path_name[path_name_length] = U_NULL;
  504.  
  505. #if defined(UNIX_FILE_SYSTEM) || defined(AMIGAOS_FILE_SYSTEM)
  506.  
  507.             input_name = path_name;
  508.  
  509. #elif defined(WIN32_FILE_SYSTEM)
  510.  
  511.             input_name = NULL;
  512.             full_directory_name = NULL;
  513.             char disk = (input_name_length >= 2 && Case::IsAsciiAlpha(head[0]) && head[1] == U_COLON ? head[0] : 0);
  514.  
  515.             //
  516.             // Look for the directory. If it is found, update input_name and head.
  517.             //
  518.             option.SaveCurrentDirectoryOnDisk(disk);
  519.             if (SetCurrentDirectory(head))
  520.             {
  521.                 char tmp[1];
  522.                 DWORD directory_length = GetCurrentDirectory(0, tmp); // first, get the right size
  523.                 full_directory_name = new char[directory_length + 1];  // allocate the directory
  524.                 DWORD length = GetCurrentDirectory(directory_length, full_directory_name);
  525.                 if (length <= directory_length)
  526.                 {
  527.                     for (char *ptr = full_directory_name; *ptr; ptr++)
  528.                         *ptr = (*ptr != U_BACKSLASH ? *ptr : (char) U_SLASH); // turn '\' to '/'.
  529.  
  530.                     input_name_length = length;
  531.                     input_name = new wchar_t[input_name_length + 1];
  532.                     for (int k = 0; k < input_name_length; k++)
  533.                         input_name[k] = full_directory_name[k];
  534.                     input_name[input_name_length] = U_NULL;
  535.                     head = full_directory_name;
  536.                 }
  537.             }
  538.  
  539.             //
  540.             // Default input_name, in case we do not succeed in finding the directory
  541.             //
  542.             if (! input_name)
  543.             {
  544.                 input_name = new wchar_t[input_name_length + 1];
  545.                 for (int j = 0; j < input_name_length; j++)
  546.                     input_name[j] = path_name[j];
  547.                 input_name[input_name_length] = U_NULL;
  548.             }
  549.  
  550.             option.ResetCurrentDirectoryOnDisk(disk); // reset the current directory on disk
  551.             option.SetMainCurrentDirectory();         // reset the real current directory...
  552. #endif
  553.  
  554.             //
  555.             //
  556.             //
  557.             if (input_name_length > 0)
  558.             {
  559.                 NameSymbol *name_symbol = FindOrInsertName(path_name, path_name_length);
  560.  
  561.                 //
  562.                 // If a directory is specified more than once, ignore the duplicates.
  563.                 //
  564.                 if (classpath_table.FindPathSymbol(name_symbol))
  565.                 {
  566.                     if (name_symbol == dot_name_symbol)
  567.                     {
  568.                         dot_classpath_index = classpath.Length(); // The next index
  569.                         classpath.Next() = classpath[0];          // share the "." directory
  570.                         unnamed_package -> directory.Next() = classpath[0] -> RootDirectory();
  571.                     }
  572.  
  573.                     continue;
  574.                 }
  575.  
  576.                 //
  577.                 // Check whether or not the path points to a system directory. If not, assume it's a zip file
  578.                 //
  579.                 if (SystemIsDirectory(head))
  580.                 {
  581.                     DirectorySymbol *dot_directory = ProcessSubdirectories(input_name, input_name_length);
  582.                     unnamed_package -> directory.Next() = dot_directory;
  583.                     classpath.Next() = classpath_table.InsertPathSymbol(name_symbol, dot_directory);
  584.                 }
  585.                 else
  586.                 {
  587.                     Zip *zipinfo = new Zip(*this, head);
  588.                     if (! zipinfo -> IsValid()) // If the zipfile is all screwed up, give up here !!!
  589.                     {
  590.                         wchar_t *name = new wchar_t[input_name_length + 1];
  591.                         for (int i = 0; i < input_name_length; i++)
  592.                             name[i] = input_name[i];
  593.                         name[input_name_length] = U_NULL;
  594.                         bad_zip_filenames.Next() = name;
  595.                     }
  596.  
  597.                     unnamed_package -> directory.Next() = zipinfo -> RootDirectory();
  598.  
  599.                     //
  600.                     // Create the new path symbol and update the class path with it.
  601.                     //
  602.                     PathSymbol *path_symbol = classpath_table.InsertPathSymbol(name_symbol, zipinfo -> RootDirectory());
  603.                     path_symbol -> zipfile = zipinfo;
  604.                     classpath.Next() = path_symbol;
  605.                 }
  606.             }
  607.         }
  608.  
  609. #ifdef WIN32_FILE_SYSTEM
  610.         delete [] full_directory_name;
  611.         delete [] input_name;
  612. #endif
  613.  
  614.         delete [] path_name;
  615.     }
  616.  
  617.     //
  618.     // TODO: If the user did not specify "." in the class path we assume it.
  619.     // javac makes that assumption also. Is that correct?
  620.     //
  621.     if (dot_classpath_index == 0)
  622.         unnamed_package -> directory.Next() = classpath[0] -> RootDirectory();
  623.  
  624.     return;
  625. }
  626.  
  627.  
  628. TypeSymbol *Control::GetPrimitiveType(wchar_t *name, char *signature)
  629. {
  630.     NameSymbol *name_symbol = FindOrInsertName(name, wcslen(name));
  631.     TypeSymbol *type = unnamed_package -> InsertSystemTypeSymbol(name_symbol);
  632.  
  633.     type -> SetSignature(Utf8_pool.FindOrInsert(signature, strlen(signature)));
  634.     type -> outermost_type = type;
  635.     type -> SetOwner(unnamed_package);
  636.     type -> SetACC_PUBLIC();
  637.     type -> MarkPrimitive();
  638.  
  639.     return type;
  640. }
  641.  
  642.  
  643. void Control::ProcessSystemInformation()
  644. {
  645.     //
  646.     // Add entry for system package
  647.     //
  648.     system_package = ProcessPackage(StringConstant::US_java_SL_lang);
  649.     java_util_package = ProcessPackage(StringConstant::US_java_SL_util);
  650.  
  651.     //
  652.     // Create an entry for each primitive type. Note that the type void is treated as a primitive.
  653.     //
  654.     void_type = GetPrimitiveType(US_void, U8S_V);
  655.     boolean_type = GetPrimitiveType(US_boolean, U8S_Z);
  656.     byte_type = GetPrimitiveType(US_byte, U8S_B);
  657.     char_type = GetPrimitiveType(US_char, U8S_C);
  658.     short_type = GetPrimitiveType(US_short, U8S_S);
  659.     int_type = GetPrimitiveType(US_int, U8S_I);
  660.     long_type = GetPrimitiveType(US_long, U8S_J);
  661.     float_type = GetPrimitiveType(US_float, U8S_F);
  662.     double_type = GetPrimitiveType(US_double, U8S_D);
  663.  
  664.     return;
  665. }
  666.  
  667.  
  668. DirectorySymbol *Control::GetOutputDirectory(FileSymbol *file_symbol)
  669. {
  670.     DirectorySymbol *directory_symbol;
  671.  
  672.     // A FileSymbol for a .class file has a NULL semantic    
  673.     if (file_symbol -> semantic == NULL ||
  674.         (file_symbol -> semantic -> control).option.directory == NULL) {
  675.         directory_symbol = file_symbol -> directory_symbol;
  676.     }
  677.     else
  678.     {
  679.         Control &control = file_symbol -> semantic -> control;
  680.         char *directory_prefix = control.option.directory;
  681.         int directory_prefix_length = strlen(directory_prefix),
  682.             utf8_name_length = file_symbol -> package -> PackageNameLength() * 3,
  683.             estimated_length = directory_prefix_length + utf8_name_length + 1; // +1 for slash
  684.  
  685.         char *directory_name = new char[estimated_length + 1]; // +1 for '\0'
  686.  
  687.         strcpy(directory_name, directory_prefix);
  688.  
  689.         if (file_symbol -> package != control.unnamed_package) // if there was a package declaration, then...
  690.         {
  691.             if (directory_prefix[directory_prefix_length - 1] != U_SLASH)
  692.                 strcat(directory_name, StringConstant::U8S__SL);
  693.             char *utf8_name = new char[utf8_name_length + 1];
  694.             (void) ConvertUnicodeToUtf8(file_symbol -> package -> PackageName(), utf8_name);
  695.             strcat(directory_name, utf8_name);
  696.             delete [] utf8_name;
  697.  
  698.             if (! SystemIsDirectory(directory_name)) // The directory does not yet exist.
  699.             {
  700.                 for (char *ptr = &directory_name[directory_prefix_length + 1]; *ptr; ptr++)
  701.                 {
  702.                     if (*ptr == U_SLASH) // all the slashes in a package_name are forward slashes
  703.                     {
  704.                         *ptr = U_NULL;
  705.                         if (! SystemIsDirectory(directory_name))
  706.                             SystemMkdir(directory_name);
  707.                         *ptr = U_SLASH; // restore slash
  708.                     }
  709.                 }
  710.                 SystemMkdir(directory_name);
  711.             }
  712.         }
  713.  
  714.         //
  715.         // Read the directory and insert the directory symbol. Note that since
  716.         // the original length computation was an estimate, we compute the real
  717.         // length here.
  718.         //
  719.         int length = strlen(directory_name);
  720.         wchar_t *name = new wchar_t[length + 1];
  721.         for (int i = 0; i < length; i++)
  722.             name[i] = directory_name[i];
  723.         name[length] = U_NULL;
  724.  
  725.         directory_symbol = control.ProcessSubdirectories(name, length);
  726.  
  727.         delete [] name;
  728.         delete [] directory_name;
  729.     }
  730.  
  731.     return directory_symbol;
  732. }
  733.  
  734.  
  735. FileSymbol *Control::GetJavaFile(PackageSymbol *package, NameSymbol *name_symbol)
  736. {
  737.     FileSymbol *file_symbol = NULL;
  738.  
  739.     //
  740.     //
  741.     //
  742.     int length = name_symbol -> Utf8NameLength() + FileSymbol::java_suffix_length;
  743.     char *full_filename = new char[length + 1]; // +1 for \0
  744.     strcpy(full_filename, name_symbol -> Utf8Name());
  745.     strcat(full_filename, FileSymbol::java_suffix);
  746.  
  747.     DirectoryEntry *entry = NULL;
  748.     DirectorySymbol *directory_symbol = NULL;
  749.     for (int k = 0; k < package -> directory.Length(); k++)
  750.     {
  751.         directory_symbol = package -> directory[k];
  752.         if ((entry = directory_symbol -> FindEntry(full_filename, length)))
  753.             break;
  754.     }
  755.  
  756.     if (entry)
  757.     {
  758.         PathSymbol *path_symbol = directory_symbol -> PathSym();
  759.  
  760.         file_symbol = directory_symbol -> FindFileSymbol(name_symbol);
  761.         if (! ((file_symbol && file_symbol -> IsJava()) || path_symbol -> IsZip()))
  762.         {
  763.             file_symbol = directory_symbol -> InsertFileSymbol(name_symbol);
  764.  
  765.             file_symbol -> directory_symbol = directory_symbol;
  766.             file_symbol -> SetJava();
  767.             file_symbol -> mtime = entry -> Mtime();
  768.         }
  769.     }
  770.  
  771.     delete [] full_filename;
  772.  
  773.     return file_symbol;
  774. }
  775.  
  776.  
  777. FileSymbol *Control::GetFile(Control &control, PackageSymbol *package, NameSymbol *name_symbol)
  778. {
  779.     return control.option.old_classpath_search_order                           
  780.             ?    GetFileFirst(control, package, name_symbol)                   
  781.             :    GetFileBoth(control, package, name_symbol);     
  782. }
  783.  
  784. FileSymbol *Control::GetFileBoth(Control &control, PackageSymbol *package, NameSymbol *name_symbol)
  785. {
  786.     FileSymbol *java_file_symbol = NULL, *class_file_symbol = NULL;
  787.  
  788.     //
  789.     // calculate a length that is large enough...
  790.     //
  791.     int class_length = name_symbol -> Utf8NameLength() + FileSymbol::class_suffix_length,
  792.     java_length = name_symbol -> Utf8NameLength() + FileSymbol::java_suffix_length;
  793.  
  794.     char *class_name = new char[class_length + 1]; // +1 for \0
  795.     strcpy(class_name, name_symbol -> Utf8Name());
  796.     strcat(class_name, FileSymbol::class_suffix);
  797.  
  798.     char *java_name = new char[java_length + 1]; // +1 for \0
  799.     strcpy(java_name, name_symbol -> Utf8Name());
  800.     strcat(java_name, FileSymbol::java_suffix);
  801.  
  802.     for (int k = 0; k < package -> directory.Length(); k++)
  803.     {
  804.         DirectorySymbol *directory_symbol = package -> directory[k];
  805.         bool foundBothEntries = false;
  806.         FileSymbol *file_symbol = directory_symbol -> FindFileSymbol(name_symbol);
  807.         if (! file_symbol)
  808.         {
  809.             PathSymbol *path_symbol = directory_symbol -> PathSym();
  810.             if (! path_symbol -> IsZip())
  811.             {
  812.                 DirectoryEntry *java_entry = directory_symbol -> FindEntry(java_name, java_length),
  813.                 *class_entry = (((! control.option.depend) || (java_entry == NULL))
  814.                                 ? directory_symbol -> FindEntry(class_name, class_length)
  815.                                 : (DirectoryEntry *) NULL);
  816.  
  817.                 if (java_entry || class_entry)
  818.                 {
  819.                     file_symbol = directory_symbol -> InsertFileSymbol(name_symbol);
  820.                     file_symbol -> directory_symbol = directory_symbol;
  821.  
  822.                     if (java_entry && ((! class_entry) || class_entry -> Mtime() < java_entry -> Mtime()))
  823.                     {
  824.                         file_symbol -> SetJava();
  825.                         file_symbol -> mtime = java_entry -> Mtime();
  826.                     }
  827.                     else
  828.                     {
  829.                         if (java_entry)
  830.                             file_symbol -> SetClass();
  831.                         else file_symbol -> SetClassOnly();
  832.                         file_symbol -> mtime = class_entry -> Mtime();
  833.                     }
  834.                 }
  835.  
  836.                 if (java_entry && class_entry)
  837.                     foundBothEntries = true; // flag case where both .java and class found in same path
  838.             }
  839.         }
  840.  
  841.         if (file_symbol)
  842.         {
  843.             if (file_symbol -> IsJava() && ! java_file_symbol)
  844.                 java_file_symbol = file_symbol; // if no .java file seen yet, note this one
  845.             else if (! class_file_symbol)
  846.                 class_file_symbol = file_symbol; // if no .class file seen yet, note this one
  847.  
  848.  
  849.             if (foundBothEntries == true || (java_file_symbol && class_file_symbol))
  850.                 break;      // both .java and .class seen, so no point in continuing the search
  851.         }
  852.     }
  853.  
  854.     delete [] java_name;
  855.     delete [] class_name;
  856.  
  857.     //
  858.     // If both .java and .class seen, do a mod time check to decide which one to deliver.
  859.     // Otherwise just return whichever kind we found, or NULL.
  860.     //
  861.     if (java_file_symbol && ((! class_file_symbol) || class_file_symbol -> mtime < java_file_symbol -> mtime))
  862.         return java_file_symbol;
  863.     else
  864.         return class_file_symbol;
  865. }
  866.  
  867. FileSymbol *Control::GetFileFirst(Control &control, PackageSymbol *package, NameSymbol *name_symbol)
  868. {
  869.     FileSymbol *file_symbol = NULL;
  870.  
  871.     //
  872.     // calculate a length that is large enough...
  873.     //
  874.     int class_length = name_symbol -> Utf8NameLength() + FileSymbol::class_suffix_length,
  875.         java_length = name_symbol -> Utf8NameLength() + FileSymbol::java_suffix_length;
  876.  
  877.     char *class_name = new char[class_length + 1]; // +1 for \0
  878.     strcpy(class_name, name_symbol -> Utf8Name());
  879.     strcat(class_name, FileSymbol::class_suffix);
  880.  
  881.     char *java_name = new char[java_length + 1]; // +1 for \0
  882.     strcpy(java_name, name_symbol -> Utf8Name());
  883.     strcat(java_name, FileSymbol::java_suffix);
  884.  
  885.     for (int k = 0; k < package -> directory.Length(); k++)
  886.     {
  887.         DirectorySymbol *directory_symbol = package -> directory[k];
  888.         file_symbol = directory_symbol -> FindFileSymbol(name_symbol);
  889.         if (file_symbol)
  890.              break;
  891.  
  892.         PathSymbol *path_symbol = directory_symbol -> PathSym();
  893.         if (! path_symbol -> IsZip())
  894.         {
  895.             DirectoryEntry *java_entry = directory_symbol -> FindEntry(java_name, java_length),
  896.                            *class_entry = (((! control.option.depend) || (java_entry == NULL))
  897.                                                                        ? directory_symbol -> FindEntry(class_name, class_length)
  898.                                                                        : (DirectoryEntry *) NULL);
  899.  
  900.             if (java_entry || class_entry)
  901.             {
  902.                 file_symbol = directory_symbol -> InsertFileSymbol(name_symbol);
  903.                 file_symbol -> directory_symbol = directory_symbol;
  904.  
  905.                 if (java_entry && ((! class_entry) || class_entry -> Mtime() < java_entry -> Mtime()))
  906.                 {
  907.                     file_symbol -> SetJava();
  908.                     file_symbol -> mtime = java_entry -> Mtime();
  909.                 }
  910.                 else
  911.                 {
  912.                     if (java_entry)
  913.                          file_symbol -> SetClass();
  914.                     else file_symbol -> SetClassOnly();
  915.                     file_symbol -> mtime = class_entry -> Mtime();
  916.                 }
  917.                 break;
  918.             }
  919.         }
  920.     }
  921.  
  922.     delete [] java_name;
  923.     delete [] class_name;
  924.  
  925.     return file_symbol;
  926. }
  927.  
  928.  
  929.  
  930. TypeSymbol *Control::GetType(PackageSymbol *package, wchar_t *name)
  931. {
  932.     NameSymbol *name_symbol = FindOrInsertName(name, wcslen(name));
  933.     TypeSymbol *type = package -> FindTypeSymbol(name_symbol);
  934.  
  935.     if (! type)
  936.     {
  937.         Control &control = *this;
  938.         FileSymbol *file_symbol = GetFile(control, package, name_symbol);
  939.         type = system_semantic -> ReadType(file_symbol, package, name_symbol, 0);
  940.     }
  941.     else if (type -> SourcePending())
  942.          ProcessHeaders(type -> file_symbol);
  943.  
  944.     return type;
  945. }
  946.  
  947. #ifdef    HAVE_JIKES_NAMESPACE
  948. }            // Close namespace Jikes block
  949. #endif
  950.  
  951.