1: 2 eval 'exec perl -S $0 ${1+"$@"}' 3 if 0; 4#************************************************************** 5# 6# Licensed to the Apache Software Foundation (ASF) under one 7# or more contributor license agreements. See the NOTICE file 8# distributed with this work for additional information 9# regarding copyright ownership. The ASF licenses this file 10# to you under the Apache License, Version 2.0 (the 11# "License"); you may not use this file except in compliance 12# with the License. You may obtain a copy of the License at 13# 14# http://www.apache.org/licenses/LICENSE-2.0 15# 16# Unless required by applicable law or agreed to in writing, 17# software distributed under the License is distributed on an 18# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 19# KIND, either express or implied. See the License for the 20# specific language governing permissions and limitations 21# under the License. 22# 23#************************************************************** 24 25 26 27sub usage() { 28 print "Usage: api-to-idl.pl source.api destination_path\n"; 29 print; 30 print "This tool converts oovbaapi *.api files into *.idl's.\n"; 31 exit 1; 32} 33 34my $src = shift; 35my $dest = shift; 36 37if ( !defined( $src ) || !defined( $dest ) || $src eq "-h" || $src eq "--help" ) { 38 usage(); 39} 40 41# Parsing functions 42my $state = ""; 43my $source = ""; 44my $name = ""; 45my $value = ""; 46 47my %result; 48 49# Process element start event 50sub start_element($) { 51 my ($el) = @_; 52 53 @element_attr = split( /\s+/, $el ); 54 my $element = $element_attr[0]; 55 56 if ( $element eq "element" ) { 57 if ( $element_attr[1] =~ /type="?([^"]*)"?/ && $1 eq "constant" ) { 58 $state = "constant"; 59 $source = ""; 60 $name = ""; 61 $value = ""; 62 } 63 } 64 elsif ( $state eq "constant" && $element eq "source" ) { 65 $state = "source"; 66 if ( $element_attr[1] =~ /id="?([^"]*)"?/ ) { 67 chomp( $source = $1 ); 68 } 69 } 70 elsif ( $state eq "source" && $element eq "name" ) { 71 $state = "name"; 72 } 73 elsif ( $state eq "source" && $element eq "value" ) { 74 $state = "value"; 75 } 76} 77 78# Process element end event 79sub end_element($) { 80 my ($element) = @_; 81 82 if ( $state eq "name" && $element eq "name" ) { 83 $state = "source"; 84 } 85 elsif ( $state eq "value" && $element eq "value" ) { 86 $state = "source"; 87 } 88 elsif ( $state ne "" && $element eq "element" ) { 89 $state = ""; 90 91 my @destination = split( /\./, $source ); 92 my $module = shift( @destination ); 93 my $type = shift( @destination ); 94 95 $module =~ tr/[A-Z]/[a-z]/; 96 97 $result{$module} = {} unless exists $result{$module}; 98 $result{$module}{$type} = [] unless exists $result{$module}{$type}; 99 100 push( @{$result{$module}{$type}}, 101 { "name" => $name, "value" => $value } ); 102 } 103} 104 105# Process characters 106sub characters($) { 107 my ($data) = @_; 108 109 if ( $state eq "name" ) { 110 chomp( $name = $data ); 111 } 112 elsif ( $state eq "value" ) { 113 chomp( $value = $data ); 114 } 115} 116 117# Create idls from the parsed data 118sub generate_idls($) { 119 my ($path) = @_; 120 121 foreach $module ( keys %result ) { 122 foreach $type ( keys %{$result{$module}} ) { 123 my $fname = $path . "/" . $type . ".idl"; 124 open( IDL, ">$fname" ) || die "Cannot write $fname."; 125 126 if( $module eq "vba" ) { 127 print IDL "module ooo { module $module {\n"; 128 } 129 else { 130 print IDL "module ooo { module vba { module $module {\n"; 131 } 132 133 print IDL " constants $type {\n"; 134 foreach $constant ( @{$result{$module}{$type}} ) { 135 print IDL " const long $constant->{'name'} = $constant->{'value'};\n"; 136 } 137 if( $module eq "vba" ) { 138 print IDL " };\n}; };\n"; 139 } 140 else { 141 print IDL " };\n}; }; };\n"; 142 } 143 144 close( IDL ); 145 } 146 } 147} 148 149# Parse the input 150open( IN, "<$src" ) || die "Cannot open $src."; 151 152my $in_comment = 0; 153my $line = ""; 154while (<IN>) { 155 # ignore comments 156 s/<!--[^>]*-->//g; 157 if ( /<!--/ ) { 158 $in_comment = 1; 159 s/<!--.*//; 160 } 161 elsif ( /-->/ && $in_comment ) { 162 $in_comment = 0; 163 s/.*-->//; 164 } 165 elsif ( $in_comment ) { 166 next; 167 } 168 # ignore empty lines 169 chomp; 170 s/^\s*//; 171 s/\s*$//; 172 next if ( $_ eq "" ); 173 174 # take care of lines where element continues 175 if ( $line ne "" ) { 176 $line .= " " . $_; 177 } 178 else { 179 $line = $_; 180 } 181 next if ( !/>$/ ); 182 183 # the actual parsing 184 my @starts = split( /</, $line ); 185 $line = ""; 186 foreach $start ( @starts ) { 187 next if ( $start eq "" ); 188 189 @ends = split( />/, $start ); 190 my $element = $ends[0]; 191 my $data = $ends[1]; 192 193 # start or end element 194 if ( $element =~ /^\/(.*)/ ) { 195 end_element( $1 ); 196 } 197 else { 198 start_element( $element ); 199 } 200 201 # the data 202 characters( $data ); 203 } 204} 205close( IN ); 206 207# Generate the output 208generate_idls($dest); 209