home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 2 / AACD 2.iso / AACD / Programming / jikes-1.02 / src / system.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1999-09-05  |  32.0 KB  |  845 lines

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