From 0f6d41a084dddafa911d4ee4b4851f5d5494405e Mon Sep 17 00:00:00 2001 From: "igor%mir2.org" Date: Thu, 29 Jul 2004 10:44:59 +0000 Subject: [PATCH] Renaming StringIdMap to Main and ipdating documentation --- .../javascript/tools/idswitch/Main.java | 610 ++++++++++++++++++ .../mozilla/javascript/tools/idswitch/README | 12 +- .../tools/idswitch/StringIdMap.java | 0 3 files changed, 619 insertions(+), 3 deletions(-) create mode 100644 js/rhino/toolsrc/org/mozilla/javascript/tools/idswitch/Main.java delete mode 100644 js/rhino/toolsrc/org/mozilla/javascript/tools/idswitch/StringIdMap.java diff --git a/js/rhino/toolsrc/org/mozilla/javascript/tools/idswitch/Main.java b/js/rhino/toolsrc/org/mozilla/javascript/tools/idswitch/Main.java new file mode 100644 index 00000000000..10882afe1d6 --- /dev/null +++ b/js/rhino/toolsrc/org/mozilla/javascript/tools/idswitch/Main.java @@ -0,0 +1,610 @@ +/* -*- Mode: java; tab-width: 4; indent-tabs-mode: 1; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Rhino code, released + * May 6, 1999. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1997-1999 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Igor Bukanov + * + * Alternatively, the contents of this file may be used under the + * terms of the GNU Public License (the "GPL"), in which case the + * provisions of the GPL are applicable instead of those above. + * If you wish to allow use of your version of this file only + * under the terms of the GPL and not to allow others to use your + * version of this file under the NPL, indicate your decision by + * deleting the provisions above and replace them with the notice + * and other provisions required by the GPL. If you do not delete + * the provisions above, a recipient may use your version of this + * file under either the NPL or the GPL. + */ +package org.mozilla.javascript.tools.idswitch; + +import java.io.*; +import java.util.*; +import java.text.SimpleDateFormat; + +import org.mozilla.javascript.EvaluatorException; +import org.mozilla.javascript.tools.ToolErrorReporter; + +public class Main { + + private static final String PROGRAM_NAME = "Main"; + + private static final String SWITCH_TAG_STR = "string_id_map"; + private static final String GENERATED_TAG_STR = "generated"; + private static final String STRING_TAG_STR = "string"; + + private static final int + NORMAL_LINE = 0, + SWITCH_TAG = 1, + GENERATED_TAG = 2, + STRING_TAG = 3; + + private final Vector all_pairs = new Vector(); + + private ToolErrorReporter R; + private CodePrinter P; + private FileBody body; + private String source_file; + + private int tag_definition_end; + + private int tag_value_start; + private int tag_value_end; + + private static boolean is_value_type(int id) { + if (id == STRING_TAG) { return true; } + return false; + } + + private static String tag_name(int id) { + switch (id) { + case SWITCH_TAG: return SWITCH_TAG_STR; + case -SWITCH_TAG: return "/" + SWITCH_TAG_STR; + case GENERATED_TAG: return GENERATED_TAG_STR; + case -GENERATED_TAG: return "/" + GENERATED_TAG_STR; + } + return ""; + } + + void process_file(String file_path) throws IOException { + source_file = file_path; + + body = new FileBody(); + + InputStream is; + if (file_path.equals("-")) { + is = System.in; + } + else { + is = new FileInputStream(file_path); + } + try { + Reader r = new InputStreamReader(is, "ASCII"); + body.readData(r); + } + finally { is.close(); } + + process_file(); + + if (body.wasModified()) { + OutputStream os; + if (file_path.equals("-")) { + os = System.out; + } + else { + os = new FileOutputStream(file_path); + } + + try { + Writer w = new OutputStreamWriter(os); + body.writeData(w); + w.flush(); + } + finally { os.close(); } + } + } + + private void process_file() throws IOException { + int cur_state = 0; + char[] buffer = body.getBuffer(); + + int generated_begin = -1, generated_end = -1; + int time_stamp_begin = -1, time_stamp_end = -1; + + body.startLineLoop(); + L:while (body.nextLine()) { + int begin = body.getLineBegin(); + int end = body.getLineEnd(); + + int tag_id = extract_line_tag_id(buffer, begin, end); + boolean bad_tag = false; + switch (cur_state) { + case 0: + if (tag_id == SWITCH_TAG) { + cur_state = SWITCH_TAG; + all_pairs.removeAllElements(); + generated_begin = -1; + } + else if (tag_id == -SWITCH_TAG) { + bad_tag = true; + } + break; + case SWITCH_TAG: + if (tag_id == 0) { + look_for_id_definitions(buffer, begin, end, false); + } + else if (tag_id == STRING_TAG) { + look_for_id_definitions(buffer, begin, end, true); + } + else if (tag_id == GENERATED_TAG) { + if (generated_begin >= 0) { bad_tag = true; } + else { + cur_state = GENERATED_TAG; + time_stamp_begin = tag_definition_end; + time_stamp_end = end; + } + } + else if (tag_id == -SWITCH_TAG) { + cur_state = 0; + if (generated_begin >= 0 && !all_pairs.isEmpty()) { + generate_java_code(); + String code = P.toString(); + boolean different = body.setReplacement + (generated_begin, generated_end, code); + if (different) { + String stamp = get_time_stamp(); + body.setReplacement + (time_stamp_begin, time_stamp_end, stamp); + } + } + + break; + } + else { + bad_tag = true; + } + break; + case GENERATED_TAG: + if (tag_id == 0) { + if (generated_begin < 0) { generated_begin = begin; } + } + else if (tag_id == -GENERATED_TAG) { + if (generated_begin < 0) { generated_begin = begin; } + cur_state = SWITCH_TAG; + generated_end = begin; + } + else { + bad_tag = true; + } + break; + } + if (bad_tag) { + String text = R.getMessage("msg.idswitch.bad_tag_order", + tag_name(tag_id)); + throw R.runtimeError + (text, source_file, body.getLineNumber(), null, 0); + } + } + + if (cur_state != 0) { + String text = R.getMessage("msg.idswitch.file_end_in_switch", + tag_name(cur_state)); + throw R.runtimeError + (text, source_file, body.getLineNumber(), null, 0); + } + } + + private String get_time_stamp() { + SimpleDateFormat f = new SimpleDateFormat + (" 'Last update:' yyyy-MM-dd HH:mm:ss z"); + String dateString = f.format(new Date()); + return f.format(new Date()); + } + + private void generate_java_code() { + + P.clear(); + + IdValuePair[] pairs = new IdValuePair[all_pairs.size()]; + all_pairs.copyInto(pairs); + + SwitchGenerator g = new SwitchGenerator(); + g.char_tail_test_threshold = 2; + g.setReporter(R); + g.setCodePrinter(P); + + g.generateSwitch(pairs, "0"); + } + + private int extract_line_tag_id(char[] array, int cursor, int end) { + int id = 0; + cursor = skip_white_space(array, cursor, end); + int after_leading_white_space = cursor; + cursor = look_for_slash_slash(array, cursor, end); + if (cursor != end) { + boolean at_line_start = (after_leading_white_space + 2 == cursor); + cursor = skip_white_space(array, cursor, end); + if (cursor != end && array[cursor] == '#') { + ++cursor; + + boolean end_tag = false; + if (cursor != end && array[cursor] == '/') { + ++cursor; end_tag = true; + } + + int tag_start = cursor; + + for (; cursor != end; ++cursor) { + int c = array[cursor]; + if (c == '#' || c == '=' ||is_white_space(c)) { break; } + } + + if (cursor != end) { + int tag_end = cursor; + cursor = skip_white_space(array, cursor, end); + if (cursor != end) { + int c = array[cursor]; + if (c == '=' || c == '#') { + id = get_tag_id + (array, tag_start, tag_end, at_line_start); + if (id != 0) { + String bad = null; + if (c == '#') { + if (end_tag) { + id = -id; + if (is_value_type(id)) { + bad = "msg.idswitch.no_end_usage"; + } + } + tag_definition_end = cursor + 1; + } + else { + if (end_tag) { + bad = "msg.idswitch.no_end_with_value"; + } + else if (!is_value_type(id)) { + bad = "msg.idswitch.no_value_allowed"; + } + id = extract_tag_value + (array, cursor + 1, end, id); + } + if (bad != null) { + String s = R.getMessage(bad, tag_name(id)); + throw R.runtimeError + (s, source_file, body.getLineNumber(), + null, 0); + } + } + } + } + } + } + } + return id; + } + +// Return position after first of // or end if not found + private int look_for_slash_slash(char[] array, int cursor, int end) { + while (cursor + 2 <= end) { + int c = array[cursor++]; + if (c == '/') { + c = array[cursor++]; + if (c == '/') { + return cursor; + } + } + } + return end; + } + + private int extract_tag_value(char[] array, int cursor, int end, int id) { + // cursor points after #[^#=]+= + // ALERT: implement support for quoted strings + boolean found = false; + cursor = skip_white_space(array, cursor, end); + if (cursor != end) { + int value_start = cursor; + int value_end = cursor; + while (cursor != end) { + int c = array[cursor]; + if (is_white_space(c)) { + int after_space = skip_white_space(array, cursor + 1, end); + if (after_space != end && array[after_space] == '#') { + value_end = cursor; + cursor = after_space; + break; + } + cursor = after_space + 1; + } + else if (c == '#') { + value_end = cursor; + break; + } + else { + ++cursor; + } + } + if (cursor != end) { + // array[cursor] is '#' here + found = true; + tag_value_start = value_start; + tag_value_end = value_end; + tag_definition_end = cursor + 1; + } + } + return (found) ? id : 0; + } + + private int get_tag_id + (char[] array, int begin, int end, boolean at_line_start) + { + if (at_line_start) { + if (equals(SWITCH_TAG_STR, array, begin, end)) { + return SWITCH_TAG; + } + if (equals(GENERATED_TAG_STR, array, begin, end)) { + return GENERATED_TAG; + } + } + if (equals(STRING_TAG_STR, array, begin, end)) { + return STRING_TAG; + } + return 0; + } + + private void look_for_id_definitions + (char[] array, int begin, int end, boolean use_tag_value_as_string) + { + // Look for the pattern + // '^[ \t]+Id_([a-zA-Z0-9_]+)[ \t]*=.*$' + // where \1 gives field or method name + int cursor = begin; + // Skip tab and spaces at the beginning + cursor = skip_white_space(array, cursor, end); + int id_start = cursor; + int name_start = skip_matched_prefix("Id_", array, cursor, end); + if (name_start >= 0) { + // Found Id_ prefix + cursor = name_start; + cursor = skip_name_char(array, cursor, end); + int name_end = cursor; + if (name_start != name_end) { + cursor = skip_white_space(array, cursor, end); + if (cursor != end) { + if (array[cursor] == '=') { + int id_end = name_end; + if (use_tag_value_as_string) { + name_start = tag_value_start; + name_end = tag_value_end; + } + // Got the match + add_id(array, id_start, id_end, name_start, name_end); + } + } + } + } + } + + private void add_id + (char[] array, int id_start, int id_end, int name_start, int name_end) + { + String name = new String(array, name_start, name_end - name_start); + String value = new String(array, id_start, id_end - id_start); + + IdValuePair pair = new IdValuePair(name, value); + + pair.setLineNumber(body.getLineNumber()); + + all_pairs.addElement(pair); + } + + private static boolean is_white_space(int c) { + return c == ' ' || c == '\t'; + } + + private static int skip_white_space(char[] array, int begin, int end) { + int cursor = begin; + for (; cursor != end; ++cursor) { + int c = array[cursor]; + if (!is_white_space(c)) { break; } + } + return cursor; + } + + private static int skip_matched_prefix + (String prefix, char[] array, int begin, int end) + { + int cursor = -1; + int prefix_length = prefix.length(); + if (prefix_length <= end - begin) { + cursor = begin; + for (int i = 0; i != prefix_length; ++i, ++cursor) { + if (prefix.charAt(i) != array[cursor]) { + cursor = -1; break; + } + } + } + return cursor; + } + + private static boolean equals(String str, char[] array, int begin, int end) + { + if (str.length() == end - begin) { + for (int i = begin, j = 0; i != end; ++i, ++j) { + if (array[i] != str.charAt(j)) { return false; } + } + return true; + } + return false; + } + + private static int skip_name_char(char[] array, int begin, int end) { + int cursor = begin; + for (; cursor != end; ++cursor) { + int c = array[cursor]; + if (!('a' <= c && c <= 'z') && !('A' <= c && c <= 'Z')) { + if (!('0' <= c && c <= '9')) { + if (c != '_') { + break; + } + } + } + } + return cursor; + } + + public static void main(String[] args) { + Main self = new Main(); + int status = self.exec(args); + System.exit(status); + } + + private int exec(String[] args) { + R = new ToolErrorReporter(true, System.err); + + int arg_count = process_options(args); + + if (arg_count == 0) { + option_error(R.getMessage + ("msg.idswitch.no_file_argument")); + return -1; + } + if (arg_count > 1) { + option_error(R.getMessage + ("msg.idswitch.too_many_arguments")); + return -1; + } + + P = new CodePrinter(); + P.setIndentStep(4); + P.setIndentTabSize(0); + + try { + process_file(args[0]); + } + catch (IOException ex) { + print_error(R.getMessage + ("msg.idswitch.io_error", ex.toString())); + return -1; + } + catch (EvaluatorException ex) { + return -1; + } + return 0; + } + + private int process_options(String[] args) { + + int status = 1; + + boolean show_usage = false; + boolean show_version = false; + + int N = args.length; + L: for (int i = 0; i != N; ++i) { + String arg = args[i]; + int arg_length = arg.length(); + if (arg_length >= 2) { + if (arg.charAt(0) == '-') { + if (arg.charAt(1) == '-') { + if (arg_length == 2) { + args[i] = null; break; + } + if (arg.equals("--help")) { + show_usage = true; + } + else if (arg.equals("--version")) { + show_version = true; + } + else { + option_error(R.getMessage + ("msg.idswitch.bad_option", arg)); + status = -1; break L; + } + } + else { + for (int j = 1; j != arg_length; ++j) { + char c = arg.charAt(j); + switch (c) { + case 'h': show_usage = true; break; + default: + option_error(R.getMessage + ("msg.idswitch.bad_option_char", + "" + c)); + status = -1; + break L; + } + + } + } + args[i] = null; + } + } + } + + if (status == 1) { + if (show_usage) { show_usage(); status = 0; } + if (show_version) { show_version(); status = 0; } + } + + if (status != 1) { System.exit(status); } + + return remove_nulls(args); + } + + private void show_usage() { + System.out.println(R.getMessage("msg.idswitch.usage")); + System.out.println(); + } + + private void show_version() { + System.out.println(R.getMessage("msg.idswitch.version")); + } + + private void option_error(String str) { + print_error(R.getMessage("msg.idswitch.bad_invocation", str)); + } + + private void print_error(String text) { + System.err.println(text); + } + + private int remove_nulls(String[] array) { + int N = array.length; + int cursor = 0; + for (; cursor != N; ++cursor) { + if (array[cursor] == null) { break; } + } + int destination = cursor; + if (cursor != N) { + ++cursor; + for (; cursor != N; ++cursor) { + String elem = array[cursor]; + if (elem != null) { + array[destination] = elem; ++destination; + } + } + } + return destination; + } + + + +} + diff --git a/js/rhino/toolsrc/org/mozilla/javascript/tools/idswitch/README b/js/rhino/toolsrc/org/mozilla/javascript/tools/idswitch/README index 325b116eb8c..321647bf41e 100644 --- a/js/rhino/toolsrc/org/mozilla/javascript/tools/idswitch/README +++ b/js/rhino/toolsrc/org/mozilla/javascript/tools/idswitch/README @@ -1,8 +1,12 @@ -Notes on StringIdMap (main class org.mozilla.javascript.tools.idswitch.StringIdMap) utility + +USING IDSWITCH GENERATOR TOOL + +Usage: +java org.mozilla.javascript.tools.idswitch.Main The main purpose of this utility is to generate Java code to map strings to some ids that can be used, for example, in a switch statement. -The utility scans the file for lines with the following structure: +The utility scans the input file for lines with the following structure: // #string_id_map# ... @@ -68,7 +72,9 @@ For example, if file x.java contains: then invocation -java org.mozilla.javascript.tools.string_switch.StringIdMap x.java + +java org.mozilla.javascript.tools.idswitch.Main x.java + would replace that by a code fragment similar to: // #string_id_map# diff --git a/js/rhino/toolsrc/org/mozilla/javascript/tools/idswitch/StringIdMap.java b/js/rhino/toolsrc/org/mozilla/javascript/tools/idswitch/StringIdMap.java deleted file mode 100644 index e69de29bb2d..00000000000