1#! perl 2#--------------------------------------------------------------------------- 3# Project: TwlSDK - xml2env 4# File: xml2env.pl 5# 6# Copyright 2005-2008 Nintendo. All rights reserved. 7# 8# These coded instructions, statements, and computer programs contain 9# proprietary information of Nintendo of America Inc. and/or Nintendo 10# Company Ltd., and are protected by Federal copyright law. They may 11# not be disclosed to third parties or copied or duplicated in any form, 12# in whole or in part, without the prior written consent of Nintendo. 13# 14# $Date:: 2008-09-18#$ 15# $Rev: 8573 $ 16# $Author: okubata_ryoma $ 17#--------------------------------------------------------------------------- 18 19 20use strict; 21 22# Check availability of XML::Parser 23if (eval "require XML::Parser; return 1;" != 1){ 24 printf "Use cygwin setup to insert the newest version of Perl and the expat library. Set up an environment that allows you to use XML::Parser. Then run again. \n"; 25 exit; 26} 27 28require Getopt::Std; 29require XML::Parser; 30 31# Specify access to the handler routine as a parameter and initialize the parser 32my $parser = XML::Parser -> new(Handlers => { 33 Init => \&handle_doc_start, 34 Final => \&handle_doc_end, 35 Start => \&handle_elem_start, 36 End => \&handle_elem_end, 37 Char => \&handle_char_data, 38}); 39 40my (%opts); 41my $c = Getopt::Std::getopts('o:h', \%opts); 42 43my ($src, $tmp, $line, $resource_name, $resource_count); 44 45# Output filename used when no options have been attached 46$tmp = $src . '.result.c'; 47 48 49# h for help 50if(exists $opts{h} || scalar(@ARGV) < 1){ 51 print "After the command enter one argument (the .xml file you want to search) \n"; 52 print "Input example: perl xml2env.pl d:/test/main.xml \n"; 53 print "In the above example, the file is in d:/test/ \n"; 54 print "If in the argument you enter "-o\" followed by a file name, the script will output to the file. \n"; 55 print "If you enter "-h\" in the argument, a simple help menu will be displayed. \n"; 56 die "$!"; 57} 58 59 60 61# Enter name of output file after the -o option 62if(exists $opts{o}){ 63 $tmp = $opts{o}; 64} 65 66# Enter the name of the file to be accessed without an option 67if(@ARGV){ 68 $src = $ARGV[$resource_count]; 69} 70 71open(FO, ">" . $tmp) or die ("cannot open $tmp to write."); 72 73my %default_type = ( 74 "u8" => "ENV_U8", 75 "s8" => "ENV_S8", 76 "u16" => "ENV_U16", 77 "s16" => "ENV_S16", 78 "u32" => "ENV_U32", 79 "s32" => "ENV_S32", 80 "u64" => "ENV_U64", 81 "s64" => "ENV_S64", 82 "bool" => "ENV_BOOL", 83 "string" => "ENV_STRING", 84 "hexbinary" => "ENV_BINARY" 85); 86 87$line = "/*---------------------------------------------------------------------------*/\n"; 88$line .= "#include <nitro.h>\n"; 89$line .= "//================================================================================\n"; 90$line .= "\n"; 91print FO $line; 92 93 94# Read data and parse 95my $file = $src; 96if($file){ 97 $parser->parsefile($file); 98} 99else{ 100 my $input = ""; 101 while(<STDIN>){ $input .= $_; } 102 $parser->parse($input); 103} 104 105close(FO); 106exit; 107 108my ($record, $context, $resource_names, $datafile_name); 109 110# Handler 111 112# Output the top of the file simultaneously as processing starts 113sub handle_doc_start{ 114 print ""; 115} 116my ($class_name, $class_context); 117# Parser is called each time the launch of a new element is encountered 118sub handle_elem_start{ 119 my($expat, $name, %atts) = @_; 120 $context = $name; 121 122 if($name =~ /resource/i){ 123 $resource_names .= " $atts{'name'},"; 124 print "ENVResource $atts{'name'}\[\] = {\n"; 125 print FO "ENVResource $atts{'name'}\[\] = {\n"; 126 } 127 elsif($name =~ /class/i){ 128 $class_name = $atts{'name'}; 129 } 130 else{ 131 # In the loop, search for items coming under default_type and process 132 foreach my $i(keys %default_type){ 133 if($name =~ /$i/i){ 134 $class_context = "\"$class_name\.$atts{'name'}\",\t". "$default_type{$name}"; 135 if($name =~ /hexbinary/i){ 136 if(exists $atts{'src'}){ 137 $datafile_name = $atts{'src'}; 138 # Initialize attribute values used when loading files 139 $atts{'src'} = undef; 140 } 141 } 142 } 143 } 144 } 145} 146 147# Store element-internal character data in the latest element buffer 148sub handle_char_data{ 149 my($expat, $text) = @_; 150 151 $record->{$context} .= $text; 152 153} 154my ($line, $filedata, $char); 155# Call the parser each time the close of a new element is encountered 156sub handle_elem_end{ 157 my($expat, $name) = @_; 158 if($name =~ /resource/i){ 159 print " ENV_RESOUCE_END\n};\n\n"; 160 print FO " ENV_RESOUCE_END\n};\n\n"; 161 } 162 # When the element name is not 'class' 163 elsif($name ne 'class'){ 164 if($name =~ /hexbinary/i){ 165 # When the element name is 'hexbinary' and it is necessary to load a file 166 if($datafile_name){ 167 open(FP, "<" . $datafile_name) or die ("cannot open $datafile_name to read."); 168 while(!eof(FP)) { 169 $char = getc FP; 170 # Convert text to ASCII code 171 $char = unpack("C", $char); 172 # Convert ASCII code to hexadecimal 173 $char = sprintf("%x", $char); 174 $filedata .= '\x' . $char; 175 } 176 print " $class_context( \"$filedata\" ),\n"; 177 print FO " $class_context( \"$filedata\" ),\n"; 178 # Initialize file read flag 179 $datafile_name = undef; 180 $filedata = ""; 181 } 182 else{ 183 my @ascii; 184 my $hexdata; 185 # Convert text to ASCII code 186 @ascii = unpack("C*", $record->{$context}); 187 foreach my $i(@ascii){ 188 # Convert ASCII code to hexadecimal 189 $hexdata .= '\x' . sprintf("%x", $i); 190 } 191 print " $class_context( \"$hexdata\" ),\n"; 192 print FO " $class_context( \"$hexdata\" ),\n"; 193 # Initialize text each time 194 $record->{$context} = ""; 195 } 196 } 197 elsif($name =~ /string/i){ 198 $record->{$context} =~ s/(["\\])/\\$1/g; 199 $record->{$context} =~ s/[\n]/\\n/g; 200 $record->{$context} =~ s/[\t]/\\t/g; 201 print " $class_context( \"$record->{$context}\" ),\n"; 202 print FO " $class_context( \"$record->{$context}\" ),\n"; 203 # Initialize text each time 204 $record->{$context} = ""; 205 } 206 else{ 207 # In the loop, search for items coming under default_type and process 208 foreach my $i(keys %default_type){ 209 if($name =~ /$i/i){ 210 print " $class_context( $record->{$context} ),\n"; 211 print FO " $class_context( $record->{$context} ),\n"; 212 # Initialize text each time 213 $record->{$context} = ""; 214 } 215 } 216 } 217 # Initialize text 218 $class_context = ""; 219 $context = ""; 220 } 221} 222 223# Output end of file last 224sub handle_doc_end{ 225 print "ENVResource* resourceArray\[\]={"; 226 print FO "ENVResource* resourceArray\[\]={"; 227 print "$resource_names"; 228 print FO "$resource_names"; 229 print " NULL };"; 230 print FO " NULL };"; 231} 232 233