// $Id: option.cpp,v 1.86 2004/03/25 13:32:28 ericb Exp $ // // This software is subject to the terms of the IBM Jikes Compiler // License Agreement available at the following URL: // http://ibm.com/developerworks/opensource/jikes. // Copyright (C) 1996, 2004 IBM Corporation and others. All Rights Reserved. // You must accept the terms of that agreement to use this software. // #include "option.h" #include "javasym.h" #include "error.h" #include "case.h" #include "tab.h" #include "stream.h" #ifdef HAVE_JIKES_NAMESPACE namespace Jikes { // Open namespace Jikes block #endif // // Look for file names in an @file and add them to the passed // in tuple. // void ArgumentExpander::ExpandAtFileArgument(Tuple& arguments, char *file_name, Tuple& bad_options) { struct stat status; FILE *afile = SystemFopen(file_name, "r"); if (afile && (SystemStat(file_name, &status) == 0)) { char *buffer; int file_size; char *start = NULL; char *end = NULL; char *eol = NULL; buffer = new char[status.st_size + 2]; file_size = SystemFread(buffer, 1, status.st_size, afile); // Fails under Cygwin (fopen "b" flag) //assert(status.st_size == file_size); buffer[file_size] = U_LINE_FEED; buffer[file_size + 1] = U_NULL; for (char *ptr = buffer; *ptr; ) { // Skip spaces, tabs, and EOL until we find some text while (start == NULL && *ptr) { switch (*ptr) { case U_SPACE: case U_HORIZONTAL_TAB: case U_LINE_FEED: case U_CARRIAGE_RETURN: break; // Out of the switch not the while default: start = ptr; end = ptr; } ptr++; } // If at end of the buffer, no arguments are left if (! *ptr) break; // Find the end of this line, save last non space // or tab position in the end ptr while (eol == NULL) { switch (*ptr) { case U_LINE_FEED: case U_CARRIAGE_RETURN: eol = ptr; break; case U_SPACE: case U_HORIZONTAL_TAB: break; // ignore tabs and spaces default: end = ptr; } ptr++; } // Ignore single/double quotes at start and end of line. if (start < end && (*start == U_DOUBLE_QUOTE && *end == U_DOUBLE_QUOTE) || (*start == U_SINGLE_QUOTE && *end == U_SINGLE_QUOTE)) { start++; end--; } // Another @file name in an @file is not allowed if (start < end && (*start == U_AT)) { bad_options.Next() = new OptionError(OptionError::NESTED_AT_FILE, file_name); break; } // Copy arg into new string and add to tuple *(end+1) = '\0'; char *arg = new char[strlen(start) + 1]; strcpy(arg, start); arguments.Next() = arg; // Reinit the pointers start = NULL; end = NULL; eol = NULL; } delete [] buffer; } else { bad_options.Next() = new OptionError(OptionError::INVALID_AT_FILE, file_name); } if (afile != NULL) fclose(afile); } ArgumentExpander::ArgumentExpander(int argc_, char *argv_[], Tuple& bad_options) { Tuple arguments(8192); for (int i = 0; i < argc_; i++) { char *argument = argv_[i]; if (argument[0] == '@') { ExpandAtFileArgument(arguments, argument + 1, bad_options); } else { char *str = new char[strlen(argument) + 1]; strcpy(str, argument); arguments.Next() = str; } } argc = arguments.Length(); argv = new char*[argc]; for (int k = 0; k < argc; k++) argv[k] = arguments[k]; } const wchar_t* OptionError::GetErrorMessage() { ErrorString s; s << "Error: "; switch (kind) { case INVALID_OPTION: s << '\"' << name << "\" is an invalid option."; break; case MISSING_OPTION_ARGUMENT: s << '\"' << name << "\" requires an argument."; break; case INVALID_SOURCE_ARGUMENT: if (ENABLE_SOURCE_15) { s << "\"-source\" only recognizes Java releases 1.3 (JLS 2 " << "features), 1.4 (assert statement), and 1.5 (partial " << "support beta, see NEWS for supported features)."; break; } s << "\"-source\" only recognizes Java releases 1.3 (JLS 2 features) " << "and 1.4 (assert statement)."; break; case INVALID_TARGET_ARGUMENT: s << "\"-target\" only recognizes Java releases 1.1, 1.2, 1.3, 1.4, " << "and 1.4.2."; break; case INVALID_K_OPTION: s << "No argument specified for +K option. The proper form is " << "\"+Kxxx=xxx\" (with no intervening space)."; break; case INVALID_K_TARGET: s << '\"' << name << "\" is not a valid target in a +K option. The target must be a " << "numeric type or boolean."; break; case INVALID_TAB_VALUE: s << '\"' << name << "\" is not a valid tab size. An integer value is expected."; break; case INVALID_P_ARGUMENT: s << '\"' << name << "\" is not a recognized flag for controlling pedantic warnings."; break; case INVALID_DIRECTORY: s << "The directory specified in the \"-d\" option, \"" << name << "\", is either invalid or it could not be expanded."; break; case INVALID_AT_FILE: s << "The @ file \"" << name << "\", is either invalid or it could not be located."; break; case NESTED_AT_FILE: s << "The @ file \"" << name << "\" must not reference another @ file."; break; case UNSUPPORTED_ENCODING: s << "Unsupported encoding: \"" << name << "\"."; break; case UNSUPPORTED_OPTION: s << "The option \"" << name << "\" is unsupported in this build."; break; case DISABLED_OPTION: s << "The option \"" << name << "\" has been temporarily disabled."; break; default: assert(false && "invalid OptionError kind"); } return s.Array(); } #ifdef WIN32_FILE_SYSTEM void Option::SaveCurrentDirectoryOnDisk(char c) { if (! current_directory[c]) { char *disk_directory = NULL, disk[3] = { c, U_COLON, U_NULL }, tmp[1]; if (SetCurrentDirectory(disk)) { // first, get the right size DWORD directory_length = GetCurrentDirectory(0, tmp); // allocate the directory disk_directory = new char[directory_length + 1]; DWORD length = GetCurrentDirectory(directory_length, disk_directory); if (length <= directory_length) { for (char *ptr = disk_directory; *ptr; ptr++) // turn '\' to '/'. *ptr = (*ptr != U_BACKSLASH ? *ptr : (char) U_SLASH); } } if (! disk_directory) { disk_directory = new char[2]; disk_directory[0] = U_DOT; disk_directory[1] = U_NULL; } current_directory[Case::ToAsciiLower(c)] = disk_directory; current_directory[Case::ToAsciiUpper(c)] = disk_directory; } } #endif // WIN32_FILE_SYSTEM // // Skip leading whitespace and copy the rest to a new string // so we don't have to worry about affecting the environment // variable. If input value is NULL or consists of only whitespace // characters, returns NULL. // static inline char* makeStrippedCopy(char* value) { if (value == NULL) return NULL; while (isspace(*value)) value++; char* result = new char[strlen(value) + 1]; strcpy(result, value); #ifdef HAVE_CYGWIN_WIN32_TO_POSIX_PATH_LIST if (*value) { // // Under Cygwin, we convert a Windows-style path into a UNIX-style // path. A path like "C:\Cygwin\tmp;C:\Windows" is converted into // "/tmp:/cygdrive/c/Windows" (assuming C:\Cygwin is cygroot). We // can then parse it using the UNIX path seperator char ':'. // if (! cygwin_posix_path_list_p(result)) { char* temp = new char[cygwin_win32_to_posix_path_list_buf_size(result)]; cygwin_win32_to_posix_path_list(result, temp); delete[] result; result = temp; } } #endif // CYGWIN_WIN32_TO_POSIX_PATH_LIST return result; } Option::Option(ArgumentExpander& arguments, Tuple& bad_options) : first_file_index(arguments.argc), #ifdef JIKES_DEBUG debug_trap_op(0), debug_dump_lex(false), debug_dump_ast(false), debug_unparse_ast(false), debug_unparse_ast_debug(false), debug_comments(false), debug_dump_class(false), debug_trace_stack_change(false), #endif // JIKES_DEBUG nocleanup(false), incremental(false), makefile(false), dependence_report(false), bytecode(true), full_check(false), unzip(false), dump_errors(false), errors(true), pedantic(false), noassert(false), dependence_report_name(NULL) { #ifdef WIN32_FILE_SYSTEM for (int j = 0; j < 128; j++) current_directory[j] = NULL; char tmp[1]; // first, get the right size DWORD directory_length = GetCurrentDirectory(0, tmp); // allocate the directory char *main_current_directory = new char[directory_length + 1]; DWORD length = GetCurrentDirectory(directory_length, main_current_directory); if (length > directory_length) { main_current_directory[0] = U_DOT; main_current_directory[1] = U_NULL; main_disk = 0; } else { for (char *ptr = main_current_directory; *ptr; ptr++) // turn '\' to '/'. *ptr = (*ptr != U_BACKSLASH ? *ptr : (char) U_SLASH); main_disk = main_current_directory[0]; // the first character current_directory[Case::ToAsciiLower(main_disk)] = main_current_directory; current_directory[Case::ToAsciiUpper(main_disk)] = main_current_directory; } current_directory[0] = main_current_directory; #endif // WIN32_FILE_SYSTEM Tuple filename_index(2048); for (int i = 1; i < arguments.argc; i++) { bool consumed = false; if (arguments.argv[i][0] == '-') { consumed = true; if (strcmp(arguments.argv[i], "-bootclasspath") == 0 || strcmp(arguments.argv[i], "--bootclasspath") == 0) { if (i + 1 == arguments.argc) { bad_options.Next() = new OptionError(OptionError::MISSING_OPTION_ARGUMENT, arguments.argv[i]); continue; } // Create a clean copy of the -bootclasspath argument so we // can modify this copy and delete it later in ~JikesOption delete [] bootclasspath; bootclasspath = makeStrippedCopy(arguments.argv[++i]); } else if (strcmp(arguments.argv[i], "-classpath") == 0 || strcmp(arguments.argv[i], "--classpath") == 0 || strcmp(arguments.argv[i], "-cp") == 0) { if (i + 1 == arguments.argc) { bad_options.Next() = new OptionError(OptionError::MISSING_OPTION_ARGUMENT, arguments.argv[i]); continue; } // Create a clean copy of the -classpath argument so we can // modify this copy and delete it later in ~JikesOption delete [] classpath; classpath = makeStrippedCopy(arguments.argv[++i]); } else if (strcmp(arguments.argv[i], "-d") == 0 || strcmp(arguments.argv[i], "--target-directory") == 0) { if (i + 1 == arguments.argc) { bad_options.Next() = new OptionError(OptionError::MISSING_OPTION_ARGUMENT, arguments.argv[i]); continue; } ++i; delete [] directory; // // FIXME: Move this platform specific stuff to platform.cpp. // #if defined(UNIX_FILE_SYSTEM) int length = strlen(arguments.argv[i]); directory = new char[length + 1]; strcpy(directory, arguments.argv[i]); #elif defined(WIN32_FILE_SYSTEM) char disk = (Case::IsAsciiAlpha(arguments.argv[i][0]) && arguments.argv[i][1] == U_COLON) ? arguments.argv[i][0] : 0; SaveCurrentDirectoryOnDisk(disk); if (SetCurrentDirectory(arguments.argv[i])) { char tmp[1]; // first, get the right size DWORD directory_length = GetCurrentDirectory(0, tmp); // allocate the directory directory = new char[directory_length + 1]; DWORD length = GetCurrentDirectory(directory_length, directory); if (length > directory_length) { delete [] directory; directory = NULL; } } // reset the current directory on the disk ResetCurrentDirectoryOnDisk(disk); // reset the real current directory... SetMainCurrentDirectory(); if (! directory) { bad_options.Next() = new OptionError(OptionError::INVALID_DIRECTORY, arguments.argv[i]); } #endif // WIN32_FILE_SYSTEM if (directory) { for (char *ptr = directory; *ptr; ptr++) // turn '\' to '/'. *ptr = (*ptr != U_BACKSLASH ? *ptr : (char) U_SLASH); } } else if (strcmp(arguments.argv[i], "-debug") == 0) ; // Ignore for compatibility. else if (strcmp(arguments.argv[i], "-depend") == 0 || strcmp(arguments.argv[i], "--depend") == 0 || strcmp(arguments.argv[i], "-Xdepend") == 0) { depend = true; } else if (strcmp(arguments.argv[i], "-deprecation") == 0 || strcmp(arguments.argv[i], "--deprecation") == 0) { deprecation = true; } else if (strcmp(arguments.argv[i], "-encoding") == 0 || strcmp(arguments.argv[i], "--encoding") == 0) { if (i + 1 == arguments.argc) { bad_options.Next() = new OptionError(OptionError::MISSING_OPTION_ARGUMENT, arguments.argv[i]); continue; } i++; #if defined(HAVE_ENCODING) delete [] encoding; encoding = new char[strlen(arguments.argv[i]) + 1]; strcpy(encoding, arguments.argv[i]); if (! Stream::IsSupportedEncoding(encoding)) { bad_options.Next() = new OptionError(OptionError::UNSUPPORTED_ENCODING, encoding); encoding = NULL; } #else // ! defined(HAVE_ENCODING) bad_options.Next() = new OptionError(OptionError::UNSUPPORTED_OPTION, "-encoding"); #endif // ! defined(HAVE_ENCODING) } else if (strcmp(arguments.argv[i], "-extdirs") == 0 || strcmp(arguments.argv[i], "--extdirs") == 0) { if (i + 1 == arguments.argc) { bad_options.Next() = new OptionError(OptionError::MISSING_OPTION_ARGUMENT, arguments.argv[i]); continue; } // Create a clean copy of the -extdirs argument so we can // modify this copy and delete it later in ~JikesOption delete [] extdirs; extdirs = makeStrippedCopy(arguments.argv[++i]); } else if (arguments.argv[i][1] == 'g') { // This defaults to SOURCE | LINES if no -g option was // explicitly specified. "-g" is equivalent to // "-g:source,lines,vars". if (! strcmp(arguments.argv[i], "-g:none")) g = NONE; else if (! strcmp(arguments.argv[i], "-g:source") ) g = SOURCE; else if (! strcmp(arguments.argv[i], "-g:lines")) g = LINES; else if (! strcmp(arguments.argv[i], "-g:vars")) g = VARS; else if (! strcmp(arguments.argv[i], "-g:source,lines") || ! strcmp(arguments.argv[i], "-g:lines,source")) g = SOURCE | LINES; else if (! strcmp(arguments.argv[i], "-g:source,vars") || ! strcmp(arguments.argv[i], "-g:vars,source")) g = SOURCE | VARS; else if (! strcmp(arguments.argv[i], "-g:lines,vars") || ! strcmp(arguments.argv[i], "-g:vars,lines")) g = LINES | VARS; else if (! strcmp(arguments.argv[i], "-g") || ! strcmp(arguments.argv[i], "-g:source,lines,vars") || ! strcmp(arguments.argv[i], "-g:source,vars,lines") || ! strcmp(arguments.argv[i], "-g:lines,source,vars") || ! strcmp(arguments.argv[i], "-g:lines,vars,source") || ! strcmp(arguments.argv[i], "-g:vars,source,lines") || ! strcmp(arguments.argv[i], "-g:vars,lines,source")) g = SOURCE | LINES | VARS; else { bad_options.Next() = new OptionError(OptionError::INVALID_OPTION, arguments.argv[i]); } } else if (strcmp(arguments.argv[i], "-help") == 0 || strcmp(arguments.argv[i], "--help") == 0 || strcmp(arguments.argv[i], "-h") == 0 || strcmp(arguments.argv[i], "-?") == 0) { help = true; } else if (arguments.argv[i][1] == 'J') ; // Ignore for compatibility. else if (strcmp(arguments.argv[i], "-nowarn") == 0 || strcmp(arguments.argv[i], "--nowarn") == 0 || strcmp(arguments.argv[i], "-q") == 0) { tolerance = NO_WARNINGS; } else if (strcmp(arguments.argv[i], "-Werror") == 0) { tolerance = ToleranceLevel(WARNINGS_ARE_ERRORS | CAUTIONS_ARE_ERRORS); } else if (strcmp(arguments.argv[i], "-nowrite") == 0 || strcmp(arguments.argv[i], "--nowrite") == 0) { nowrite = true; } else if (strcmp(arguments.argv[i], "-O") == 0 || strcmp(arguments.argv[i], "--optimize") == 0) { optimize = true; } else if (strcmp(arguments.argv[i], "-source") == 0 || strcmp(arguments.argv[i], "--source") == 0) { if (i + 1 == arguments.argc) { bad_options.Next() = new OptionError(OptionError::MISSING_OPTION_ARGUMENT, arguments.argv[i]); continue; } // See below for setting the default. i++; if (! strcmp(arguments.argv[i], "1.3")) source = SDK1_3; else if (! strcmp(arguments.argv[i], "1.4")) source = SDK1_4; else if (ENABLE_SOURCE_15 && ! strcmp(arguments.argv[i], "1.5")) { source = SDK1_5; } else { bad_options.Next() = new OptionError(OptionError::INVALID_SOURCE_ARGUMENT, "-source"); } } else if (strcmp(arguments.argv[i], "-sourcepath") == 0 || strcmp(arguments.argv[i], "--sourcepath") == 0) { if (i + 1 == arguments.argc) { bad_options.Next() = new OptionError(OptionError::MISSING_OPTION_ARGUMENT, arguments.argv[i]); continue; } // Create a clean copy of the -sourcepath argument so we can // modify this copy and delete it later in ~JikesOption delete [] sourcepath; sourcepath = makeStrippedCopy(arguments.argv[++i]); } else if (strcmp(arguments.argv[i], "-target") == 0 || strcmp(arguments.argv[i], "--target") == 0) { if (i + 1 == arguments.argc) { bad_options.Next() = new OptionError(OptionError::MISSING_OPTION_ARGUMENT, arguments.argv[i]); continue; } // See below for setting the default. i++; if (! strcmp(arguments.argv[i], "1.1")) target = SDK1_1; else if (! strcmp(arguments.argv[i], "1.2")) target = SDK1_2; else if (! strcmp(arguments.argv[i], "1.3")) target = SDK1_3; else if (! strcmp(arguments.argv[i], "1.4")) target = SDK1_4; else if (! strcmp(arguments.argv[i], "1.4.2")) target = SDK1_4_2; else if (! strcmp(arguments.argv[i], "1.5")) target = SDK1_5; else { bad_options.Next() = new OptionError(OptionError::INVALID_TARGET_ARGUMENT, "-target"); } } else if (strcmp(arguments.argv[i], "-verbose") == 0 || strcmp(arguments.argv[i], "--verbose") == 0 || strcmp(arguments.argv[i], "-v") == 0) { verbose = true; } else if (strcmp(arguments.argv[i], "-version") == 0 || strcmp(arguments.argv[i], "--version") == 0 || strcmp(arguments.argv[i], "-V") == 0) { version = true; } else if (strcmp(arguments.argv[i], "-Xstdout") == 0) // // FIXME: Javac 1.3 takes an argument to -Xstdout, as the name // of the file where to direct output. It is not a unary // flag to direct output to stdout instead of stderr. // Coutput.StandardOutput(); else if (strcmp(arguments.argv[i], "-Xswitchcheck") == 0) { const char* image = arguments.argv[i] + 2; bool success = SemanticError::ProcessWarningSwitch(image); assert(success); } else if (arguments.argv[i][1] == 'X') { // Note that we've already consumed -Xdepend, -Xstdout, // and -Xswitchcheck. bad_options.Next() = new OptionError(OptionError::UNSUPPORTED_OPTION, arguments.argv[i]); } else if (arguments.argv[i][1] != '-') { bad_options.Next() = new OptionError(OptionError::INVALID_OPTION, arguments.argv[i]); } else consumed = false; } if (! consumed && (arguments.argv[i][0] == '+' || (arguments.argv[i][0] == '-' && arguments.argv[i][1] == '-'))) { consumed = true; if (strcmp(arguments.argv[i], "++") == 0 || strcmp(arguments.argv[i], "--incremental") == 0) { incremental = true; full_check = true; } else if (strcmp(arguments.argv[i], "+a") == 0 || strcmp(arguments.argv[i], "--noassert") == 0) { noassert = true; } else if (strcmp(arguments.argv[i], "+B") == 0 || strcmp(arguments.argv[i], "--nobytecode") == 0) { bytecode = false; } else if (strcmp(arguments.argv[i], "+D") == 0 || strcmp(arguments.argv[i], "--dump-errors") == 0) { dump_errors = true; errors = false; } else if (strncmp(arguments.argv[i], "+DR", 3) == 0) { char *image = arguments.argv[i] + 3; if (*image == '=') image++; else if (! *image) { if (i + 1 == arguments.argc) { bad_options.Next() = new OptionError(OptionError::MISSING_OPTION_ARGUMENT, arguments.argv[i]); continue; } image = arguments.argv[++i]; } makefile = true; dependence_report = true; full_check = true; dependence_report_name = new char[strlen(image) + 1]; strcpy(dependence_report_name, image); } else if (strcmp(arguments.argv[i], "+E") == 0 || strcmp(arguments.argv[i], "--emacs") == 0) { errors = false; } else if (strcmp(arguments.argv[i], "+F") == 0 || strcmp(arguments.argv[i], "--full-dependence") == 0) { full_check = true; } else if (arguments.argv[i][1] == 'K') { char *name = arguments.argv[i] + 2, *image; for (image = name; *image && *image != '='; image++) ; if (*image != '=') bad_options.Next() = new OptionError(OptionError::INVALID_K_OPTION, arguments.argv[i]); else { int key = 0; // assume undefined image++; if (strcmp(image, "boolean") == 0) key = TK_boolean; else if (strcmp(image, "byte") == 0) key = TK_byte; else if (strcmp(image, "char") == 0) key = TK_char; else if (strcmp(image, "short") == 0) key = TK_short; else if (strcmp(image, "int") == 0) key = TK_int; else if (strcmp(image, "long") == 0) key = TK_long; else if (strcmp(image, "float") == 0) key = TK_float; else if (strcmp(image, "double") == 0) key = TK_double; else { bad_options.Next() = new OptionError(OptionError::INVALID_K_TARGET, image); } if (key != 0) { int i = keyword_map.NextIndex(); keyword_map[i].key = key; keyword_map[i].length = image - name - 1; keyword_map[i].name = new wchar_t[keyword_map[i].length]; for (int k = 0; k < keyword_map[i].length; k++) keyword_map[i].name[k] = name[k]; } } } else if (strcmp(arguments.argv[i], "+M") == 0 || strcmp(arguments.argv[i], "--makefile") == 0) { makefile = true; full_check = true; } else if (strcmp(arguments.argv[i], "+OLDCSO") == 0) old_classpath_search_order = true; else if (strcmp(arguments.argv[i], "+P") == 0 || strcmp(arguments.argv[i], "--pedantic") == 0) { // Turn on ALL default pedantic warnings. Can be called // multiple times. pedantic = true; SemanticError::EnableDefaultWarnings(); } else if (arguments.argv[i][1] == 'P') { const char* image = arguments.argv[i] + 2; if (! SemanticError::ProcessWarningSwitch(image)) { bad_options.Next() = new OptionError(OptionError::INVALID_P_ARGUMENT, image); } } else if (arguments.argv[i][1] == 'T' || strncmp(arguments.argv[i], "--tab", 5) == 0) { int tab_size = 0; char* image = arguments.argv[i] + 2; if (arguments.argv[i][1] == '-') image += 3; if (*image == '=') image++; else if (! *image) { if (i + 1 == arguments.argc) { bad_options.Next() = new OptionError(OptionError::MISSING_OPTION_ARGUMENT, arguments.argv[i]); continue; } image = arguments.argv[++i]; } char *p; for (p = image; *p && *p >= '0' && *p <= '9'; p++) { int digit = *p - '0'; tab_size = tab_size * 10 + digit; } if (*p) { bad_options.Next() = new OptionError(OptionError::INVALID_TAB_VALUE, image); } Tab::SetTabSize(tab_size == 0 ? Tab::DEFAULT_TAB_SIZE : tab_size); } else if (strcmp(arguments.argv[i], "+U") == 0 || strcmp(arguments.argv[i], "--unzip-dependence") == 0) { unzip = true; full_check = true; } else if (strcmp(arguments.argv[i], "--zero-cautions") == 0) { tolerance = CAUTIONS_ARE_ERRORS; } else if (strncmp(arguments.argv[i], "+Z", 2) == 0) { // We accept +Z, +Z0, +Z1, and +Z2, where +Z means +Z1. char* start = arguments.argv[i] + 2; char* end = 0; int level = (*start == '\0') ? 1 : strtoul(start, &end, 10); if (end && *end != 0) level = 666; // Translate the numeric level into a ToleranceLevel. if (level == 0) { tolerance = NO_WARNINGS; } else if (level == 1) { tolerance = CAUTIONS_ARE_ERRORS; } else if (level == 2) { tolerance = ToleranceLevel(WARNINGS_ARE_ERRORS | CAUTIONS_ARE_ERRORS); } else { bad_options.Next() = new OptionError(OptionError::INVALID_OPTION, arguments.argv[i]); } } #ifdef JIKES_DEBUG else if (strcmp(arguments.argv[i], "+A") == 0) debug_dump_ast = true; else if (strcmp(arguments.argv[i], "+c") == 0) debug_comments = true; else if (strcmp(arguments.argv[i], "+C") == 0) debug_dump_class = true; else if (strcmp(arguments.argv[i], "+L") == 0) debug_dump_lex = true; else if (strcmp(arguments.argv[i], "+O") == 0) debug_trap_op = atoi(arguments.argv[++i]); else if (strcmp(arguments.argv[i], "+S") == 0) debug_trace_stack_change = true; else if (strcmp(arguments.argv[i], "+u") == 0) debug_unparse_ast = true; else if (strcmp(arguments.argv[i], "+ud") == 0) { debug_unparse_ast = true; debug_unparse_ast_debug = true; } #endif // JIKES_DEBUG else { bad_options.Next() = new OptionError(OptionError::INVALID_OPTION, arguments.argv[i]); } } if (! consumed) filename_index.Next() = i; } // Specify defaults for -source and -target. if (source == UNKNOWN) { switch (target) { case SDK1_1: case SDK1_2: case SDK1_3: source = SDK1_3; break; case UNKNOWN: target = SDK1_4_2; // fallthrough case SDK1_4: case SDK1_4_2: source = SDK1_4; break; case SDK1_5: source = ENABLE_SOURCE_15 ? SDK1_5 : SDK1_4; break; default: assert(false && "Unexpected target level"); } } else if (target == UNKNOWN) target = source; if (! bootclasspath) // Create a clean copy of the bootclasspath envvar so we can modify // this copy and delete it later in ~JikesOption bootclasspath = makeStrippedCopy(getenv("BOOTCLASSPATH")); if (! extdirs) // Create a clean copy of the extdirs envvar so we can modify // this copy and delete it later in ~JikesOption extdirs = makeStrippedCopy(getenv("EXTDIRS")); if (! classpath) { // Create a clean copy of the jikespath envvar so we can modify // this copy and delete it later in ~JikesOption classpath = makeStrippedCopy(getenv("JIKESPATH")); if (! classpath) // Create a clean copy of the classpath envvar so we can modify // this copy and delete it later in ~JikesOption classpath = makeStrippedCopy(getenv("CLASSPATH")); } if (! sourcepath) { // Create a clean copy of the sourcepath envvar so we can modify // this copy and delete it later in ~JikesOption sourcepath = makeStrippedCopy(getenv("SOURCEPATH")); if (! sourcepath) { sourcepath = new char[2]; sourcepath[0] = '.'; sourcepath[1] = U_NULL; } } // // Initially, first_file_index is set to argc. Since the array // filename_index contains the indices of all the input files in // arguments in reverse order, we reverse the order here again to get // the original list... // for (int k = filename_index.Length() - 1; k >= 0; k--) { first_file_index--; int i = filename_index[k]; char *temp = arguments.argv[i]; arguments.argv[i] = arguments.argv[first_file_index]; arguments.argv[first_file_index] = temp; } // // If the traditional batch output form for reporting errors is requested, // then wide character expansion is turned on. // if (errors) Coutput.SetExpandWchar(); } Option::~Option() { delete [] dependence_report_name; #ifdef WIN32_FILE_SYSTEM for (char c = 'a'; c <= 'z'; c++) delete [] current_directory[c]; #endif // WIN32_FILE_SYSTEM } #ifdef HAVE_JIKES_NAMESPACE } // Close namespace Jikes block #endif