indexing description: "[ EiffelMedia Class Generator. Parses an XML file and stores it in a table (see EM_CLASS_GENERATOR_XM_FILTER). Processes command line arguments, generates a main class and a singleton of it. ]" date: "$Date$" revision: "$Revision$" deferred class EM_CLASS_GENERATOR inherit KL_SHARED_ARGUMENTS XM_CALLBACKS_FILTER_FACTORY feature -- Initialization make is -- creation procedure do if (not (arguments.argument_count >= 1)) or arguments.index_of_beginning_with_word_option ("h") /= 0 or arguments.index_of_word_option ("-help") /= 0 then print_help has_error := true else input_file_name := arguments.argument (1) if not input_file_name.substring (input_file_name.count - 3, input_file_name.count).is_equal (".xml") then print_help has_error := true else if arguments.index_of_beginning_with_word_option ("o") /= 0 and then not arguments.separate_word_option_value ("o").is_equal ("") then main_class_name := arguments.separate_word_option_value ("o") elseif arguments.index_of_word_option ("-output") /= 0 and then not arguments.separate_word_option_value ("-output").is_equal ("") then main_class_name := arguments.separate_word_option_value ("-output") else main_class_name := input_file_name.substring (1, input_file_name.count - 4) end if arguments.index_of_word_option ("-no-singleton") /= 0 then no_singleton := true end process_additional_parameters shared_class_name := "shared_" + main_class_name end end if not has_error then io.put_string ("Parsing " + input_file_name + "...%N") parse has_error := parser_xml_filter.has_error if not has_error and parser_xml_filter.xml_table /= void then xml_table := parser_xml_filter.xml_table generate_classes end end if has_error then io.put_string ("Failed%N") end end process_additional_parameters is -- process additional command line parameters do end generate_classes is -- generate the classes and write the files require not_has_error: not has_error deferred end parse is -- parse the input xml file require input_file_name /= void local input_file: PLAIN_TEXT_FILE do create input_file.make (input_file_name) create xml_parser.make create parser_xml_filter.make_null xml_parser.set_callbacks (callbacks_pipe (<>)) if input_file /= void and then input_file.exists and then input_file.is_readable then input_file.open_read input_file.read_stream (input_file.count) xml_parser.parse_from_string (input_file.last_string) input_file.close else print_error ("failed reading input file") end end generate_main_class is -- Generate the Main class require xml_table /= void not has_error deferred end generate_shared_class is -- Generate class with the singleton require not_has_error: not has_error deferred end write_main_file is -- write the main file to disk require not has_error main_class_name /= void local main_file: PLAIN_TEXT_FILE do create main_file.make_open_write (main_class_name + ".e") if main_file.is_open_write then main_file.put_string (main_class_content) else print_error ("Could not open file " + main_class_name + ".e for writing%N") end end write_shared_file is -- write the shared file to disk require not has_error shared_class_name /= void local shared_file: PLAIN_TEXT_FILE do create shared_file.make_open_write (shared_class_name + ".e") if shared_file.is_open_write then shared_file.put_string (shared_class_content) else print_error ("Could not open file " + shared_class_name + ".e for writing%N") end end feature -- Code Generators do_not_edit_message: STRING is require not has_error local i: INTEGER do create Result.make_empty Result.append_string("%T%TTHIS CLASS WAS AUTO-GENERATED WITH THE COMMAND%N") Result.append_string ("%T%T" + cropped_program_name (arguments.program_name)) from i := 1 until i > arguments.argument_count loop Result.append_string (" " + arguments.argument (i)) i := i + 1 end Result.append_string("%N") Result.append_string ("%T%TDO NOT EDIT THIS CLASS") end feature -- helper functions print_help is -- print help for the command line tool deferred end print_error (an_error: STRING) is -- Print an error message do has_error := true io.put_string("Error: " + an_error + "%N") end cropped_program_name (a_name_with_path: STRING): STRING is -- Return program name (without the path) require a_name_with_path /= void a_name_with_path.count > 0 local program_name: STRING do program_name := arguments.program_name -- remove path program_name := program_name.substring (program_name.last_index_of ('/', program_name.count) + 1, program_name.count) program_name := program_name.substring (program_name.last_index_of ('\', program_name.count) + 1, program_name.count) Result := program_name end attributes_ok: BOOLEAN check_for_attributes(the_attributes: ARRAY[STRING]; an_entry: DS_HASH_TABLE[STRING, STRING]) is -- Check if an XML-entry has all needed arguments require the_attributes /= void the_attributes.count > 0 an_entry /= void local i: INTEGER do attributes_ok := true if not an_entry.has ("name") then print_error ("Name missing") attributes_ok := false else from i := 1 until i > the_attributes.count loop if not an_entry.has (the_attributes.item (i)) then attributes_ok := false print_error ("Attribute %"" + the_attributes.item (i) + "%" missing (setting name: " + an_entry.item ("name") + ")") end i := i + 1 end end end feature -- Attributes xml_parser: XM_EIFFEL_PARSER parser_xml_filter: EM_CLASS_GENERATOR_XM_FILTER xml_table: DS_HASH_TABLE[DS_LINKED_LIST[DS_HASH_TABLE[STRING, STRING]], STRING] input_file_name: STRING main_class_name: STRING shared_class_name: STRING main_class_content: STRING shared_class_content: STRING has_error: BOOLEAN no_singleton: BOOLEAN end