Commit | Line | Data |
---|---|---|
a0d0e21e LW |
1 | #!/usr/bin/perl |
2 | 'di '; | |
3 | 'ds 00 \"'; | |
4 | 'ig 00 '; | |
5 | ||
6 | use Getopt::Std; | |
7 | ||
8 | $usage='h2xs [-Aachfm] [-n module_name] [headerfile [extra_libraries]] | |
9 | -a Omit AutoLoad facilities from .pm file. | |
10 | -c Omit the constant() function from the XS file. | |
11 | -A Equivalent to -a -c | |
12 | -f Force creation of the extension even if the C header does not exist. | |
13 | -m Also create an old-style Makefile.SH | |
14 | -h help | |
15 | -n Specify a name to use for the extension. | |
16 | extra_libraries are any libraries that might be needed for loading | |
17 | the extension, e.g. -lm would try to link in the math library. | |
18 | '; | |
19 | ||
20 | sub usage{ die "Usage: $usage\n" } | |
21 | ||
22 | getopts("fhcaAmn:") || &usage; | |
23 | ||
24 | &usage if $opt_h; | |
25 | ||
26 | if( @ARGV ){ | |
27 | $path_h = shift; | |
28 | } | |
29 | elsif( ! @ARGV && ! $opt_n ){ | |
30 | die "Must supply header file or module name\n"; | |
31 | } | |
32 | ||
33 | $extralibs = "@ARGV"; | |
34 | if( $opt_A ){ | |
35 | $opt_a = $opt_c = 1; | |
36 | } | |
37 | $write_makefile_sh = ($opt_m) ? 1 : 0; | |
38 | ||
39 | if( $path_h ){ | |
40 | $name = $path_h; | |
41 | if( $path_h =~ s#::#/#g && $opt_n ){ | |
42 | warn "Nesting of headerfile ignored with -n\n"; | |
43 | } | |
44 | $path_h .= ".h" unless $path_h =~ /\.h$/; | |
45 | $path_h = "/usr/include/$path_h" unless $path_h =~ m#^[./]#; | |
46 | die "Can't find $path_h\n" if( ! $opt_f && ! -f $path_h ); | |
47 | } | |
48 | ||
49 | $module = $opt_n || do { | |
50 | $name =~ s/\.h$//; | |
51 | if( $name !~ /::/ ){ | |
52 | $name =~ s#^.*/##; | |
53 | $name = "\u$name"; | |
54 | } | |
55 | $name; | |
56 | }; | |
57 | ||
58 | chdir 'ext' if -d 'ext'; | |
59 | ||
60 | if( $module =~ /::/ ){ | |
61 | $nested = 1; | |
62 | @modparts = split(/::/,$module); | |
63 | $modfname = $modparts[-1]; | |
64 | $modpname = join('/',@modparts); | |
65 | } | |
66 | else { | |
67 | $nested = 0; | |
68 | @modparts = (); | |
69 | $modfname = $modpname = $module; | |
70 | } | |
71 | ||
72 | ||
73 | die "Won't overwrite existing ext/$modpname\n" if -e $modpname; | |
74 | # quick hack, should really loop over @modparts | |
75 | mkdir($modparts[0], 0777) if $nested; | |
76 | mkdir($modpname, 0777); | |
77 | chdir($modpname) || die "Can't chdir ext/$modpname: $!\n"; | |
78 | ||
79 | open(XS, ">$modfname.xs") || die "Can't create ext/$modpname/$modfname.xs: $!\n"; | |
80 | open(PM, ">$modfname.pm") || die "Can't create ext/$modpname/$modfname.pm: $!\n"; | |
81 | ||
82 | ||
83 | if( -r $path_h ){ | |
84 | open(CH, "<$path_h") || die "Can't open $path_h: $!\n"; | |
85 | while (<CH>) { | |
86 | if (/^#[ \t]*define\s+(\w+)\b\s*[^("]/) { | |
87 | $_ = $1; | |
88 | next if /^_.*_h_*$/i; | |
89 | $names{$_}++; | |
90 | @AZ = 'A' .. 'Z' if !@AZ && /^[A-Z]/; | |
91 | @az = 'a' .. 'z' if !@az && /^[a-z]/; | |
92 | @under = '_' if !@under && /^_/; | |
93 | } | |
94 | } | |
95 | close(CH); | |
96 | @names = sort keys %names; | |
97 | } | |
98 | ||
99 | $" = "\n\t"; | |
100 | warn "Writing ext/$modpname/$modfname.pm\n"; | |
101 | ||
102 | if( ! $opt_a ){ | |
103 | print PM <<"END"; | |
104 | package $module; | |
105 | ||
106 | require Exporter; | |
107 | require AutoLoader; | |
108 | require DynaLoader; | |
109 | \@ISA = qw(Exporter AutoLoader DynaLoader); | |
110 | # Items to export into callers namespace by default | |
111 | # (move infrequently used names to \@EXPORT_OK below) | |
112 | \@EXPORT = qw( | |
113 | @names | |
114 | ); | |
115 | # Other items we are prepared to export if requested | |
116 | \@EXPORT_OK = qw( | |
117 | ); | |
118 | ||
119 | sub AUTOLOAD { | |
120 | if (\@_ > 1) { | |
121 | \$AutoLoader::AUTOLOAD = \$AUTOLOAD; | |
122 | goto &AutoLoader::AUTOLOAD; | |
123 | } | |
124 | local(\$constname); | |
125 | (\$constname = \$AUTOLOAD) =~ s/.*:://; | |
126 | \$val = constant(\$constname, \@_ ? \$_[0] : 0); | |
127 | if (\$! != 0) { | |
128 | if (\$! =~ /Invalid/) { | |
129 | \$AutoLoader::AUTOLOAD = \$AUTOLOAD; | |
130 | goto &AutoLoader::AUTOLOAD; | |
131 | } | |
132 | else { | |
133 | (\$pack,\$file,\$line) = caller; | |
134 | die "Your vendor has not defined $module macro \$constname, used at \$file line \$line.\n"; | |
135 | } | |
136 | } | |
137 | eval "sub \$AUTOLOAD { \$val }"; | |
138 | goto &\$AUTOLOAD; | |
139 | } | |
140 | ||
141 | bootstrap $module; | |
142 | ||
143 | # Preloaded methods go here. Autoload methods go after __END__, and are | |
144 | # processed by the autosplit program. | |
145 | ||
146 | 1; | |
147 | __END__ | |
148 | END | |
149 | } | |
150 | else{ | |
151 | print PM <<"END"; | |
152 | package $module; | |
153 | ||
154 | require Exporter; | |
155 | require DynaLoader; | |
156 | \@ISA = qw(Exporter DynaLoader); | |
157 | # Items to export into callers namespace by default | |
158 | \@EXPORT = qw(); | |
159 | # Other items we are prepared to export if requested | |
160 | \@EXPORT_OK = qw(); | |
161 | ||
162 | ||
163 | bootstrap $module; | |
164 | ||
165 | 1; | |
166 | END | |
167 | } | |
168 | ||
169 | close PM; | |
170 | ||
171 | warn "Writing ext/$modpname/$modfname.xs\n"; | |
172 | print XS <<"END"; | |
173 | #include "EXTERN.h" | |
174 | #include "perl.h" | |
175 | #include "XSUB.h" | |
176 | ||
177 | END | |
178 | if( $path_h ){ | |
179 | my($h) = $path_h; | |
180 | $h =~ s#^/usr/include/##; | |
181 | print XS <<"END"; | |
182 | #include <$h> | |
183 | ||
184 | END | |
185 | } | |
186 | ||
187 | if( ! $opt_c ){ | |
188 | print XS <<"END"; | |
189 | static int | |
190 | not_here(s) | |
191 | char *s; | |
192 | { | |
193 | croak("$module::%s not implemented on this architecture", s); | |
194 | return -1; | |
195 | } | |
196 | ||
197 | static double | |
198 | constant(name, arg) | |
199 | char *name; | |
200 | int arg; | |
201 | { | |
202 | errno = 0; | |
203 | switch (*name) { | |
204 | END | |
205 | ||
206 | foreach $letter (@AZ, @az, @under) { | |
207 | ||
208 | last if $letter eq 'a' && !@names; | |
209 | ||
210 | print XS " case '$letter':\n"; | |
211 | my($name); | |
212 | while (substr($names[0],0,1) eq $letter) { | |
213 | $name = shift(@names); | |
214 | print XS <<"END"; | |
215 | if (strEQ(name, "$name")) | |
216 | #ifdef $name | |
217 | return $name; | |
218 | #else | |
219 | goto not_there; | |
220 | #endif | |
221 | END | |
222 | } | |
223 | print XS <<"END"; | |
224 | break; | |
225 | END | |
226 | } | |
227 | print XS <<"END"; | |
228 | } | |
229 | errno = EINVAL; | |
230 | return 0; | |
231 | ||
232 | not_there: | |
233 | errno = ENOENT; | |
234 | return 0; | |
235 | } | |
236 | ||
237 | ||
238 | MODULE = $module PACKAGE = $module | |
239 | ||
240 | double | |
241 | constant(name,arg) | |
242 | char * name | |
243 | int arg | |
244 | ||
245 | END | |
246 | } | |
247 | else{ | |
248 | print XS <<"END"; | |
249 | ||
250 | MODULE = $module PACKAGE = $module | |
251 | ||
252 | END | |
253 | } | |
254 | ||
255 | close XS; | |
256 | ||
257 | { | |
258 | warn "Writing ext/$modpname/Makefile.PL\n"; | |
259 | open(PL, ">Makefile.PL") || die "Can't create ext/$modpname/Makefile.PL: $!\n"; | |
260 | ||
261 | # Ideally this should have a #!../.. ... miniperl etc header | |
262 | print PL <<'END'; | |
263 | use ExtUtils::MakeMaker; | |
264 | # See lib/ExtUtils/MakeMaker.pm for details of how to influence | |
265 | # the contents of the Makefile being created. | |
266 | END | |
267 | print PL "&writeMakefile(\n"; | |
268 | print PL " 'potential_libs' => '$extralibs', # e.g., '-lm' \n"; | |
269 | print PL " 'INC' => '', # e.g., '-I/usr/include/other' \n"; | |
270 | print PL " 'DISTNAME' => 'myname',\n"; | |
271 | print PL " 'VERSION' => '0.1',\n"; | |
272 | print PL ");\n"; | |
273 | } | |
274 | ||
275 | if ($write_makefile_sh){ | |
276 | warn "Writing ext/$modpname/Makefile.SH\n"; | |
277 | open(MF, ">Makefile.SH") || die "Can't create ext/$modpname/Makefile.SH: $!\n"; | |
278 | print MF <<'END'; | |
279 | : This forces SH files to create target in same directory as SH file. | |
280 | : This is so that make depend always knows where to find SH derivatives. | |
281 | ||
282 | case "$0" in | |
283 | */*) cd `expr X$0 : 'X\(.*\)/'` ;; | |
284 | esac | |
285 | ||
286 | if test -f config.sh; then TOP=.; | |
287 | elif test -f ../config.sh; then TOP=..; | |
288 | elif test -f ../../config.sh; then TOP=../..; | |
289 | elif test -f ../../../config.sh; then TOP=../../..; | |
290 | elif test -f ../../../../config.sh; then TOP=../../../..; | |
291 | else | |
292 | echo "Can't find config.sh."; exit 1 | |
293 | fi | |
294 | ||
295 | : Find absolute path name for TOP. This is needed when we cd to TOP | |
296 | : to run perl on autosplit. | |
297 | oldpwd=`pwd`; cd $TOP; ABSTOP=`pwd`; cd $oldpwd | |
298 | ||
299 | case $CONFIG in | |
300 | '') | |
301 | . $TOP/config.sh | |
302 | ;; | |
303 | esac | |
304 | ||
305 | : Find out directory name. This is also the extension name. | |
306 | ext=`pwd | $sed -e 's@.*/@@'` | |
307 | ||
308 | : This extension might have its own typemap | |
309 | if test -f typemap; then | |
310 | exttypemap='typemap' | |
311 | else | |
312 | exttypemap='' | |
313 | fi | |
314 | ||
315 | : This extension might need additional libraries. | |
316 | END | |
317 | print MF "potential_libs=\"$extralibs\"\n"; | |
318 | print MF <<'END'; | |
319 | . $TOP/ext/util/extliblist | |
320 | ||
321 | : This extension might need bootstrap support | |
322 | if test -f ${ext}_BS; then | |
323 | bootdep=${ext}_BS | |
324 | else | |
325 | bootdep='' | |
326 | fi | |
327 | ||
328 | case "$dlsrc" in | |
329 | dl_aix*) | |
330 | echo "#!" > $ext.exp | |
331 | echo "boot_$ext" >> $ext.exp | |
332 | ;; | |
333 | esac | |
334 | ||
335 | echo "Extracting ext/$ext/Makefile (with variable substitutions)" | |
336 | : This section of the file will have variable substitutions done on it. | |
337 | : Move anything that needs config subs from !NO!SUBS! section to !GROK!THIS!. | |
338 | : Protect any dollar signs and backticks that you do not want interpreted | |
339 | : by putting a backslash in front. You may delete these comments. | |
340 | $spitshell >Makefile << !GROK!THIS! | |
341 | # | |
342 | # This Makefile is for the $ext extension to perl. | |
343 | # | |
344 | CC = $cc | |
345 | RANLIB = $ranlib | |
346 | TOP = $TOP | |
347 | ABSTOP = $ABSTOP | |
348 | LDFLAGS = $ldflags | |
349 | CLDFLAGS = $ldflags | |
350 | SMALL = $small | |
351 | LARGE = $large $split | |
352 | ||
353 | # To use an alternate make, set \\$altmake in config.sh. | |
354 | MAKE = ${altmake-make} | |
355 | ||
356 | EXT = $ext | |
357 | ||
358 | # $ext might have its own typemap | |
359 | EXTTYPEMAP = $exttypemap | |
360 | ||
361 | # $ext might have its own bootstrap support | |
362 | BOOTDEP = $bootdep | |
363 | BOOTSTRAP = $ext.bs | |
364 | ||
365 | # The following are used to build and install shared libraries for | |
366 | # dynamic loading. | |
367 | LDDLFLAGS = $lddlflags | |
368 | CCDLFLAGS = $ccdlflags | |
369 | CCCDLFLAGS = $cccdlflags | |
370 | SO = $so | |
371 | ||
372 | # $ext might need to be linked with some extra libraries. | |
373 | # EXTRALIBS = full list of libraries needed for static linking. | |
374 | # Only those libraries that actually exist are included. | |
375 | # DYNLOADLIBS = list of those libraries that are needed but can be | |
376 | # linked in dynamically on this platform. On SunOS, for | |
377 | # example, this would be .so* libraries, but not archive | |
378 | # libraries. The bootstrap file is installed only if | |
379 | # this list is not empty. | |
380 | # STATLOADLIBS = list of those libraries which must be statically | |
381 | # linked into the shared library. On SunOS 4.1.3, | |
382 | # for example, I have only an archive version of | |
383 | # -lm, and it must be linked in statically. | |
384 | EXTRALIBS = $extralibs | |
385 | DYNALOADLIBS = $dynaloadlibs | |
386 | STATLOADLIBS = $statloadlibs | |
387 | ||
388 | !GROK!THIS! | |
389 | ||
390 | $spitshell >>Makefile <<'!NO!SUBS!' | |
391 | ||
392 | # Where to put things: | |
393 | AUTO = $(TOP)/lib/auto | |
394 | INSTALLBOOT = $(AUTO)/$(EXT)/$(EXT).bs | |
395 | INSTALLDYNAMIC = $(AUTO)/$(EXT)/$(EXT).$(SO) | |
396 | INSTALLSTATIC = $(EXT).a | |
397 | INSTALLPM = $(TOP)/lib/$(EXT).pm | |
398 | ||
399 | PERL = $(ABSTOP)/miniperl | |
400 | XSUBPP = $(TOP)/ext/xsubpp | |
401 | SHELL = /bin/sh | |
402 | CCCMD = `sh $(shellflags) $(TOP)/cflags $@` | |
403 | ||
404 | .c.o: | |
405 | $(CCCMD) $(CCCDLFLAGS) -I$(TOP) $*.c | |
406 | ||
407 | all: dynamic | |
408 | # Phony target to force checking subdirectories. | |
409 | FORCE: | |
410 | ||
411 | # Target for Dynamic Loading: | |
412 | dynamic: $(INSTALLDYNAMIC) $(INSTALLPM) $(INSTALLBOOT) | |
413 | ||
414 | $(INSTALLDYNAMIC): $(EXT).o | |
415 | @test -d $(AUTO) || mkdir $(AUTO) | |
416 | @test -d $(AUTO)/$(EXT) || mkdir $(AUTO)/$(EXT) | |
417 | ld $(LDDLFLAGS) -o $@ $(EXT).o $(STATLOADLIBS) | |
418 | ||
419 | $(BOOTSTRAP): Makefile $(BOOTDEP) | |
420 | $(PERL) -I$(TOP)/lib $(TOP)/ext/util/mkbootstrap $(DYNALOADLIBS) | |
421 | touch $(BOOTSTRAP) | |
422 | ||
423 | $(INSTALLBOOT): $(BOOTSTRAP) | |
424 | @test ! -s $(BOOTSTRAP) || cp $(BOOTSTRAP) $@ | |
425 | ||
426 | # Target for Static Loading: | |
427 | static: $(INSTALLSTATIC) $(INSTALLPM) | |
428 | ||
429 | $(INSTALLSTATIC): $(EXT).o | |
430 | ar cr $@ $(EXT).o | |
431 | $(RANLIB) $@ | |
432 | echo $(EXTRALIBS) >> $(TOP)/ext.libs | |
433 | ||
434 | $(EXT).c: $(EXT).xs $(XSUBPP) $(TOP)/ext/typemap $(EXTTYPEMAP) $(TOP)/cflags Makefile | |
435 | $(PERL) $(XSUBPP) $(EXT).xs >tmp | |
436 | mv tmp $@ | |
437 | ||
438 | END | |
439 | if( ! $opt_a ){ | |
440 | print MF <<'END'; | |
441 | $(INSTALLPM): $(EXT).pm | |
442 | rm -f $@ | |
443 | cp $(EXT).pm $@ | |
444 | cd $(TOP); $(PERL) autosplit $(EXT) | |
445 | END | |
446 | } | |
447 | else { | |
448 | print MF <<'END'; | |
449 | $(INSTALLPM): $(EXT).pm | |
450 | cp $(EXT).pm $@ | |
451 | END | |
452 | } | |
453 | print MF <<'END'; | |
454 | ||
455 | clean: | |
456 | rm -f *.o *.a mon.out core $(EXT).c so_locations $(BOOTSTRAP) $(EXT).exp | |
457 | ||
458 | realclean: clean | |
459 | rm -f makefile Makefile | |
460 | rm -f $(INSTALLPM) $(INSTALLDYNAMIC) $(INSTALLSTATIC) $(INSTALLBOOT) | |
461 | rm -rf $(AUTO)/$(EXT) | |
462 | ||
463 | purge: realclean | |
464 | ||
465 | $(EXT).o : $(TOP)/EXTERN.h | |
466 | $(EXT).o : $(TOP)/perl.h | |
467 | $(EXT).o : $(TOP)/embed.h | |
468 | $(EXT).o : $(TOP)/config.h | |
469 | $(EXT).o : $(TOP)/unixish.h | |
470 | $(EXT).o : $(TOP)/handy.h | |
471 | $(EXT).o : $(TOP)/regexp.h | |
472 | $(EXT).o : $(TOP)/sv.h | |
473 | $(EXT).o : $(TOP)/util.h | |
474 | $(EXT).o : $(TOP)/form.h | |
475 | $(EXT).o : $(TOP)/gv.h | |
476 | $(EXT).o : $(TOP)/cv.h | |
477 | $(EXT).o : $(TOP)/opcode.h | |
478 | $(EXT).o : $(TOP)/op.h | |
479 | $(EXT).o : $(TOP)/cop.h | |
480 | $(EXT).o : $(TOP)/av.h | |
481 | $(EXT).o : $(TOP)/hv.h | |
482 | $(EXT).o : $(TOP)/mg.h | |
483 | $(EXT).o : $(TOP)/scope.h | |
484 | $(EXT).o : $(TOP)/pp.h | |
485 | $(EXT).o : $(TOP)/proto.h | |
486 | $(EXT).o : $(TOP)/XSUB.h | |
487 | ||
488 | Makefile: Makefile.SH $(TOP)/config.sh ; /bin/sh Makefile.SH | |
489 | $(TOP)/config.h: $(TOP)/config.sh; cd $(TOP); /bin/sh config_h.SH | |
490 | $(TOP)/embed.h: $(TOP)/config.sh; cd $(TOP); /bin/sh embed_h.SH | |
491 | $(TOP)/cflags: $(TOP)/config.sh; cd $(TOP); /bin/sh cflags.SH | |
492 | ||
493 | !NO!SUBS! | |
494 | chmod 755 Makefile | |
495 | $eunicefix Makefile | |
496 | ||
497 | END | |
498 | close MF; | |
499 | } | |
500 | ||
501 | system '/bin/ls > MANIFEST'; | |
502 | ||
503 | # this needs fixing | |
504 | # system '[ -f Makefile.SH ] && sh Makefile.SH'; | |
505 | # system '[ -f Makefile.PL ] && perl Makefile.PL'; | |
506 | ||
507 | ||
508 | ############################################################################## | |
509 | ||
510 | # These next few lines are legal in both Perl and nroff. | |
511 | ||
512 | .00 ; # finish .ig | |
513 | ||
514 | 'di \" finish diversion--previous line must be blank | |
515 | .nr nl 0-1 \" fake up transition to first page again | |
516 | .nr % 0 \" start at page 1 | |
517 | '; __END__ ############# From here on it's a standard manual page ############ | |
518 | .TH H2XS 1 "August 9, 1994" | |
519 | .AT 3 | |
520 | .SH NAME | |
521 | h2xs \- convert .h C header files to Perl extensions | |
522 | .SH SYNOPSIS | |
523 | .B h2xs [-Aachfm] [-n module_name] [headerfile [extra_libraries]] | |
524 | .SH DESCRIPTION | |
525 | .I h2xs | |
526 | builds a Perl extension from any C header file. The extension will include | |
527 | functions which can be used to retrieve the value of any #define statement | |
528 | which was in the C header. | |
529 | .PP | |
530 | The | |
531 | .I module_name | |
532 | will be used for the name of the extension. If module_name is not supplied | |
533 | then the name of the header file will be used, with the first character | |
534 | capitalized. | |
535 | .PP | |
536 | If the extension might need extra libraries, they should be included | |
537 | here. The extension Makefile.SH will take care of checking whether | |
538 | the libraries actually exist and how they should be loaded. | |
539 | The extra libraries should be specified in the form -lm -lposix, etc, | |
540 | just as on the cc command line. By default, the Makefile.SH will | |
541 | search through the library path determined by Configure. That path | |
542 | can be augmented by including arguments of the form -L/another/library/path | |
543 | in the extra-libraries argument. | |
544 | .SH OPTIONS | |
545 | .TP | |
546 | .B \-f | |
547 | Allows an extension to be created for a header even if that | |
548 | header is not found in /usr/include. | |
549 | .TP | |
550 | .B \-a | |
551 | Omit AutoLoad(), AUTOLOAD, and autosplit from the .pm and Makefile files. | |
552 | .TP | |
553 | .B \-c | |
554 | Omit constant() from the .xs file. | |
555 | .TP | |
556 | .B \-n module_name | |
557 | Specifies a name to be used for the extension. | |
558 | .TP | |
559 | .B \-A | |
560 | Turns on both -a and -c. | |
561 | .TP | |
562 | .B \-m | |
563 | Causes an old-style Makefile.SH to be created. | |
564 | .SH EXAMPLES | |
565 | .nf | |
566 | ||
567 | # Default behavior, extension is Rusers | |
568 | h2xs rpcsvc/rusers | |
569 | ||
570 | # Same, but extension is RUSERS | |
571 | h2xs -n RUSERS rpcsvc/rusers | |
572 | ||
573 | # Extension is rpcsvc::rusers. Still finds <rpcsvc/rusers.h> | |
574 | h2xs rpcsvc::rusers | |
575 | ||
576 | # Extension is ONC::RPC. Still finds <rpcsvc/rusers.h> | |
577 | h2xs -n ONC::RPC rpcsvc/rusers | |
578 | ||
579 | # Without AUTOLOAD, AutoLoad, autosplit | |
580 | h2xs -a rpcsvc/rusers | |
581 | ||
582 | # Creates templates for an extension named RPC | |
583 | h2xs -Afn RPC | |
584 | ||
585 | # Extension is ONC::RPC. | |
586 | h2xs -An ONC::RPC | |
587 | ||
588 | # Makefile.SH will look for library -lrpc in | |
589 | # additional directory /opt/net/lib | |
590 | h2xs rpcsvc/rusers -L/opt/net/lib -lrpc | |
591 | ||
592 | .fi | |
593 | .SH ENVIRONMENT | |
594 | No environment variables are used. | |
595 | .SH AUTHOR | |
596 | Larry Wall | |
597 | .SH "SEE ALSO" | |
598 | perl(1) | |
599 | .SH DIAGNOSTICS | |
600 | The usual warnings if it can't read or write the files involved. | |
601 | .ex |