home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume30
/
perl
/
patch30
< prev
next >
Wrap
Text File
|
1992-06-11
|
51KB
|
1,939 lines
Newsgroups: comp.sources.misc
From: lwall@netlabs.com (Larry Wall)
Subject: v30i041: perl - The perl programming language, Patch30
Message-ID: <1992Jun11.180756.1426@sparky.imd.sterling.com>
X-Md4-Signature: 655951ed82458e9acd368f8737df5cbd
Date: Thu, 11 Jun 1992 18:07:56 GMT
Approved: kent@sparky.imd.sterling.com
Submitted-by: lwall@netlabs.com (Larry Wall)
Posting-number: Volume 30, Issue 41
Archive-name: perl/patch30
Environment: UNIX, MS-DOS, OS2
Patch-To: perl: Volume 18, Issue 19-54
System: perl version 4.0
Patch #: 30
Priority: highish
Subject: patch #20, continued
Description:
See patch #20.
Fix: From rn, say "| patch -p -N -d DIR", where DIR is your perl source
directory. Outside of rn, say "cd DIR; patch -p -N <thisarticle".
If you don't have the patch program, apply the following by hand,
or get patch (version 2.0, latest patchlevel).
After patching:
*** DO NOTHING--INSTALL ALL PATCHES UP THROUGH #33 FIRST ***
If patch indicates that patchlevel is the wrong version, you may need
to apply one or more previous patches, or the patch may already
have been applied. See the patchlevel.h file to find out what has or
has not been applied. In any event, don't continue with the patch.
If you are missing previous patches they can be obtained from me:
Larry Wall
lwall@netlabs.com
If you send a mail message of the following form it will greatly speed
processing:
Subject: Command
@SH mailpatch PATH perl 4.0 LIST
^ note the c
where PATH is a return path FROM ME TO YOU either in Internet notation,
or in bang notation from some well-known host, and LIST is the number
of one or more patches you need, separated by spaces, commas, and/or
hyphens. Saying 35- says everything from 35 to the end.
Index: patchlevel.h
Prereq: 29
1c1
< #define PATCHLEVEL 29
---
> #define PATCHLEVEL 30
Index: perly.y
*** perly.y.old Mon Jun 8 17:51:22 1992
--- perly.y Mon Jun 8 17:51:23 1992
***************
*** 1,4 ****
! /* $RCSfile: perly.y,v $$Revision: 4.0.1.2 $$Date: 91/11/05 18:17:38 $
*
* Copyright (c) 1991, Larry Wall
*
--- 1,4 ----
! /* $RCSfile: perly.y,v $$Revision: 4.0.1.4 $$Date: 92/06/08 17:33:25 $
*
* Copyright (c) 1991, Larry Wall
*
***************
*** 6,11 ****
--- 6,22 ----
* License or the Artistic License, as specified in the README file.
*
* $Log: perly.y,v $
+ * Revision 4.0.1.4 92/06/08 17:33:25 lwall
+ * patch20: one of the backdoors to expectterm was on the wrong reduction
+ *
+ * Revision 4.0.1.3 92/06/08 15:18:16 lwall
+ * patch20: an expression may now start with a bareword
+ * patch20: relaxed requirement for semicolon at the end of a block
+ * patch20: added ... as variant on ..
+ * patch20: fixed double debug break in foreach with implicit array assignment
+ * patch20: if {block} {block} didn't work any more
+ * patch20: deleted some minor memory leaks
+ *
* Revision 4.0.1.2 91/11/05 18:17:38 lwall
* patch11: extra comma at end of list is now allowed in more places (Hi, Felix!)
* patch11: once-thru blocks didn't display right in the debugger
***************
*** 47,54 ****
%token <ival> '{' ')'
! %token <cval> WORD
! %token <ival> APPEND OPEN SSELECT LOOPEX
%token <ival> USING FORMAT DO SHIFT PUSH POP LVALFUN
%token <ival> WHILE UNTIL IF UNLESS ELSE ELSIF CONTINUE SPLIT FLIST
%token <ival> FOR FILOP FILOP2 FILOP3 FILOP4 FILOP22 FILOP25
--- 58,65 ----
%token <ival> '{' ')'
! %token <cval> WORD LABEL
! %token <ival> APPEND OPEN SSELECT LOOPEX DOTDOT
%token <ival> USING FORMAT DO SHIFT PUSH POP LVALFUN
%token <ival> WHILE UNTIL IF UNLESS ELSE ELSIF CONTINUE SPLIT FLIST
%token <ival> FOR FILOP FILOP2 FILOP3 FILOP4 FILOP22 FILOP25
***************
*** 95,100 ****
--- 106,112 ----
{
#if defined(YYDEBUG) && defined(DEBUGGING)
yydebug = (debug & 1);
+ expectterm = 2;
#endif
}
/*CONTINUED*/ lineseq
***************
*** 116,130 ****
{ $$ = $2; }
| ELSIF '(' expr ')' compblock
{ cmdline = $1;
! $$ = make_ccmd(C_ELSIF,$3,$5); }
;
block : '{' remember lineseq '}'
{ $$ = block_head($3);
! if (cmdline > $1)
cmdline = $1;
if (savestack->ary_fill > $2)
! restorelist($2); }
;
remember: /* NULL */ /* in case they push a package name */
--- 128,143 ----
{ $$ = $2; }
| ELSIF '(' expr ')' compblock
{ cmdline = $1;
! $$ = make_ccmd(C_ELSIF,1,$3,$5); }
;
block : '{' remember lineseq '}'
{ $$ = block_head($3);
! if (cmdline > (line_t)$1)
cmdline = $1;
if (savestack->ary_fill > $2)
! restorelist($2);
! expectterm = 2; }
;
remember: /* NULL */ /* in case they push a package name */
***************
*** 150,158 ****
else {
$$ = Nullcmd;
cmdline = NOLINE;
! } }
| label sideff ';'
! { $$ = add_label($1,$2); }
;
sideff : error
--- 163,173 ----
else {
$$ = Nullcmd;
cmdline = NOLINE;
! }
! expectterm = 2; }
| label sideff ';'
! { $$ = add_label($1,$2);
! expectterm = 2; }
;
sideff : error
***************
*** 181,208 ****
$$ = invert(make_icmd(C_IF,$3,$5)); }
| IF block compblock
{ cmdline = $1;
! $$ = make_ccmd(C_IF,cmd_to_arg($2),$3); }
| UNLESS block compblock
{ cmdline = $1;
! $$ = invert(make_ccmd(C_IF,cmd_to_arg($2),$3)); }
;
loop : label WHILE '(' texpr ')' compblock
{ cmdline = $2;
$$ = wopt(add_label($1,
! make_ccmd(C_WHILE,$4,$6) )); }
| label UNTIL '(' expr ')' compblock
{ cmdline = $2;
$$ = wopt(add_label($1,
! invert(make_ccmd(C_WHILE,$4,$6)) )); }
| label WHILE block compblock
{ cmdline = $2;
$$ = wopt(add_label($1,
! make_ccmd(C_WHILE, cmd_to_arg($3),$4) )); }
| label UNTIL block compblock
{ cmdline = $2;
$$ = wopt(add_label($1,
! invert(make_ccmd(C_WHILE, cmd_to_arg($3),$4)) )); }
| label FOR REG '(' expr crp compblock
{ cmdline = $2;
/*
--- 196,223 ----
$$ = invert(make_icmd(C_IF,$3,$5)); }
| IF block compblock
{ cmdline = $1;
! $$ = make_icmd(C_IF,cmd_to_arg($2),$3); }
| UNLESS block compblock
{ cmdline = $1;
! $$ = invert(make_icmd(C_IF,cmd_to_arg($2),$3)); }
;
loop : label WHILE '(' texpr ')' compblock
{ cmdline = $2;
$$ = wopt(add_label($1,
! make_ccmd(C_WHILE,1,$4,$6) )); }
| label UNTIL '(' expr ')' compblock
{ cmdline = $2;
$$ = wopt(add_label($1,
! invert(make_ccmd(C_WHILE,1,$4,$6)) )); }
| label WHILE block compblock
{ cmdline = $2;
$$ = wopt(add_label($1,
! make_ccmd(C_WHILE, 1, cmd_to_arg($3),$4) )); }
| label UNTIL block compblock
{ cmdline = $2;
$$ = wopt(add_label($1,
! invert(make_ccmd(C_WHILE,1,cmd_to_arg($3),$4)) )); }
| label FOR REG '(' expr crp compblock
{ cmdline = $2;
/*
***************
*** 229,235 ****
Nullarg)),
Nullarg),
wopt(over($3,add_label($1,
! make_ccmd(C_WHILE,
make_op(O_ARRAY, 1,
stab2arg(A_STAB,scrstab),
Nullarg,Nullarg ),
--- 244,250 ----
Nullarg)),
Nullarg),
wopt(over($3,add_label($1,
! make_ccmd(C_WHILE, 0,
make_op(O_ARRAY, 1,
stab2arg(A_STAB,scrstab),
Nullarg,Nullarg ),
***************
*** 239,245 ****
}
else {
$$ = wopt(over($3,add_label($1,
! make_ccmd(C_WHILE,$5,$7) )));
}
}
| label FOR '(' expr crp compblock
--- 254,260 ----
}
else {
$$ = wopt(over($3,add_label($1,
! make_ccmd(C_WHILE,1,$5,$7) )));
}
}
| label FOR '(' expr crp compblock
***************
*** 256,262 ****
Nullarg)),
Nullarg),
wopt(over(defstab,add_label($1,
! make_ccmd(C_WHILE,
make_op(O_ARRAY, 1,
stab2arg(A_STAB,scrstab),
Nullarg,Nullarg ),
--- 271,277 ----
Nullarg)),
Nullarg),
wopt(over(defstab,add_label($1,
! make_ccmd(C_WHILE, 0,
make_op(O_ARRAY, 1,
stab2arg(A_STAB,scrstab),
Nullarg,Nullarg ),
***************
*** 266,272 ****
}
else { /* lisp, anyone? */
$$ = wopt(over(defstab,add_label($1,
! make_ccmd(C_WHILE,$4,$6) )));
}
}
| label FOR '(' nexpr ';' texpr ';' nexpr ')' block
--- 281,287 ----
}
else { /* lisp, anyone? */
$$ = wopt(over(defstab,add_label($1,
! make_ccmd(C_WHILE,1,$4,$6) )));
}
}
| label FOR '(' nexpr ';' texpr ';' nexpr ')' block
***************
*** 275,283 ****
yyval.compval.comp_alt = $8;
cmdline = $2;
$$ = append_line($4,wopt(add_label($1,
! make_ccmd(C_WHILE,$6,yyval.compval) ))); }
| label compblock /* a block is a loop that happens once */
! { $$ = add_label($1,make_ccmd(C_BLOCK,Nullarg,$2)); }
;
nexpr : /* NULL */
--- 290,298 ----
yyval.compval.comp_alt = $8;
cmdline = $2;
$$ = append_line($4,wopt(add_label($1,
! make_ccmd(C_WHILE,1,$6,yyval.compval) ))); }
| label compblock /* a block is a loop that happens once */
! { $$ = add_label($1,make_ccmd(C_BLOCK,1,Nullarg,$2)); }
;
nexpr : /* NULL */
***************
*** 286,298 ****
;
texpr : /* NULL means true */
! { (void)scanstr("1"); $$ = yylval.arg; }
| expr
;
label : /* empty */
{ $$ = Nullch; }
! | WORD ':'
;
decl : format
--- 301,313 ----
;
texpr : /* NULL means true */
! { (void)scanstr("1",SCAN_DEF); $$ = yylval.arg; }
| expr
;
label : /* empty */
{ $$ = Nullch; }
! | LABEL
;
decl : format
***************
*** 339,344 ****
--- 354,360 ----
curstash->tbl_coeffsize = 0;
Safefree($2); $2 = Nullch;
cmdline = NOLINE;
+ expectterm = 2;
}
;
***************
*** 409,415 ****
{ $$ = make_op(O_BIT_OR, 2, $1, $3, Nullarg); }
| sexpr DOTDOT sexpr
{ arg4 = Nullarg;
! $$ = make_op(O_F_OR_R, 4, $1, $3, Nullarg); }
| sexpr ANDAND sexpr
{ $$ = make_op(O_AND, 2, $1, $3, Nullarg); }
| sexpr OROR sexpr
--- 425,432 ----
{ $$ = make_op(O_BIT_OR, 2, $1, $3, Nullarg); }
| sexpr DOTDOT sexpr
{ arg4 = Nullarg;
! $$ = make_op(O_F_OR_R, 4, $1, $3, Nullarg);
! $$[0].arg_flags |= $2; }
| sexpr ANDAND sexpr
{ $$ = make_op(O_AND, 2, $1, $3, Nullarg); }
| sexpr OROR sexpr
***************
*** 449,454 ****
--- 466,472 ----
$$ = make_op($1, 1,
stab2arg(A_STAB,stabent($2,TRUE)),
Nullarg, Nullarg);
+ Safefree($2); $2 = Nullch;
}
| FILETEST sexpr
{ opargs[$1] = 1;
***************
*** 487,497 ****
{ $$ = make_op(O_ARRAY, 1,
stab2arg(A_STAB,$1),
Nullarg, Nullarg); }
! | REG '{' expr '}' %prec '('
{ $$ = make_op(O_HELEM, 2,
stab2arg(A_STAB,hadd($1)),
jmaybe($3),
! Nullarg); }
| '(' expr crp '[' expr ']' %prec '('
{ $$ = make_op(O_LSLICE, 3,
Nullarg,
--- 505,516 ----
{ $$ = make_op(O_ARRAY, 1,
stab2arg(A_STAB,$1),
Nullarg, Nullarg); }
! | REG '{' expr ';' '}' %prec '('
{ $$ = make_op(O_HELEM, 2,
stab2arg(A_STAB,hadd($1)),
jmaybe($3),
! Nullarg);
! expectterm = FALSE; }
| '(' expr crp '[' expr ']' %prec '('
{ $$ = make_op(O_LSLICE, 3,
Nullarg,
***************
*** 507,522 ****
stab2arg(A_STAB,aadd($1)),
listish(make_list($3)),
Nullarg); }
! | ARY '{' expr '}' %prec '('
{ $$ = make_op(O_HSLICE, 2,
stab2arg(A_STAB,hadd($1)),
listish(make_list($3)),
! Nullarg); }
! | DELETE REG '{' expr '}' %prec '('
{ $$ = make_op(O_DELETE, 2,
stab2arg(A_STAB,hadd($2)),
jmaybe($4),
! Nullarg); }
| ARYLEN %prec '('
{ $$ = stab2arg(A_ARYLEN,$1); }
| RSTRING %prec '('
--- 526,549 ----
stab2arg(A_STAB,aadd($1)),
listish(make_list($3)),
Nullarg); }
! | ARY '{' expr ';' '}' %prec '('
{ $$ = make_op(O_HSLICE, 2,
stab2arg(A_STAB,hadd($1)),
listish(make_list($3)),
! Nullarg);
! expectterm = FALSE; }
! | DELETE REG '{' expr ';' '}' %prec '('
{ $$ = make_op(O_DELETE, 2,
stab2arg(A_STAB,hadd($2)),
jmaybe($4),
! Nullarg);
! expectterm = FALSE; }
! | DELETE '(' REG '{' expr ';' '}' ')' %prec '('
! { $$ = make_op(O_DELETE, 2,
! stab2arg(A_STAB,hadd($3)),
! jmaybe($4),
! Nullarg);
! expectterm = FALSE; }
| ARYLEN %prec '('
{ $$ = stab2arg(A_ARYLEN,$1); }
| RSTRING %prec '('
***************
*** 543,559 ****
stab2arg(A_WORD,stabent($2,MULTI)),
make_list(Nullarg),
Nullarg);
$$->arg_flags |= AF_DEPR; }
| AMPER WORD '(' ')'
{ $$ = make_op((perldb ? O_DBSUBR : O_SUBR), 2,
stab2arg(A_WORD,stabent($2,MULTI)),
make_list(Nullarg),
! Nullarg); }
| AMPER WORD
{ $$ = make_op((perldb ? O_DBSUBR : O_SUBR), 2,
stab2arg(A_WORD,stabent($2,MULTI)),
Nullarg,
! Nullarg); }
| DO REG '(' expr crp
{ $$ = make_op((perldb ? O_DBSUBR : O_SUBR), 2,
stab2arg(A_STAB,$2),
--- 570,591 ----
stab2arg(A_WORD,stabent($2,MULTI)),
make_list(Nullarg),
Nullarg);
+ Safefree($2); $2 = Nullch;
$$->arg_flags |= AF_DEPR; }
| AMPER WORD '(' ')'
{ $$ = make_op((perldb ? O_DBSUBR : O_SUBR), 2,
stab2arg(A_WORD,stabent($2,MULTI)),
make_list(Nullarg),
! Nullarg);
! Safefree($2); $2 = Nullch;
! }
| AMPER WORD
{ $$ = make_op((perldb ? O_DBSUBR : O_SUBR), 2,
stab2arg(A_WORD,stabent($2,MULTI)),
Nullarg,
! Nullarg);
! Safefree($2); $2 = Nullch;
! }
| DO REG '(' expr crp
{ $$ = make_op((perldb ? O_DBSUBR : O_SUBR), 2,
stab2arg(A_STAB,$2),
***************
*** 609,620 ****
{ $$ = make_op(O_OPEN, 2,
stab2arg(A_WORD,stabent($2,TRUE)),
stab2arg(A_STAB,stabent($2,TRUE)),
! Nullarg); }
| OPEN '(' WORD ')'
{ $$ = make_op(O_OPEN, 2,
stab2arg(A_WORD,stabent($3,TRUE)),
stab2arg(A_STAB,stabent($3,TRUE)),
! Nullarg); }
| OPEN '(' handle cexpr ')'
{ $$ = make_op(O_OPEN, 2,
$3,
--- 641,656 ----
{ $$ = make_op(O_OPEN, 2,
stab2arg(A_WORD,stabent($2,TRUE)),
stab2arg(A_STAB,stabent($2,TRUE)),
! Nullarg);
! Safefree($2); $2 = Nullch;
! }
| OPEN '(' WORD ')'
{ $$ = make_op(O_OPEN, 2,
stab2arg(A_WORD,stabent($3,TRUE)),
stab2arg(A_STAB,stabent($3,TRUE)),
! Nullarg);
! Safefree($3); $3 = Nullch;
! }
| OPEN '(' handle cexpr ')'
{ $$ = make_op(O_OPEN, 2,
$3,
***************
*** 763,769 ****
{ $$ = make_op($1,2,
stab2arg(A_WORD,stabent($2,TRUE)),
stab2arg(A_STAB,defstab),
! Nullarg); }
| LISTOP WORD expr
{ $$ = make_op($1,2,
stab2arg(A_WORD,stabent($2,TRUE)),
--- 799,807 ----
{ $$ = make_op($1,2,
stab2arg(A_WORD,stabent($2,TRUE)),
stab2arg(A_STAB,defstab),
! Nullarg);
! Safefree($2); $2 = Nullch;
! }
| LISTOP WORD expr
{ $$ = make_op($1,2,
stab2arg(A_WORD,stabent($2,TRUE)),
***************
*** 823,828 ****
--- 861,867 ----
warn(
"\"%s\" may clash with future reserved word",
$1 );
+ Safefree($1); $1 = Nullch;
}
;
%% /* PROGRAM */
Index: atarist/test/pi.pl
*** atarist/test/pi.pl.old Mon Jun 8 17:45:13 1992
--- atarist/test/pi.pl Mon Jun 8 17:45:13 1992
***************
*** 0 ****
--- 1,174 ----
+ # ---------------------------------------------------------------------------
+ # pi.perl computes pi (3.14...) about 5120 Digits
+ #
+ # W. Kebsch, July-1988 {uunet!mcvax}!unido!nixpbe!kebsch
+
+ $my_name = $0;
+ $version = $my_name . "-1.2";
+
+ # some working parameter
+
+ $smax = 5120; # max digits
+ $lmax = 4; # digits per one array element
+ $hmax = 10000; # one array element contains: 0..9999
+ $smin = $lmax; # min digits
+ $mag = 7; # magic number
+
+ # subroutines
+
+ sub mul_tm # multiply the tm array with a long value
+ {
+ $cb = pop(@_); # elements(array)
+ $x = pop(@_); # value
+
+ $c = 0;
+ for($i = 1; $i <= $cb; $i++)
+ {
+ $z = $tm[$i] * $x + $c;
+ $c = int($z / $hmax);
+ $tm[$i] = $z - $c * $hmax;
+ }
+ }
+
+ sub mul_pm # multiply the pm array with a long value
+ {
+ $cb = pop(@_); # elements(array)
+ $x = pop(@_); # value
+
+ $c = 0;
+ for($i = 1; $i <= $cb; $i++)
+ {
+ $z = $pm[$i] * $x + $c;
+ $c = int($z / $hmax);
+ $pm[$i] = $z - $c * $hmax;
+ }
+ }
+
+ sub divide # divide the tm array by a long value
+ {
+ $cb = pop(@_); # elements(array)
+ $x = pop(@_); # value
+
+ $c = 0;
+ for($i = $cb; $i >= 1; $i--)
+ {
+ $z = $tm[$i] + $c;
+ $q = int($z / $x);
+ $tm[$i] = $q;
+ $c = ($z - $q * $x) * $hmax;
+ }
+ }
+
+ sub add # add tm array to pm array
+ {
+ $cb = pop(@_); # elements(array)
+
+ $c = 0;
+ for($i = 1; $i <= $cb; $i++)
+ {
+ $z = $pm[$i] + $tm[$i] + $c;
+ if($z >= $hmax)
+ {
+ $pm[$i] = $z - $hmax;
+ $c = 1;
+ }
+ else
+ {
+ $pm[$i] = $z;
+ $c = 0;
+ }
+ }
+ }
+
+ $m0 = 0; $m1 = 0; $m2 = 0;
+
+ sub check_xb # reduce current no. of elements (speed up!)
+ {
+ $cb = pop(@_); # current no. of elements
+
+ if(($pm[$cb] == $m0) && ($pm[$cb - 1] == $m1) && ($pm[$cb - 2] == $m2))
+ {
+ $cb--;
+ }
+ $m0 = $pm[$cb];
+ $m1 = $pm[$cb - 1];
+ $m2 = $pm[$cb - 2];
+ $cb;
+ }
+
+ sub display # show the result
+ {
+ $cb = pop(@_); # elements(array);
+
+ printf("\n%3d.", $pm[$cb]);
+ $j = $mag - $lmax;
+ for($i = $cb - 1; $i >= $j; $i--)
+ {
+ printf(" %04d", $pm[$i]);
+ }
+ print "\n";
+ }
+
+ sub the_job # let's do the job
+ {
+ $s = pop(@_); # no. of digits
+
+ $s = int(($s + $lmax - 1) / $lmax) * $lmax;
+ $b = int($s / $lmax) + $mag - $lmax;
+ $xb = $b;
+ $t = int($s * 5 / 3);
+
+ for($i = 1; $i <= $b; $i++) # init arrays
+ {
+ $pm[$i] = 0;
+ $tm[$i] = 0;
+ }
+ $pm[$b - 1] = $hmax / 2;
+ $tm[$b - 1] = $hmax / 2;
+
+ printf("digits:%5d, terms:%5d, elements:%5d\n", $s, $t, $b);
+ for($n = 1; $n <= $t; $n++)
+ {
+ printf("\r\t\t\t term:%5d", $n);
+ if($n < 200)
+ {
+ do mul_tm((4 * ($n * $n - $n) + 1), $xb);
+ }
+ else
+ {
+ do mul_tm((2 * $n - 1), $xb);
+ do mul_tm((2 * $n - 1), $xb);
+ }
+ if($n < 100)
+ {
+ do divide(($n * (16 * $n + 8)), $xb);
+ }
+ else
+ {
+ do divide((8 * $n), $xb);
+ do divide((2 * $n + 1), $xb);
+ }
+ do add($xb);
+ if($xb > $mag)
+ {
+ $xb = do check_xb($xb);
+ }
+ }
+ do mul_pm(6, $b);
+ do display($b);
+ ($user,$sys,$cuser,$csys) = times;
+ printf("\n[u=%g s=%g cu=%g cs=%g]\n",$user, $sys, $cuser, $csys);
+ }
+
+ # main block ----------------------------------------------------------------
+
+ $no_of_args = $#ARGV + 1;
+ print("$version, ");
+ die("usage: $my_name <no. of digits>") unless($no_of_args == 1);
+ $digits = int($ARGV[0]);
+ die("no. of digits out of range [$smin\..$smax]")
+ unless(($digits >= $smin) && ($digits <= $smax));
+ do the_job($digits);
+ exit 0;
+
+ # That's all ----------------------------------------------------------------
Index: pstruct
*** pstruct.old Mon Jun 8 17:51:29 1992
--- pstruct Mon Jun 8 17:51:30 1992
***************
*** 0 ****
--- 1,1071 ----
+ #!/usr/local/bin/perl
+ #
+ #
+ # c2ph (aka pstruct)
+ # Tom Christiansen, <tchrist@convex.com>
+ #
+ # As pstruct, dump C structures as generated from 'cc -g -S' stabs.
+ # As c2ph, do this PLUS generate perl code for getting at the structures.
+ #
+ # See the usage message for more. If this isn't enough, read the code.
+ #
+
+ $RCSID = '$RCSfile: pstruct,v $$Revision: 4.0.1.1 $$Date: 92/06/08 15:19:40 $';
+
+
+ ######################################################################
+
+ # some handy data definitions. many of these can be reset later.
+
+ $bitorder = 'b'; # ascending; set to B for descending bit fields
+
+ %intrinsics =
+ %template = (
+ 'char', 'c',
+ 'unsigned char', 'C',
+ 'short', 's',
+ 'short int', 's',
+ 'unsigned short', 'S',
+ 'unsigned short int', 'S',
+ 'short unsigned int', 'S',
+ 'int', 'i',
+ 'unsigned int', 'I',
+ 'long', 'l',
+ 'long int', 'l',
+ 'unsigned long', 'L',
+ 'unsigned long', 'L',
+ 'long unsigned int', 'L',
+ 'unsigned long int', 'L',
+ 'long long', 'q',
+ 'long long int', 'q',
+ 'unsigned long long', 'Q',
+ 'unsigned long long int', 'Q',
+ 'float', 'f',
+ 'double', 'd',
+ 'pointer', 'p',
+ 'null', 'x',
+ 'neganull', 'X',
+ 'bit', $bitorder,
+ );
+
+ &buildscrunchlist;
+ delete $intrinsics{'neganull'};
+ delete $intrinsics{'bit'};
+ delete $intrinsics{'null'};
+
+ # use -s to recompute sizes
+ %sizeof = (
+ 'char', '1',
+ 'unsigned char', '1',
+ 'short', '2',
+ 'short int', '2',
+ 'unsigned short', '2',
+ 'unsigned short int', '2',
+ 'short unsigned int', '2',
+ 'int', '4',
+ 'unsigned int', '4',
+ 'long', '4',
+ 'long int', '4',
+ 'unsigned long', '4',
+ 'unsigned long int', '4',
+ 'long unsigned int', '4',
+ 'long long', '8',
+ 'long long int', '8',
+ 'unsigned long long', '8',
+ 'unsigned long long int', '8',
+ 'float', '4',
+ 'double', '8',
+ 'pointer', '4',
+ );
+
+ ($type_width, $member_width, $offset_width, $size_width) = (20, 20, 6, 5);
+
+ ($offset_fmt, $size_fmt) = ('d', 'd');
+
+ $indent = 2;
+
+ $CC = 'cc';
+ $CFLAGS = '-g -S';
+ $DEFINES = '';
+
+ $perl++ if $0 =~ m#/?c2ph$#;
+
+ require 'getopts.pl';
+
+ eval '$'.$1.'$2;' while $ARGV[0] =~ /^([A-Za-z_]+=)(.*)/ && shift;
+
+ &Getopts('aixdpvtnws:') || &usage(0);
+
+ $opt_d && $debug++;
+ $opt_t && $trace++;
+ $opt_p && $perl++;
+ $opt_v && $verbose++;
+ $opt_n && ($perl = 0);
+
+ if ($opt_w) {
+ ($type_width, $member_width, $offset_width) = (45, 35, 8);
+ }
+ if ($opt_x) {
+ ($offset_fmt, $offset_width, $size_fmt, $size_width) = ( 'x', '08', 'x', 04 );
+ }
+
+ eval '$'.$1.'$2;' while $ARGV[0] =~ /^([A-Za-z_]+=)(.*)/ && shift;
+
+ sub PLUMBER {
+ select(STDERR);
+ print "oops, apperent pager foulup\n";
+ $isatty++;
+ &usage(1);
+ }
+
+ sub usage {
+ local($oops) = @_;
+ unless (-t STDOUT) {
+ select(STDERR);
+ } elsif (!$oops) {
+ $isatty++;
+ $| = 1;
+ print "hit <RETURN> for further explanation: ";
+ <STDIN>;
+ open (PIPE, "|". ($ENV{PAGER} || 'more'));
+ $SIG{PIPE} = PLUMBER;
+ select(PIPE);
+ }
+
+ print "usage: $0 [-dpnP] [var=val] [files ...]\n";
+
+ exit unless $isatty;
+
+ print <<EOF;
+
+ Options:
+
+ -w wide; short for: type_width=45 member_width=35 offset_width=8
+ -x hex; short for: offset_fmt=x offset_width=08 size_fmt=x size_width=04
+
+ -n do not generate perl code (default when invoked as pstruct)
+ -p generate perl code (default when invoked as c2ph)
+ -v generate perl code, with C decls as comments
+
+ -i do NOT recompute sizes for intrinsic datatypes
+ -a dump information on intrinsics also
+
+ -t trace execution
+ -d spew reams of debugging output
+
+ -slist give comma-separated list a structures to dump
+
+
+ Var Name Default Value Meaning
+
+ EOF
+
+ &defvar('CC', 'which_compiler to call');
+ &defvar('CFLAGS', 'how to generate *.s files with stabs');
+ &defvar('DEFINES','any extra cflags or cpp defines, like -I, -D, -U');
+
+ print "\n";
+
+ &defvar('type_width', 'width of type field (column 1)');
+ &defvar('member_width', 'width of member field (column 2)');
+ &defvar('offset_width', 'width of offset field (column 3)');
+ &defvar('size_width', 'width of size field (column 4)');
+
+ print "\n";
+
+ &defvar('offset_fmt', 'sprintf format type for offset');
+ &defvar('size_fmt', 'sprintf format type for size');
+
+ print "\n";
+
+ &defvar('indent', 'how far to indent each nesting level');
+
+ print <<'EOF';
+
+ If any *.[ch] files are given, these will be catted together into
+ a temporary *.c file and sent through:
+ $CC $CFLAGS $DEFINES
+ and the resulting *.s groped for stab information. If no files are
+ supplied, then stdin is read directly with the assumption that it
+ contains stab information. All other liens will be ignored. At
+ most one *.s file should be supplied.
+
+ EOF
+ close PIPE;
+ exit 1;
+ }
+
+ sub defvar {
+ local($var, $msg) = @_;
+ printf "%-16s%-15s %s\n", $var, eval "\$$var", $msg;
+ }
+
+ $recurse = 1;
+
+ if (@ARGV) {
+ if (grep(!/\.[csh]$/,@ARGV)) {
+ warn "Only *.[csh] files expected!\n";
+ &usage;
+ }
+ elsif (grep(/\.s$/,@ARGV)) {
+ if (@ARGV > 1) {
+ warn "Only one *.s file allowed!\n";
+ &usage;
+ }
+ }
+ elsif (@ARGV == 1 && $ARGV[0] =~ /\.c$/) {
+ local($dir, $file) = $ARGV[0] =~ m#(.*/)?(.*)$#;
+ $chdir = "cd $dir; " if $dir;
+ &system("$chdir$CC $CFLAGS $DEFINES $file") && exit 1;
+ $ARGV[0] =~ s/\.c$/.s/;
+ }
+ else {
+ $TMP = "/tmp/c2ph.$$.c";
+ &system("cat @ARGV > $TMP") && exit 1;
+ &system("cd /tmp; $CC $CFLAGS $DEFINES $TMP") && exit 1;
+ unlink $TMP;
+ $TMP =~ s/\.c$/.s/;
+ @ARGV = ($TMP);
+ }
+ }
+
+ if ($opt_s) {
+ for (split(/[\s,]+/, $opt_s)) {
+ $interested{$_}++;
+ }
+ }
+
+
+ $| = 1 if $debug;
+
+ main: {
+
+ if ($trace) {
+ if (-t && !@ARGV) {
+ print STDERR "reading from your keyboard: ";
+ } else {
+ print STDERR "reading from " . (@ARGV ? "@ARGV" : "<STDIN>").": ";
+ }
+ }
+
+ STAB: while (<>) {
+ if ($trace && !($. % 10)) {
+ $lineno = $..'';
+ print STDERR $lineno, "\b" x length($lineno);
+ }
+ next unless /^\s*\.stabs\s+/;
+ $line = $_;
+ s/^\s*\.stabs\s+//;
+ &stab;
+ }
+ print STDERR "$.\n" if $trace;
+ unlink $TMP if $TMP;
+
+ &compute_intrinsics if $perl && !$opt_i;
+
+ print STDERR "resolving types\n" if $trace;
+
+ &resolve_types;
+ &adjust_start_addrs;
+
+ $sum = 2 + $type_width + $member_width;
+ $pmask1 = "%-${type_width}s %-${member_width}s";
+ $pmask2 = "%-${sum}s %${offset_width}${offset_fmt}%s %${size_width}${size_fmt}%s";
+
+ if ($perl) {
+ # resolve template -- should be in stab define order, but even this isn't enough.
+ print STDERR "\nbuilding type templates: " if $trace;
+ for $i (reverse 0..$#type) {
+ next unless defined($name = $type[$i]);
+ next unless defined $struct{$name};
+ $build_recursed = 0;
+ &build_template($name) unless defined $template{&psou($name)} ||
+ $opt_s && !$interested{$name};
+ }
+ print STDERR "\n\n" if $trace;
+ }
+
+ print STDERR "dumping structs: " if $trace;
+
+
+ foreach $name (sort keys %struct) {
+ next if $opt_s && !$interested{$name};
+ print STDERR "$name " if $trace;
+
+ undef @sizeof;
+ undef @typedef;
+ undef @offsetof;
+ undef @indices;
+ undef @typeof;
+
+ $mname = &munge($name);
+
+ $fname = &psou($name);
+
+ print "# " if $perl && $verbose;
+ $pcode = '';
+ print "$fname {\n" if !$perl || $verbose;
+ $template{$fname} = &scrunch($template{$fname}) if $perl;
+ &pstruct($name,$name,0);
+ print "# " if $perl && $verbose;
+ print "}\n" if !$perl || $verbose;
+ print "\n" if $perl && $verbose;
+
+ if ($perl) {
+ print "$pcode";
+
+ printf("\nsub %-32s { %4d; }\n\n", "${mname}'struct", $countof{$name});
+
+ print <<EOF;
+ sub ${mname}'typedef {
+ local(\$${mname}'index) = shift;
+ defined \$${mname}'index
+ ? \$${mname}'typedef[\$${mname}'index]
+ : \$${mname}'typedef;
+ }
+ EOF
+
+ print <<EOF;
+ sub ${mname}'sizeof {
+ local(\$${mname}'index) = shift;
+ defined \$${mname}'index
+ ? \$${mname}'sizeof[\$${mname}'index]
+ : \$${mname}'sizeof;
+ }
+ EOF
+
+ print <<EOF;
+ sub ${mname}'offsetof {
+ local(\$${mname}'index) = shift;
+ defined \$${mname}index
+ ? \$${mname}'offsetof[\$${mname}'index]
+ : \$${mname}'sizeof;
+ }
+ EOF
+
+ print <<EOF;
+ sub ${mname}'typeof {
+ local(\$${mname}'index) = shift;
+ defined \$${mname}index
+ ? \$${mname}'typeof[\$${mname}'index]
+ : '$name';
+ }
+ EOF
+
+
+ print "\$${mname}'typedef = '" . &scrunch($template{$fname})
+ . "';\n";
+
+ print "\$${mname}'sizeof = $sizeof{$name};\n\n";
+
+
+ print "\@${mname}'indices = (", &squishseq(@indices), ");\n";
+
+ print "\n";
+
+ print "\@${mname}'typedef[\@${mname}'indices] = (",
+ join("\n\t", '', @typedef), "\n );\n\n";
+ print "\@${mname}'sizeof[\@${mname}'indices] = (",
+ join("\n\t", '', @sizeof), "\n );\n\n";
+ print "\@${mname}'offsetof[\@${mname}'indices] = (",
+ join("\n\t", '', @offsetof), "\n );\n\n";
+ print "\@${mname}'typeof[\@${mname}'indices] = (",
+ join("\n\t", '', @typeof), "\n );\n\n";
+
+ $template_printed{$fname}++;
+ $size_printed{$fname}++;
+ }
+ print "\n";
+ }
+
+ print STDERR "\n" if $trace;
+
+ unless ($perl && $opt_a) {
+ print "\n1;\n";
+ exit;
+ }
+
+
+
+ foreach $name (sort bysizevalue keys %intrinsics) {
+ next if $size_printed{$name};
+ print '$',&munge($name),"'sizeof = ", $sizeof{$name}, ";\n";
+ }
+
+ print "\n";
+
+ sub bysizevalue { $sizeof{$a} <=> $sizeof{$b}; }
+
+
+ foreach $name (sort keys %intrinsics) {
+ print '$',&munge($name),"'typedef = '", $template{$name}, "';\n";
+ }
+
+ print "\n1;\n";
+
+ exit;
+ }
+
+ ########################################################################################
+
+
+ sub stab {
+ next unless /:[\$\w]+(\(\d+,\d+\))?=[\*\$\w]+/; # (\d+,\d+) is for sun
+ s/"// || next;
+ s/",([x\d]+),([x\d]+),([x\d]+),.*// || next;
+
+ next if /^\s*$/;
+
+ $size = $3 if $3;
+
+
+ $line = $_;
+
+ if (($name, $pdecl) = /^([\$ \w]+):[tT]((\d+)(=[rufs*](\d+))+)$/) {
+ print "$name is a typedef for some funky pointers: $pdecl\n" if $debug;
+ &pdecl($pdecl);
+ next;
+ }
+
+
+
+ if (/(([ \w]+):t(\d+|\(\d+,\d+\)))=r?(\d+|\(\d+,\d+\))(;\d+;\d+;)?/) {
+ local($ident) = $2;
+ push(@intrinsics, $ident);
+ $typeno = &typeno($3);
+ $type[$typeno] = $ident;
+ print STDERR "intrinsic $ident in new type $typeno\n" if $debug;
+ next;
+ }
+
+ if (($name, $typeordef, $typeno, $extra, $struct, $_)
+ = /^([\$ \w]+):([ustT])(\d+|\(\d+,\d+\))(=[rufs*](\d+))?(.*)$/)
+ {
+ $typeno = &typeno($typeno); # sun foolery
+ }
+ elsif (/^[\$\w]+:/) {
+ next; # variable
+ }
+ else {
+ warn "can't grok stab: <$_> in: $line " if $_;
+ next;
+ }
+
+ #warn "got size $size for $name\n";
+ $sizeof{$name} = $size if $size;
+
+ s/;[-\d]*;[-\d]*;$//; # we don't care about ranges
+
+ $typenos{$name} = $typeno;
+
+ unless (defined $type[$typeno]) {
+ &panic("type 0??") unless $typeno;
+ $type[$typeno] = $name unless defined $type[$typeno];
+ printf "new type $typeno is $name" if $debug;
+ if ($extra =~ /\*/ && defined $type[$struct]) {
+ print ", a typedef for a pointer to " , $type[$struct] if $debug;
+ }
+ } else {
+ printf "%s is type %d", $name, $typeno if $debug;
+ print ", a typedef for " , $type[$typeno] if $debug;
+ }
+ print "\n" if $debug;
+ #next unless $extra =~ /[su*]/;
+
+ #$type[$struct] = $name;
+
+ if ($extra =~ /[us*]/) {
+ &sou($name, $extra);
+ $_ = &sdecl($name, $_, 0);
+ }
+ elsif (/^=ar/) {
+ print "it's a bare array typedef -- that's pretty sick\n" if $debug;
+ $_ = "$typeno$_";
+ $scripts = '';
+ $_ = &adecl($_,1);
+
+ }
+ elsif (s/((\w+):t(\d+|\(\d+,\d+\)))?=r?(;\d+;\d+;)?//) { # the ?'s are for gcc
+ push(@intrinsics, $2);
+ $typeno = &typeno($3);
+ $type[$typeno] = $2;
+ print STDERR "intrinsic $2 in new type $typeno\n" if $debug;
+ }
+ elsif (s/^=e//) { # blessed by thy compiler; mine won't do this
+ &edecl;
+ }
+ else {
+ warn "Funny remainder for $name on line $_ left in $line " if $_;
+ }
+ }
+
+ sub typeno { # sun thinks types are (0,27) instead of just 27
+ local($_) = @_;
+ s/\(\d+,(\d+)\)/$1/;
+ $_;
+ }
+
+ sub pstruct {
+ local($what,$prefix,$base) = @_;
+ local($field, $fieldname, $typeno, $count, $offset, $entry);
+ local($fieldtype);
+ local($type, $tname);
+ local($mytype, $mycount, $entry2);
+ local($struct_count) = 0;
+ local($pad, $revpad, $length, $prepad, $lastoffset, $lastlength, $fmt);
+ local($bits,$bytes);
+ local($template);
+
+
+ local($mname) = &munge($name);
+
+ sub munge {
+ local($_) = @_;
+ s/[\s\$\.]/_/g;
+ $_;
+ }
+
+ local($sname) = &psou($what);
+
+ $nesting++;
+
+ for $field (split(/;/, $struct{$what})) {
+ $pad = $prepad = 0;
+ $entry = '';
+ ($fieldname, $typeno, $count, $offset, $length) = split(/,/, $field);
+
+ $type = $type[$typeno];
+
+ $type =~ /([^[]*)(\[.*\])?/;
+ $mytype = $1;
+ $count .= $2;
+ $fieldtype = &psou($mytype);
+
+ local($fname) = &psou($name);
+
+ if ($build_templates) {
+
+ $pad = ($offset - ($lastoffset + $lastlength))/8
+ if defined $lastoffset;
+
+ if (! $finished_template{$sname}) {
+ if ($isaunion{$what}) {
+ $template{$sname} .= 'X' x $revpad . ' ' if $revpad;
+ } else {
+ $template{$sname} .= 'x' x $pad . ' ' if $pad;
+ }
+ }
+
+ $template = &fetch_template($type) x
+ ($count ? &scripts2count($count) : 1);
+
+ if (! $finished_template{$sname}) {
+ $template{$sname} .= $template;
+ }
+
+ $revpad = $length/8 if $isaunion{$what};
+
+ ($lastoffset, $lastlength) = ($offset, $length);
+
+ } else {
+ print '# ' if $perl && $verbose;
+ $entry = sprintf($pmask1,
+ ' ' x ($nesting * $indent) . $fieldtype,
+ "$prefix.$fieldname" . $count);
+
+ $entry =~ s/(\*+)( )/$2$1/;
+
+ printf $pmask2,
+ $entry,
+ ($base+$offset)/8,
+ ($bits = ($base+$offset)%8) ? ".$bits" : " ",
+ $length/8,
+ ($bits = $length % 8) ? ".$bits": ""
+ if !$perl || $verbose;
+
+
+ if ($perl && $nesting == 1) {
+ $template = &scrunch(&fetch_template($type) x
+ ($count ? &scripts2count($count) : 1));
+ push(@sizeof, int($length/8) .",\t# $fieldname");
+ push(@offsetof, int($offset/8) .",\t# $fieldname");
+ push(@typedef, "'$template', \t# $fieldname");
+ $type =~ s/(struct|union) //;
+ push(@typeof, "'$type" . ($count ? $count : '') .
+ "',\t# $fieldname");
+ }
+
+ print ' ', ' ' x $indent x $nesting, $template
+ if $perl && $verbose;
+
+ print "\n" if !$perl || $verbose;
+
+ }
+ if ($perl) {
+ local($mycount) = defined $struct{$mytype} ? $countof{$mytype} : 1;
+ $mycount *= &scripts2count($count) if $count;
+ if ($nesting==1 && !$build_templates) {
+ $pcode .= sprintf("sub %-32s { %4d; }\n",
+ "${mname}'${fieldname}", $struct_count);
+ push(@indices, $struct_count);
+ }
+ $struct_count += $mycount;
+ }
+
+
+ &pstruct($type, "$prefix.$fieldname", $base+$offset)
+ if $recurse && defined $struct{$type};
+ }
+
+ $countof{$what} = $struct_count unless defined $countof{$whati};
+
+ $template{$sname} .= '$' if $build_templates;
+ $finished_template{$sname}++;
+
+ if ($build_templates && !defined $sizeof{$name}) {
+ local($fmt) = &scrunch($template{$sname});
+ print STDERR "no size for $name, punting with $fmt..." if $debug;
+ eval '$sizeof{$name} = length(pack($fmt, ()))';
+ if ($@) {
+ chop $@;
+ warn "couldn't get size for \$name: $@";
+ } else {
+ print STDERR $sizeof{$name}, "\n" if $debUg;
+ }
+ }
+
+ --$nesting;
+ }
+
+
+ sub psize {
+ local($me) = @_;
+ local($amstruct) = $struct{$me} ? 'struct ' : '';
+
+ print '$sizeof{\'', $amstruct, $me, '\'} = ';
+ printf "%d;\n", $sizeof{$me};
+ }
+
+ sub pdecl {
+ local($pdecl) = @_;
+ local(@pdecls);
+ local($tname);
+
+ warn "pdecl: $pdecl\n" if $debug;
+
+ $pdecl =~ s/\(\d+,(\d+)\)/$1/g;
+ $pdecl =~ s/\*//g;
+ @pdecls = split(/=/, $pdecl);
+ $typeno = $pdecls[0];
+ $tname = pop @pdecls;
+
+ if ($tname =~ s/^f//) { $tname = "$tname&"; }
+ #else { $tname = "$tname*"; }
+
+ for (reverse @pdecls) {
+ $tname .= s/^f// ? "&" : "*";
+ #$tname =~ s/^f(.*)/$1&/;
+ print "type[$_] is $tname\n" if $debug;
+ $type[$_] = $tname unless defined $type[$_];
+ }
+ }
+
+
+
+ sub adecl {
+ ($arraytype, $unknown, $lower, $upper) = ();
+ #local($typeno);
+ # global $typeno, @type
+ local($_, $typedef) = @_;
+
+ while (s/^((\d+)=)?ar(\d+);//) {
+ ($arraytype, $unknown) = ($2, $3);
+ if (s/^(\d+);(\d+);//) {
+ ($lower, $upper) = ($1, $2);
+ $scripts .= '[' . ($upper+1) . ']';
+ } else {
+ warn "can't find array bounds: $_";
+ }
+ }
+ if (s/^([\d*f=]*),(\d+),(\d+);//) {
+ ($start, $length) = ($2, $3);
+ local($whatis) = $1;
+ if ($whatis =~ /^(\d+)=/) {
+ $typeno = $1;
+ &pdecl($whatis);
+ } else {
+ $typeno = $whatis;
+ }
+ } elsif (s/^(\d+)(=[*suf]\d*)//) {
+ local($whatis) = $2;
+
+ if ($whatis =~ /[f*]/) {
+ &pdecl($whatis);
+ } elsif ($whatis =~ /[su]/) { #
+ print "$prefix.$fieldname is an array$scripts anon structs; disgusting\n"
+ if $debug;
+ #$type[$typeno] = $name unless defined $type[$typeno];
+ ##printf "new type $typeno is $name" if $debug;
+ $typeno = $1;
+ $type[$typeno] = "$prefix.$fieldname";
+ local($name) = $type[$typeno];
+ &sou($name, $whatis);
+ $_ = &sdecl($name, $_, $start+$offset);
+ 1;
+ $start = $start{$name};
+ $offset = $sizeof{$name};
+ $length = $offset;
+ } else {
+ warn "what's this? $whatis in $line ";
+ }
+ } elsif (/^\d+$/) {
+ $typeno = $_;
+ } else {
+ warn "bad array stab: $_ in $line ";
+ next STAB;
+ }
+ #local($wasdef) = defined($type[$typeno]) && $debug;
+ #if ($typedef) {
+ #print "redefining $type[$typeno] to " if $wasdef;
+ #$type[$typeno] = "$whatis$scripts"; # unless defined $type[$typeno];
+ #print "$type[$typeno]\n" if $wasdef;
+ #} else {
+ #$type[$arraytype] = $type[$typeno] unless defined $type[$arraytype];
+ #}
+ $type[$arraytype] = "$type[$typeno]$scripts" if defined $type[$typeno];
+ print "type[$arraytype] is $type[$arraytype]\n" if $debug;
+ print "$prefix.$fieldname is an array of $type[$arraytype]\n" if $debug;
+ $_;
+ }
+
+
+
+ sub sdecl {
+ local($prefix, $_, $offset) = @_;
+
+ local($fieldname, $scripts, $type, $arraytype, $unknown,
+ $whatis, $pdecl, $upper,$lower, $start,$length) = ();
+ local($typeno,$sou);
+
+
+ SFIELD:
+ while (/^([^;]+);/) {
+ $scripts = '';
+ warn "sdecl $_\n" if $debug;
+ if (s/^([\$\w]+)://) {
+ $fieldname = $1;
+ } elsif (s/(\d+)=([us])(\d+|\(\d+,\d+\))//) { #
+ $typeno = &typeno($1);
+ $type[$typeno] = "$prefix.$fieldname";
+ local($name) = "$prefix.$fieldname";
+ &sou($name,$2);
+ $_ = &sdecl("$prefix.$fieldname", $_, $start+$offset);
+ $start = $start{$name};
+ $offset += $sizeof{$name};
+ #print "done with anon, start is $start, offset is $offset\n";
+ #next SFIELD;
+ } else {
+ warn "weird field $_ of $line" if $debug;
+ next STAB;
+ #$fieldname = &gensym;
+ #$_ = &sdecl("$prefix.$fieldname", $_, $start+$offset);
+ }
+
+ if (/^\d+=ar/) {
+ $_ = &adecl($_);
+ }
+ elsif (s/^(\d+|\(\d+,\d+\))?,(\d+),(\d+);//) {
+ ($start, $length) = ($2, $3);
+ &panic("no length?") unless $length;
+ $typeno = &typeno($1) if $1;
+ }
+ elsif (s/^((\d+|\(\d+,\d+\))(=[*f](\d+|\(\d+,\d+\)))+),(\d+),(\d+);//) {
+ ($pdecl, $start, $length) = ($1,$5,$6);
+ &pdecl($pdecl);
+ }
+ elsif (s/(\d+)=([us])(\d+|\(\d+,\d+\))//) { # the dratted anon struct
+ ($typeno, $sou) = ($1, $2);
+ $typeno = &typeno($typeno);
+ if (defined($type[$typeno])) {
+ warn "now how did we get type $1 in $fieldname of $line?";
+ } else {
+ print "anon type $typeno is $prefix.$fieldname\n" if $debug;
+ $type[$typeno] = "$prefix.$fieldname" unless defined $type[$typeno];
+ };
+ local($name) = "$prefix.$fieldname";
+ &sou($name,$sou);
+ print "anon ".($isastruct{$name}) ? "struct":"union"." for $prefix.$fieldname\n" if $debug;
+ $type[$typeno] = "$prefix.$fieldname";
+ $_ = &sdecl("$prefix.$fieldname", $_, $start+$offset);
+ $start = $start{$name};
+ $length = $sizeof{$name};
+ }
+ else {
+ warn "can't grok stab for $name ($_) in line $line ";
+ next STAB;
+ }
+
+ &panic("no length for $prefix.$fieldname") unless $length;
+ $struct{$name} .= join(',', $fieldname, $typeno, $scripts, $start, $length) . ';';
+ }
+ if (s/;\d*,(\d+),(\d+);//) {
+ local($start, $size) = ($1, $2);
+ $sizeof{$prefix} = $size;
+ print "start of $prefix is $start, size of $sizeof{$prefix}\n" if $debug;
+ $start{$prefix} = $start;
+ }
+ $_;
+ }
+
+ sub edecl {
+ s/;$//;
+ $enum{$name} = $_;
+ $_ = '';
+ }
+
+ sub resolve_types {
+ local($sou);
+ for $i (0 .. $#type) {
+ next unless defined $type[$i];
+ $_ = $type[$i];
+ unless (/\d/) {
+ print "type[$i] $type[$i]\n" if $debug;
+ next;
+ }
+ print "type[$i] $_ ==> " if $debug;
+ s/^(\d+)(\**)\&\*(\**)/"$2($3".&type($1) . ')()'/e;
+ s/^(\d+)\&/&type($1)/e;
+ s/^(\d+)/&type($1)/e;
+ s/(\*+)([^*]+)(\*+)/$1$3$2/;
+ s/\((\*+)(\w+)(\*+)\)/$3($1$2)/;
+ s/^(\d+)([\*\[].*)/&type($1).$2/e;
+ #s/(\d+)(\*|(\[[\[\]\d\*]+]\])+)/&type($1).$2/ge;
+ $type[$i] = $_;
+ print "$_\n" if $debug;
+ }
+ }
+ sub type { &psou($type[$_[0]] || "<UNDEFINED>"); }
+
+ sub adjust_start_addrs {
+ for (sort keys %start) {
+ ($basename = $_) =~ s/\.[^.]+$//;
+ $start{$_} += $start{$basename};
+ print "start: $_ @ $start{$_}\n" if $debug;
+ }
+ }
+
+ sub sou {
+ local($what, $_) = @_;
+ /u/ && $isaunion{$what}++;
+ /s/ && $isastruct{$what}++;
+ }
+
+ sub psou {
+ local($what) = @_;
+ local($prefix) = '';
+ if ($isaunion{$what}) {
+ $prefix = 'union ';
+ } elsif ($isastruct{$what}) {
+ $prefix = 'struct ';
+ }
+ $prefix . $what;
+ }
+
+ sub scrunch {
+ local($_) = @_;
+
+ study;
+
+ s/\$//g;
+ s/ / /g;
+ 1 while s/(\w) \1/$1$1/g;
+
+ # i wanna say this, but perl resists my efforts:
+ # s/(\w)(\1+)/$2 . length($1)/ge;
+
+ &quick_scrunch;
+
+ s/ $//;
+
+ $_;
+ }
+
+ sub buildscrunchlist {
+ $scrunch_code = "sub quick_scrunch {\n";
+ for (values %intrinsics) {
+ $scrunch_code .= "\ts/($_{2,})/'$_' . length(\$1)/ge;\n";
+ }
+ $scrunch_code .= "}\n";
+ print "$scrunch_code" if $debug;
+ eval $scrunch_code;
+ &panic("can't eval scrunch_code $@ \nscrunch_code") if $@;
+ }
+
+ sub fetch_template {
+ local($mytype) = @_;
+ local($fmt);
+ local($count) = 1;
+
+ &panic("why do you care?") unless $perl;
+
+ if ($mytype =~ s/(\[\d+\])+$//) {
+ $count .= $1;
+ }
+
+ if ($mytype =~ /\*/) {
+ $fmt = $template{'pointer'};
+ }
+ elsif (defined $template{$mytype}) {
+ $fmt = $template{$mytype};
+ }
+ elsif (defined $struct{$mytype}) {
+ if (!defined $template{&psou($mytype)}) {
+ &build_template($mytype) unless $mytype eq $name;
+ }
+ elsif ($template{&psou($mytype)} !~ /\$$/) {
+ #warn "incomplete template for $mytype\n";
+ }
+ $fmt = $template{&psou($mytype)} || '?';
+ }
+ else {
+ warn "unknown fmt for $mytype\n";
+ $fmt = '?';
+ }
+
+ $fmt x $count . ' ';
+ }
+
+ sub compute_intrinsics {
+ local($TMP) = "/tmp/c2ph-i.$$.c";
+ open (TMP, ">$TMP") || die "can't open $TMP: $!";
+ select(TMP);
+
+ print STDERR "computing intrinsic sizes: " if $trace;
+
+ undef %intrinsics;
+
+ print <<'EOF';
+ main() {
+ char *mask = "%d %s\n";
+ EOF
+
+ for $type (@intrinsics) {
+ next if $type eq 'void';
+ print <<"EOF";
+ printf(mask,sizeof($type), "$type");
+ EOF
+ }
+
+ print <<'EOF';
+ printf(mask,sizeof(char *), "pointer");
+ exit(0);
+ }
+ EOF
+ close TMP;
+
+ select(STDOUT);
+ open(PIPE, "cd /tmp && $CC $TMP && /tmp/a.out|");
+ while (<PIPE>) {
+ chop;
+ split(' ',$_,2);;
+ print "intrinsic $_[1] is size $_[0]\n" if $debug;
+ $sizeof{$_[1]} = $_[0];
+ $intrinsics{$_[1]} = $template{$_[0]};
+ }
+ close(PIPE) || die "couldn't read intrinsics!";
+ unlink($TMP, '/tmp/a.out');
+ print STDERR "done\n" if $trace;
+ }
+
+ sub scripts2count {
+ local($_) = @_;
+
+ s/^\[//;
+ s/\]$//;
+ s/\]\[/*/g;
+ $_ = eval;
+ &panic("$_: $@") if $@;
+ $_;
+ }
+
+ sub system {
+ print STDERR "@_\n" if $trace;
+ system @_;
+ }
+
+ sub build_template {
+ local($name) = @_;
+
+ &panic("already got a template for $name") if defined $template{$name};
+
+ local($build_templates) = 1;
+
+ local($lparen) = '(' x $build_recursed;
+ local($rparen) = ')' x $build_recursed;
+
+ print STDERR "$lparen$name$rparen " if $trace;
+ $build_recursed++;
+ &pstruct($name,$name,0);
+ print STDERR "TEMPLATE for $name is ", $template{&psou($name)}, "\n" if $debug;
+ --$build_recursed;
+ }
+
+
+ sub panic {
+
+ select(STDERR);
+
+ print "\npanic: @_\n";
+
+ exit 1 if $] <= 4.003; # caller broken
+
+ local($i,$_);
+ local($p,$f,$l,$s,$h,$a,@a,@sub);
+ for ($i = 0; ($p,$f,$l,$s,$h,$w) = caller($i); $i++) {
+ @a = @DB'args;
+ for (@a) {
+ if (/^StB\000/ && length($_) == length($_main{'_main'})) {
+ $_ = sprintf("%s",$_);
+ }
+ else {
+ s/'/\\'/g;
+ s/([^\0]*)/'$1'/ unless /^-?[\d.]+$/;
+ s/([\200-\377])/sprintf("M-%c",ord($1)&0177)/eg;
+ s/([\0-\37\177])/sprintf("^%c",ord($1)^64)/eg;
+ }
+ }
+ $w = $w ? '@ = ' : '$ = ';
+ $a = $h ? '(' . join(', ', @a) . ')' : '';
+ push(@sub, "$w&$s$a from file $f line $l\n");
+ last if $signal;
+ }
+ for ($i=0; $i <= $#sub; $i++) {
+ last if $signal;
+ print $sub[$i];
+ }
+ exit 1;
+ }
+
+ sub squishseq {
+ local($num);
+ local($last) = -1e8;
+ local($string);
+ local($seq) = '..';
+
+ while (defined($num = shift)) {
+ if ($num == ($last + 1)) {
+ $string .= $seq unless $inseq++;
+ $last = $num;
+ next;
+ } elsif ($inseq) {
+ $string .= $last unless $last == -1e8;
+ }
+
+ $string .= ',' if defined $string;
+ $string .= $num;
+ $last = $num;
+ $inseq = 0;
+ }
+ $string .= $last if $inseq && $last != -e18;
+ $string;
+ }
Index: lib/pwd.pl
Prereq: 4.0
*** lib/pwd.pl.old Mon Jun 8 17:49:09 1992
--- lib/pwd.pl Mon Jun 8 17:49:10 1992
***************
*** 1,8 ****
;# pwd.pl - keeps track of current working directory in PWD environment var
;#
! ;# $Header: pwd.pl,v 4.0 91/03/20 01:26:03 lwall Locked $
;#
;# $Log: pwd.pl,v $
;# Revision 4.0 91/03/20 01:26:03 lwall
;# 4.0 baseline.
;#
--- 1,11 ----
;# pwd.pl - keeps track of current working directory in PWD environment var
;#
! ;# $RCSfile: pwd.pl,v $$Revision: 4.0.1.1 $$Date: 92/06/08 13:45:22 $
;#
;# $Log: pwd.pl,v $
+ ;# Revision 4.0.1.1 92/06/08 13:45:22 lwall
+ ;# patch20: support added to pwd.pl to strip automounter crud
+ ;#
;# Revision 4.0 91/03/20 01:26:03 lwall
;# 4.0 baseline.
;#
***************
*** 25,33 ****
if ($ENV{'PWD'}) {
local($dd,$di) = stat('.');
local($pd,$pi) = stat($ENV{'PWD'});
! return if $di == $pi && $dd == $pd;
}
! chop($ENV{'PWD'} = `pwd`);
}
sub main'chdir {
--- 28,47 ----
if ($ENV{'PWD'}) {
local($dd,$di) = stat('.');
local($pd,$pi) = stat($ENV{'PWD'});
! if ($di != $pi || $dd != $pd) {
! chop($ENV{'PWD'} = `pwd`);
! }
}
! else {
! chop($ENV{'PWD'} = `pwd`);
! }
! if ($ENV{'PWD'} =~ m|(/[^/]+(/[^/]+/[^/]+))(.*)|) {
! local($pd,$pi) = stat($2);
! local($dd,$di) = stat($1);
! if ($di == $pi && $dd == $pd) {
! $ENV{'PWD'}="$2$3";
! }
! }
}
sub main'chdir {
Index: t/op/readdir.t
*** t/op/readdir.t.old Mon Jun 8 17:52:11 1992
--- t/op/readdir.t Mon Jun 8 17:52:11 1992
***************
*** 6,18 ****
print "1..3\n";
if (opendir(OP, "op")) { print "ok 1\n"; } else { print "not ok 1\n"; }
! @D = grep(/^[^\.]/, readdir(OP));
closedir(OP);
if (@D > 20 && @D < 100) { print "ok 2\n"; } else { print "not ok 2\n"; }
@R = sort @D;
! @G = <op/*>;
while (@R && @G && "op/".$R[0] eq $G[0]) {
shift(@R);
shift(@G);
--- 6,18 ----
print "1..3\n";
if (opendir(OP, "op")) { print "ok 1\n"; } else { print "not ok 1\n"; }
! @D = grep(/^[^\.].*\.t$/, readdir(OP));
closedir(OP);
if (@D > 20 && @D < 100) { print "ok 2\n"; } else { print "not ok 2\n"; }
@R = sort @D;
! @G = <op/*.t>;
while (@R && @G && "op/".$R[0] eq $G[0]) {
shift(@R);
shift(@G);
Index: atarist/test/readme
*** atarist/test/readme.old Mon Jun 8 17:45:19 1992
--- atarist/test/readme Mon Jun 8 17:45:19 1992
***************
*** 0 ****
--- 1,3 ----
+ this directory contain simple tests for the atariST port. to run a test
+ simply enter
+ perl file
Index: hints/ultrix_1.sh
*** hints/ultrix_1.sh.old Mon Jun 8 17:48:25 1992
--- hints/ultrix_1.sh Mon Jun 8 17:48:26 1992
***************
*** 0 ****
--- 1 ----
+ ccflags="$ccflags -DULTRIX_STDIO_BOTCH"
*** End of Patch 30 ***
exit 0 # Just in case...