changes to support UTF-8 encoding from
[webpac] / openisis / oipc
1 #!/usr/bin/perl -w
2 #/*
3 #       openisis - an open implementation of the CDS/ISIS database
4 #       Version 0.8.x (patchlevel see file Version)
5 #       Copyright (C) 2001-2003 by Erik Grziwotz, erik@openisis.org
6 #
7 #       This library is free software; you can redistribute it and/or
8 #       modify it under the terms of the GNU Lesser General Public
9 #       License as published by the Free Software Foundation; either
10 #       version 2.1 of the License, or (at your option) any later version.
11 #
12 #       This library is distributed in the hope that it will be useful,
13 #       but WITHOUT ANY WARRANTY; without even the implied warranty of
14 #       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 #       Lesser General Public License for more details.
16 #
17 #       You should have received a copy of the GNU Lesser General Public
18 #       License along with this library; if not, write to the Free Software
19 #       Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20 #
21 #       see README for more information
22 #EOH */
23
24 # $Id: oipc,v 1.2 2003/04/08 00:20:53 kripke Exp $
25 #
26 #       usage
27 #       ./oipc foo.oip gcc %o && ./a.out
28 #       ./oipc foo.oip gcc %o -shared -o foo.oip.so && ./oipl $PWD/foo.oip.so
29
30
31 sub mk {
32         my $ifile = shift;
33         my $ofile = $ifile . '.c';
34         my $buf = ''; # collected strings from output mode
35         my @code = ('',''); # main and global code
36         my $code = 0, $state = -1; 
37         # -1: file header
38         # 0: stuff to output literally 
39         # run code:
40         #       1: in <%
41         #       2: in <%=
42         # global code:
43         #       3: in <%!
44         #       4: in <%@
45         die "could not read $ifile" unless open I, $ifile;
46         # transform line by line
47         LIN: while (<I>) {
48                 if ( -1 == $state ) { # skipping initial # lines
49                         next if /^#/;
50                         $state = 0; # switch to output state
51                 }
52                 while (1) {
53                         if ( ! $state ) { # output up to <%
54                                 my ($o,$s,$m,$x) = /^(.*?)(<%([=!@])?(.*))?$/s;
55                                 if ( length $o ) {
56                                         $o =~ s/\\/\\\\/g;
57                                         $o =~ s/"/\\"/g;
58                                         if ( defined $s ) {
59                                                 $buf .= '"' . $o . '"';
60                                         } else {
61                                                 $buf .= '"' . $o . '\n"' . "\n";
62                                         }
63                                 }
64                                 next LIN unless defined $s;
65                                 $code[$code] .= "\tOIPS(\n".$buf."\t);\n" if length $buf;
66                                 $buf = '';
67                                 ($m ||= 0) =~ y/=!@/123/;
68                                 $state = 1+$m;
69                                 $code = 2 < $state ? 1 : 0;
70                                 $_ = $x;
71                                 $code[$code] .= "\n#line ".$.."\n";
72                                 next LIN unless length $x;
73                         }
74                         my ($x,$s,$m,$o) = /^(.*?)((!)?%>(.*))?$/s;
75                         $buf .= $x;
76                         if ( defined $s ) {
77                                 if ( 2 == $state ) { # <%=
78                                         if ( 1 == length $buf ) {
79                                                 if ( $buf =~ /[i-n]/ ) { # integer shorthand
80                                                         $buf = '"%d",'.$buf;
81                                                 } elsif ( $buf =~ /[u-w]/ ) { # unsigned shorthand
82                                                         $buf = '"%u",'.$buf;
83                                                 } elsif ( $buf =~ /[f-h]/ ) { # OpenIsis Field shorthand
84                                                         $buf = '"%.*s",'.$buf.'->len,'.$buf.'->val';
85                                                 }
86                                         }
87                                         if ( $buf =~ /^\s*"/ ) {
88                                                 $buf = 'OIPP(OIPF,'.$buf.');';
89                                         } else {
90                                                 $buf = 'OIPS('.$buf.');';
91                                         }
92                                 }
93                                 $code[$code] .= $buf;
94                                 # don't reset print code destination if global ends with !%>
95                                 $code = 0 unless $code && defined $m;
96                                 $state = 0;
97                                 if ( length $o ) {
98                                         $buf = '';
99                                         $_ = $o;
100                                         next;
101                                 }
102                                 $buf = '"\n"';
103                         } else {
104                                 $buf .= "\n";
105                         }
106                         last;
107                 }
108         }
109         close I;
110         $code[0] .= "OIPS(\n".$buf.");\n" if length $buf;
111         die "could not write $ofile" unless open O, '>', $ofile;
112         print O '#include "oip.h"',"\n";
113         print O $code[1];
114         print O "OIPRUN\n";
115         print O $code[0];
116         print O "OIPEND\n";
117         close O;
118         map s/%o/$ofile/, @_;
119         die 'exec '.join(' ',@_)." failed\n" unless exec @_;
120 }
121
122 mk @ARGV;