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

  1. // $Id: option.cpp,v 1.12 1999/08/26 15:34:09 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.  
  11. #include <ctype.h>
  12. #include "config.h"
  13. #include "option.h"
  14. #include "javasym.h"
  15. #include "error.h"
  16. #include "case.h"
  17.  
  18. //
  19. //
  20. //
  21. bool ArgumentExpander::ArgumentExpanded(Tuple<char *> &arguments, char *file_name)
  22. {
  23.     struct stat status;
  24.     FILE *afile = fopen(file_name, "r");
  25.     if (afile && (::SystemStat(file_name, &status) == 0))
  26.     {
  27.         char *buffer = new char[status.st_size + 2];
  28.         int file_size = fread(buffer, 1, status.st_size, afile);
  29.         buffer[file_size] = '\n';
  30.         for (int k = 0; k < file_size; k++)
  31.         {
  32.             //
  33.             // isgraph(c) is true if c is any printing character except space.
  34.             //
  35.             while (buffer[k] == U_SPACE || buffer[k] == U_LINE_FEED || buffer[k] == U_CARRIAGE_RETURN)
  36.                 k++;
  37.  
  38.             int n;
  39.             for (n = k + 1; ! (buffer[n] == U_SPACE || buffer[n] == U_LINE_FEED || buffer[n] == U_CARRIAGE_RETURN); n++)
  40.                 ;
  41.             buffer[n] = U_NULL;
  42.             char *str = new char[n - k + 1];
  43.             strcpy(str, &buffer[k]);
  44.             arguments.Next() = str;
  45.             k = n;
  46.         }
  47.         delete [] buffer;
  48.         fclose(afile);
  49.  
  50.         return true;
  51.     }
  52.  
  53.     return false;
  54. }
  55.  
  56.  
  57. ArgumentExpander::ArgumentExpander(int argc_, char *argv_[])
  58. {
  59.     Tuple<char *> arguments(8192);
  60.     for (int i = 0; i < argc_; i++)
  61.     {
  62.         char *argument = argv_[i];
  63.         if (argument[0] != '@' || (! ArgumentExpanded(arguments, argument + 1)))
  64.         {
  65.             char *str = new char[strlen(argument) + 1];
  66.             strcpy(str, argument);
  67.             arguments.Next() = str;
  68.         }
  69.     }
  70.  
  71.     argc = arguments.Length();
  72.     argv = new char*[argc];
  73.  
  74.     for (int k = 0; k < argc; k++)
  75.         argv[k] = arguments[k];
  76.  
  77.     return;
  78. }
  79.  
  80.  
  81. ArgumentExpander::ArgumentExpander(Tuple<char> &line)
  82. {
  83.     Tuple<char *> arguments(8192);
  84.  
  85.     int end = 0;
  86.     do
  87.     {
  88.         for (; end < line.Length() && line[end] == U_SPACE; end++)
  89.             ;
  90.         if (end < line.Length())
  91.         {
  92.             int start = end;
  93.             for (end++; end < line.Length() && line[end] != U_SPACE; end++)
  94.                 ;
  95.             int length = end - start;
  96.             char *argument = new char[length + 1];
  97.             for (int i = 0, k = start; k < end; i++, k++)
  98.                 argument[i] = line[k];
  99.             argument[length] = U_NULL;
  100.  
  101.             if (argument[0] == '@' && ArgumentExpanded(arguments, argument + 1))
  102.                  delete argument;
  103.             else arguments.Next() = argument;
  104.         }
  105.     } while(end < line.Length());
  106.  
  107.     argc = arguments.Length();
  108.     argv = new char*[argc];
  109.  
  110.     for (int k = 0; k < argc; k++)
  111.         argv[k] = arguments[k];
  112.  
  113.     return;
  114. }
  115.  
  116.  
  117. #ifdef WIN32_FILE_SYSTEM
  118. void Option::SaveCurrentDirectoryOnDisk(char c)
  119. {
  120.     if (! current_directory[c])
  121.     {
  122.         char *disk_directory = NULL,
  123.              disk[3] = { c, U_COLON, U_NULL },
  124.              tmp[1];
  125.  
  126.         if (SetCurrentDirectory(disk))
  127.         {
  128.             DWORD directory_length = GetCurrentDirectory(0, tmp);  // first, get the right size
  129.             disk_directory = new char[directory_length + 1];       // allocate the directory
  130.             DWORD length = GetCurrentDirectory(directory_length, disk_directory);
  131.             if (length <= directory_length)
  132.             {
  133.                 for (char *ptr = disk_directory; *ptr; ptr++)
  134.                     *ptr = (*ptr != U_BACKSLASH ? *ptr : (char) U_SLASH); // turn '\' to '/'.
  135.             }
  136.         }
  137.  
  138.         if (! disk_directory)
  139.         {
  140.             disk_directory = new char[2];
  141.             strcpy(disk_directory, StringConstant::U8S__DO);
  142.         }
  143.  
  144.         current_directory[Case::ToAsciiLower(c)] = disk_directory;
  145.         current_directory[Case::ToAsciiUpper(c)] = disk_directory;
  146.     }
  147.  
  148.     return;
  149. }
  150. #endif
  151.  
  152.  
  153. Option::Option(ArgumentExpander &arguments) : default_path(NULL),
  154.                                               classpath(NULL),
  155.                                               makefile_name(NULL),
  156.                                               debug_dump_lex(false),
  157.                                               debug_dump_ast(false),
  158.                                               debug_dump_class(false),
  159.                                               debug_trap_op(0),
  160.                                               applet_author(false),
  161.                                               incremental(false),
  162.                                               makefile(false),
  163.                                               bytecode(true),
  164.                                               full_check(false),
  165.                                               unzip(false),
  166.                                               dump_errors(false),
  167.                                               errors(true),
  168.                                               ascii(false),
  169.                                               comments(false),
  170.                                               pedantic(false),
  171.                                               directory(NULL),
  172.                                               first_file_index(arguments.argc),
  173.                                               one_one(true),
  174.                                               g(false),
  175.                                               nowrite(false),
  176.                                               deprecation(false),
  177.                                               verbose(false),
  178.                                               depend(false),
  179.                                               nowarn(false),
  180.                                               O(false),
  181.                                               zero_defect(false)
  182. {
  183. #ifdef WIN32_FILE_SYSTEM
  184.     for (int j = 0; j < 128; j++)
  185.          current_directory[j] = NULL;
  186.  
  187.     char tmp[1];
  188.     DWORD directory_length = GetCurrentDirectory(0, tmp); // first, get the right size
  189.     char *main_current_directory = new char[directory_length + 1];   // allocate the directory
  190.     DWORD length = GetCurrentDirectory(directory_length, main_current_directory);
  191.     if (length > directory_length)
  192.     {
  193.         delete [] main_current_directory;
  194.         main_current_directory = StringConstant::U8S__DO;
  195.         main_disk = 0;
  196.     }
  197.     else
  198.     {
  199.         for (char *ptr = main_current_directory; *ptr; ptr++)
  200.             *ptr = (*ptr != U_BACKSLASH ? *ptr : (char) U_SLASH); // turn '\' to '/'.
  201.         main_disk = main_current_directory[0]; // the first character
  202.         current_directory[Case::ToAsciiLower(main_disk)] = main_current_directory;
  203.         current_directory[Case::ToAsciiUpper(main_disk)] = main_current_directory;
  204.     }
  205.     current_directory[0] = main_current_directory;
  206. #endif
  207.  
  208.     Tuple<int> filename_index(2048);
  209.  
  210.     for (int i = 1; i < arguments.argc; i++)
  211.     {
  212.         if (arguments.argv[i][0] == '-')
  213.         {
  214.             if (strcmp(arguments.argv[i],"-classpath") == 0 && ((i + 1) < arguments.argc))
  215.             {
  216.                 classpath = arguments.argv[++i];
  217. #ifdef EBCDIC
  218.                 //
  219.                 //  Maintain CLASSPATH in ASCII and translate back to EBCDIC when building file name
  220.                 //
  221.                 for (int k = 0; k < strlen(classpath); k++)
  222.                     classpath[k] = Code::ToASCII(classpath[k]);
  223. #endif
  224.             }
  225.             else if (strcmp(arguments.argv[i], "-depend") == 0)
  226.                  depend = true;
  227.             else if (strcmp(arguments.argv[i],"-verbose") == 0)
  228.                  verbose = true;
  229.             else if (strcmp(arguments.argv[i],"-g") == 0)
  230.                  g = true;
  231.             else if (strcmp(arguments.argv[i], "-O") == 0)
  232.                  O = true;
  233.             else if (strcmp(arguments.argv[i],"-deprecation") == 0)
  234.                  deprecation = true;
  235.             else if (strcmp(arguments.argv[i],"-nowrite") == 0)
  236.                  nowrite = true;
  237.             else if (strcmp(arguments.argv[i],"-nowarn") == 0)
  238.                  nowarn = true;
  239.             else if (strcmp(arguments.argv[i],"-Xstdout") == 0)
  240.                  Coutput.StandardOutput();
  241.             else if (strcmp(arguments.argv[i], "-d") == 0 && ((i + 1) < arguments.argc))
  242.             {
  243.                 ++i;
  244. #if defined(UNIX_FILE_SYSTEM) || defined(AMIGAOS_FILE_SYSTEM)
  245.                 int length = strlen(arguments.argv[i]);
  246.                 directory = new char[length + 1];
  247.                 strcpy(directory, arguments.argv[i]);
  248. #elif defined(WIN32_FILE_SYSTEM)
  249.                 char disk = (strlen(arguments.argv[i]) >= 2 &&
  250.                             Case::IsAsciiAlpha(arguments.argv[i][0]) &&
  251.                             arguments.argv[i][1] == U_COLON
  252.                                      ? arguments.argv[i][0]
  253.                                      : 0);
  254.                 SaveCurrentDirectoryOnDisk(disk);
  255.                 if (SetCurrentDirectory(arguments.argv[i]))
  256.                 {
  257.                     char tmp[1];
  258.                     DWORD directory_length = GetCurrentDirectory(0, tmp); // first, get the right size
  259.                     directory = new char[directory_length + 1]; // allocate the directory
  260.                     DWORD length = GetCurrentDirectory(directory_length, directory);
  261.                     if (length > directory_length)
  262.                     {
  263.                         delete [] directory;
  264.                         directory = NULL;
  265.                     }
  266.                 }
  267.  
  268.                 ResetCurrentDirectoryOnDisk(disk); // reset the current directory on the disk
  269.                 SetMainCurrentDirectory();       // reset the real current directory...
  270.  
  271.                 if (! directory)
  272.                     bad_options.Next() = new OptionError(SemanticError::INVALID_DIRECTORY, arguments.argv[i]);
  273. #endif
  274. #ifdef EBCDIC
  275.                 //
  276.                 // need to translate directory name to ASCII
  277.                 //
  278.                 for (int k = 0; k < directory_length; k++)
  279.                     directory[k] = Code::ToASCII(directory[k]);
  280. #endif
  281.                 if (directory)
  282.                 {
  283.                     for (char *ptr = directory; *ptr; ptr++)
  284.                         *ptr = (*ptr != U_BACKSLASH ? *ptr : (char) U_SLASH); // turn '\' to '/'.
  285.                 }
  286.             }
  287.             else bad_options.Next() = new OptionError(SemanticError::INVALID_OPTION, arguments.argv[i]);
  288.         }
  289.         else if (arguments.argv[i][0] == '+')
  290.         {
  291.             if (strcmp(arguments.argv[i], "+AA") == 0)
  292.                  applet_author = true;
  293.             else if (strcmp(arguments.argv[i], "+A") == 0)
  294.                  debug_dump_ast = true;
  295. #ifdef EBCDIC
  296.             else if (strcmp(arguments.argv[i], "+ASCII") == 0)
  297.                      ascii = true;
  298. #endif
  299.             else if (strcmp(arguments.argv[i], "+B") == 0)
  300.                  bytecode = false;
  301.             else if (strcmp(arguments.argv[i], "+c") == 0)
  302.                  comments = true;
  303.             else if (strcmp(arguments.argv[i], "+C") == 0)
  304.                  debug_dump_class = true;
  305.             else if (strcmp(arguments.argv[i],"+D") == 0)
  306.             {
  307.                  dump_errors = true;
  308.                  errors = false;
  309.             }
  310.             else if (strcmp(arguments.argv[i],"+E") == 0)
  311.                  errors = false;
  312.             else if (arguments.argv[i][0] == '+' && arguments.argv[i][1] == 'K')
  313.             {
  314.                 char *name = arguments.argv[i] + 2,
  315.                      *image;
  316.                 for (image = name; *image && *image != '='; image++)
  317.                     ;
  318.  
  319.                 if (*image != '=')
  320.                     bad_options.Next() = new OptionError(SemanticError::INVALID_K_OPTION, arguments.argv[i]);
  321.                 else
  322.                 {
  323.                     int key = 0; // assume undefined
  324.                     image++;
  325.  
  326.                     if (strcmp(image, "boolean") == 0)
  327.                          key = TK_boolean;
  328.                     else if (strcmp(image, "byte") == 0)
  329.                          key = TK_byte;
  330.                     else if (strcmp(image, "char") == 0)
  331.                          key = TK_char;
  332.                     else if (strcmp(image, "short") == 0)
  333.                          key = TK_short;
  334.                     else if (strcmp(image, "int") == 0)
  335.                          key = TK_int;
  336.                     else if (strcmp(image, "long") == 0)
  337.                          key = TK_long;
  338.                     else if (strcmp(image, "float") == 0)
  339.                          key = TK_float;
  340.                     else if (strcmp(image, "double") == 0)
  341.                          key = TK_double;
  342.                     else bad_options.Next() = new OptionError(SemanticError::INVALID_K_TARGET, image);
  343.  
  344.                     if (key != 0)
  345.                     {
  346.                         int i = keyword_map.NextIndex();
  347.                         keyword_map[i].key = key;
  348.                         keyword_map[i].length = image - name - 1;
  349.                         keyword_map[i].name = new wchar_t[keyword_map[i].length];
  350.                         for (int k = 0; k < keyword_map[i].length; k++)
  351.                             keyword_map[i].name[k] = name[k];
  352.                     }
  353.                 }
  354.             }
  355.             else if (strcmp(arguments.argv[i],"+1.0") == 0)
  356.                  one_one = false;
  357.             else if (strcmp(arguments.argv[i],"+F") == 0)
  358.                  full_check = true;
  359.             else if (strcmp(arguments.argv[i],"+M") == 0)
  360.             {
  361.                  makefile = true;
  362.                  full_check = true;
  363.             }
  364.             else if (strncmp(arguments.argv[i], "+M=", 3) == 0)
  365.             {
  366.                  makefile = true;
  367.                  full_check = true;
  368.                  makefile_name = &arguments.argv[i][3];
  369.             }
  370.             else if (strcmp(arguments.argv[i], "+O") == 0)
  371.             {
  372.                  debug_trap_op = atoi(arguments.argv[i + 1]);
  373.                  i++;
  374.             }
  375.             else if (strcmp(arguments.argv[i],"+P") == 0)
  376.                  pedantic = true;
  377.             else if (arguments.argv[i][0] == U_PLUS && arguments.argv[i][1] == U_T)
  378.             {
  379.                 int tab_size = 0;
  380.                 char *image = arguments.argv[i] + 2,
  381.                      *p;
  382.                 for (p = image; *p && Code::IsDigit(*p); p++)
  383.                 {
  384.                     int digit = *p - U_0;
  385.                     tab_size = tab_size * 10 + digit;
  386.                 }
  387.  
  388.                 if (*p)
  389.                      bad_options.Next() = new OptionError(SemanticError::INVALID_TAB_VALUE, image);
  390.                 Tab::SetTabSize(tab_size == 0 ? Tab::DEFAULT_TAB_SIZE : tab_size);
  391.             }
  392.             else if (strcmp(arguments.argv[i], "+L") == 0)
  393.                  debug_dump_lex = true;
  394.             else if (strcmp(arguments.argv[i],"+U") == 0)
  395.             {
  396.                  unzip = true;
  397.                  full_check = true;
  398.             }
  399.             else if (strcmp(arguments.argv[i],"++") == 0)
  400.             {
  401.                  incremental = true;
  402.                  full_check = true;
  403.             }
  404.             else if (strcmp(arguments.argv[i], "+Z") == 0)
  405.                  zero_defect = true;
  406.             else bad_options.Next() = new OptionError(SemanticError::INVALID_OPTION, arguments.argv[i]);
  407.         }
  408.         else filename_index.Next() = i;
  409.     }
  410.  
  411.     if (! classpath)
  412.     {
  413.         classpath = getenv("JIKESPATH");
  414.         if (! classpath)
  415.             classpath = getenv("CLASSPATH");
  416.  
  417.         if (classpath)
  418.         {
  419. #ifdef EBCDIC
  420.             //
  421.             //  Maintain CLASSPATH in ASCII and translate back to EBCDIC when building file name
  422.             //
  423.             for (int k = 0; k < strlen(classpath); k++)
  424.                 classpath[k] = Code::ToASCII(classpath[k]);
  425. #endif
  426.             while (isspace(*classpath))
  427.                 classpath++;
  428.  
  429.             if (*classpath == U_NULL)
  430.                 classpath = NULL;
  431.         }
  432.  
  433.         if (! classpath)
  434.         {
  435.             default_path = new char[2];
  436.             default_path[0] = '.';
  437.             default_path[1] = U_NULL;
  438.             classpath = default_path;
  439.         }
  440.     }
  441.  
  442.     //
  443.     // Initially, first_file_index is set to argc. Since the array filename_index
  444.     // contains the indices of all the input files in arguments in reverse order,
  445.     // we reverse the order here again to get the original list...
  446.     //
  447.     for (int k = filename_index.Length() - 1; k >= 0; k--)
  448.     {
  449.         first_file_index--;
  450.  
  451.         int i = filename_index[k];
  452.         char *temp = arguments.argv[i];
  453.         arguments.argv[i] = arguments.argv[first_file_index];
  454.         arguments.argv[first_file_index] = temp;
  455.     }
  456.  
  457.     //
  458.     // If the traditional batch output form for reporting errors is requested,
  459.     // then wide character expansion is turned on.
  460.     //
  461.     if (errors && (! dump_errors))
  462.         Coutput.SetExpandWchar();
  463.  
  464.     return;
  465. }
  466.  
  467.  
  468. Option::~Option()
  469. {
  470.     for (int i = 0; i < bad_options.Length(); i++)
  471.         delete bad_options[i];
  472.  
  473.     delete [] default_path;
  474.     delete [] directory;
  475.  
  476. #ifdef WIN32_FILE_SYSTEM
  477.     for (char c = 'a'; c <= 'z'; c++)
  478.         delete [] current_directory[c];
  479. #endif
  480.  
  481.     return;
  482. }
  483.  
  484.  
  485.