perl 5.000
[p5sagit/p5-mst-13.2.git] / h2ph.SH
CommitLineData
154e51a4 1case $CONFIG in
2'')
3 if test ! -f config.sh; then
4 ln ../config.sh . || \
5 ln ../../config.sh . || \
6 ln ../../../config.sh . || \
7 (echo "Can't find config.sh."; exit 1)
fe14fcc3 8 fi 2>/dev/null
e5d73d77 9 . ./config.sh
154e51a4 10 ;;
11esac
12: This forces SH files to create target in same directory as SH file.
13: This is so that make depend always knows where to find SH derivatives.
14case "$0" in
15*/*) cd `expr X$0 : 'X\(.*\)/'` ;;
16esac
17echo "Extracting h2ph (with variable substitutions)"
18: This section of the file will have variable substitutions done on it.
19: Move anything that needs config subs from !NO!SUBS! section to !GROK!THIS!.
20: Protect any dollar signs and backticks that you do not want interpreted
21: by putting a backslash in front. You may delete these comments.
bee1dbe2 22rm -f h2ph
154e51a4 23$spitshell >h2ph <<!GROK!THIS!
24#!$bin/perl
a0d0e21e 25'di ';
26'ds 00 \"';
27'ig 00 ';
154e51a4 28
a0d0e21e 29\$perlincl = '$archlibexp';
154e51a4 30!GROK!THIS!
31
32: In the following dollars and backticks do not need the extra backslash.
33$spitshell >>h2ph <<'!NO!SUBS!'
34
35chdir '/usr/include' || die "Can't cd /usr/include";
36
fe14fcc3 37@isatype = split(' ',<<END);
38 char uchar u_char
39 short ushort u_short
40 int uint u_int
41 long ulong u_long
42 FILE
43END
44
55204971 45@isatype{@isatype} = (1) x @isatype;
fe14fcc3 46
47@ARGV = ('-') unless @ARGV;
154e51a4 48
49foreach $file (@ARGV) {
fe14fcc3 50 if ($file eq '-') {
51 open(IN, "-");
52 open(OUT, ">-");
53 }
54 else {
55 ($outfile = $file) =~ s/\.h$/.ph/ || next;
56 print "$file -> $outfile\n";
57 if ($file =~ m|^(.*)/|) {
58 $dir = $1;
59 if (!-d "$perlincl/$dir") {
60 mkdir("$perlincl/$dir",0777);
61 }
154e51a4 62 }
fe14fcc3 63 open(IN,"$file") || ((warn "Can't open $file: $!\n"),next);
64 open(OUT,">$perlincl/$outfile") || die "Can't create $outfile: $!\n";
154e51a4 65 }
154e51a4 66 while (<IN>) {
67 chop;
68 while (/\\$/) {
69 chop;
70 $_ .= <IN>;
71 chop;
72 }
73 if (s:/\*:\200:g) {
74 s:\*/:\201:g;
75 s/\200[^\201]*\201//g; # delete single line comments
76 if (s/\200.*//) { # begin multi-line comment?
77 $_ .= '/*';
78 $_ .= <IN>;
79 redo;
80 }
81 }
82 if (s/^#\s*//) {
83 if (s/^define\s+(\w+)//) {
84 $name = $1;
85 $new = '';
86 s/\s+$//;
87 if (s/^\(([\w,\s]*)\)//) {
88 $args = $1;
89 if ($args ne '') {
90 foreach $arg (split(/,\s*/,$args)) {
55204971 91 $arg =~ s/^\s*([^\s].*[^\s])\s*$/$1/;
154e51a4 92 $curargs{$arg} = 1;
93 }
94 $args =~ s/\b(\w)/\$$1/g;
95 $args = "local($args) = \@_;\n$t ";
96 }
97 s/^\s+//;
98 do expr();
99 $new =~ s/(["\\])/\\$1/g;
100 if ($t ne '') {
101 $new =~ s/(['\\])/\\$1/g;
102 print OUT $t,
103 "eval 'sub $name {\n$t ${args}eval \"$new\";\n$t}';\n";
104 }
105 else {
106 print OUT "sub $name {\n ${args}eval \"$new\";\n}\n";
107 }
108 %curargs = ();
109 }
110 else {
111 s/^\s+//;
112 do expr();
113 $new = 1 if $new eq '';
114 if ($t ne '') {
115 $new =~ s/(['\\])/\\$1/g;
116 print OUT $t,"eval 'sub $name {",$new,";}';\n";
117 }
118 else {
119 print OUT $t,"sub $name {",$new,";}\n";
120 }
121 }
122 }
55204971 123 elsif (/^include\s+<(.*)>/) {
d9d8d8de 124 ($incl = $1) =~ s/\.h$/.ph/;
125 print OUT $t,"require '$incl';\n";
154e51a4 126 }
127 elsif (/^ifdef\s+(\w+)/) {
128 print OUT $t,"if (defined &$1) {\n";
129 $tab += 4;
130 $t = "\t" x ($tab / 8) . ' ' x ($tab % 8);
131 }
132 elsif (/^ifndef\s+(\w+)/) {
133 print OUT $t,"if (!defined &$1) {\n";
134 $tab += 4;
135 $t = "\t" x ($tab / 8) . ' ' x ($tab % 8);
136 }
137 elsif (s/^if\s+//) {
138 $new = '';
139 do expr();
140 print OUT $t,"if ($new) {\n";
141 $tab += 4;
142 $t = "\t" x ($tab / 8) . ' ' x ($tab % 8);
143 }
144 elsif (s/^elif\s+//) {
145 $new = '';
146 do expr();
147 $tab -= 4;
148 $t = "\t" x ($tab / 8) . ' ' x ($tab % 8);
149 print OUT $t,"}\n${t}elsif ($new) {\n";
150 $tab += 4;
151 $t = "\t" x ($tab / 8) . ' ' x ($tab % 8);
152 }
153 elsif (/^else/) {
154 $tab -= 4;
155 $t = "\t" x ($tab / 8) . ' ' x ($tab % 8);
156 print OUT $t,"}\n${t}else {\n";
157 $tab += 4;
158 $t = "\t" x ($tab / 8) . ' ' x ($tab % 8);
159 }
160 elsif (/^endif/) {
161 $tab -= 4;
162 $t = "\t" x ($tab / 8) . ' ' x ($tab % 8);
163 print OUT $t,"}\n";
164 }
165 }
166 }
167 print OUT "1;\n";
168}
169
170sub expr {
171 while ($_ ne '') {
172 s/^(\s+)// && do {$new .= ' '; next;};
173 s/^(0x[0-9a-fA-F]+)// && do {$new .= $1; next;};
174 s/^(\d+)// && do {$new .= $1; next;};
175 s/^("(\\"|[^"])*")// && do {$new .= $1; next;};
176 s/^'((\\"|[^"])*)'// && do {
177 if ($curargs{$1}) {
178 $new .= "ord('\$$1')";
179 }
180 else {
181 $new .= "ord('$1')";
182 }
183 next;
184 };
154e51a4 185 s/^sizeof\s*\(([^)]+)\)/{$1}/ && do {
186 $new .= '$sizeof';
187 next;
188 };
189 s/^([_a-zA-Z]\w*)// && do {
190 $id = $1;
fe14fcc3 191 if ($id eq 'struct') {
192 s/^\s+(\w+)//;
193 $id .= ' ' . $1;
194 $isatype{$id} = 1;
195 }
196 elsif ($id eq 'unsigned') {
197 s/^\s+(\w+)//;
198 $id .= ' ' . $1;
199 $isatype{$id} = 1;
200 }
154e51a4 201 if ($curargs{$id}) {
202 $new .= '$' . $id;
203 }
204 elsif ($id eq 'defined') {
205 $new .= 'defined';
206 }
207 elsif (/^\(/) {
e5d73d77 208 s/^\((\w),/("$1",/ if $id =~ /^_IO[WR]*$/i; # cheat
154e51a4 209 $new .= " &$id";
210 }
211 elsif ($isatype{$id}) {
fe14fcc3 212 if ($new =~ /{\s*$/) {
213 $new .= "'$id'";
214 }
215 elsif ($new =~ /\(\s*$/ && /^[\s*]*\)/) {
216 $new =~ s/\(\s*$//;
217 s/^[\s*]*\)//;
218 }
219 else {
220 $new .= $id;
221 }
154e51a4 222 }
223 else {
224 $new .= ' &' . $id;
225 }
226 next;
227 };
228 s/^(.)// && do {$new .= $1; next;};
229 }
230}
231##############################################################################
232
233 # These next few lines are legal in both Perl and nroff.
234
a0d0e21e 235.00 ; # finish .ig
236
154e51a4 237'di \" finish diversion--previous line must be blank
238.nr nl 0-1 \" fake up transition to first page again
239.nr % 0 \" start at page 1
240'; __END__ ############# From here on it's a standard manual page ############
241.TH H2PH 1 "August 8, 1990"
242.AT 3
243.SH NAME
244h2ph \- convert .h C header files to .ph Perl header files
245.SH SYNOPSIS
246.B h2ph [headerfiles]
247.SH DESCRIPTION
248.I h2ph
249converts any C header files specified to the corresponding Perl header file
250format.
251It is most easily run while in /usr/include:
252.nf
253
254 cd /usr/include; h2ph * sys/*
255
256.fi
fe14fcc3 257If run with no arguments, filters standard input to standard output.
154e51a4 258.SH ENVIRONMENT
259No environment variables are used.
260.SH FILES
261/usr/include/*.h
262.br
263/usr/include/sys/*.h
264.br
265etc.
266.SH AUTHOR
267Larry Wall
268.SH "SEE ALSO"
269perl(1)
270.SH DIAGNOSTICS
271The usual warnings if it can't read or write the files involved.
272.SH BUGS
273Doesn't construct the %sizeof array for you.
274.PP
275It doesn't handle all C constructs, but it does attempt to isolate
276definitions inside evals so that you can get at the definitions
277that it can translate.
278.PP
279It's only intended as a rough tool.
280You may need to dicker with the files produced.
281.ex
282!NO!SUBS!
283chmod 755 h2ph
284$eunicefix h2ph
285rm -f h2ph.man
286ln h2ph h2ph.man