bll@seer.UUCP (Brad Lanam) (09/05/90)
I just brought perl up to patchlevel 28, and everything except Tom Christiansen's man program seems to work. It can't seem to find anything in the dbm database. I rebuilt the database, but that didn't help. He uses those eval things... I can't figure out how to print out what is in the dbm array. Has anyone else had this problem? I'm running Xenix 2.3.2. Thanx -- Brad -- Until the next disk seek... -- Brad Lanam ...!uunet!{seeker|unisoft}!seer!bll bll@seer.uucp -- The pertinent sections: sub fetch { local($key,$root) = @_; local(%recursed); return $dbmopened{$root} ? &quick_fetch($key,$dbm{$root}) : &slow_fetch($key,$root); } sub quick_fetch { local($key,$array) = @_; local(@retlist) = (); local(@tmplist) = (); local($_, $entry); ############# this line doesn't find a thing ########## return @retlist unless $entry = eval "\$$array".'{$key};'; if ($@) { chop $@; die "bad eval: $@"; } @tmplist = split(/\002/, $entry); for (@tmplist) { if (/\001/) { push(@retlist, $_); } else { push(@retlist, &quick_fetch($_,$array)) unless $recursed{$_}++; # explain and diction are near duplicate man pages referencing # each other, requiring this check. one should be removed } } return @retlist; } # -------------------------------------------------------------------------- sub find_files { local($target) = @_; local($root, $entry); local(@retlist) = (); local(@tmplist) = (); local(@entries) = (); # globals: $vars, $called_before, %dbm $vars = 'dbm00'; if (!$hard_way && !$called_before++) { # generate dbm names for $root (@MANPATH) { $dbm{$root} = $vars++; # magic incr $string = "dbmopen($dbm{$root},\"$root/whatis\",0644);"; unless (-f "$root/whatis.pag" && eval $string) { if ($@) { chop $@; warn "Can't eval $string: $@"; } else { warn "No dbm file for $root/whatis: $!\n"; } $status = 1; next; } $dbmopened{$root} = 1; } } for $root (@MANPATH) { @tmplist = (); unless ($dbmopened{$root}) { @tmplist = &slow_fetch($target,$root); } else { @entries = &fetch($target,$root); next if $#entries < 0; for $entry (@entries) { ($cmd, $page, $section, $desc) = split(/\001/, $entry); $target =~ s/([^\w])/\\$1/g; next unless $cmd =~ /$target/ || $page =~ /$target/; ($stem) = $section =~ /^(.)/; # Check that it exists if (-f "$root/man.$stem/$page.$section") { push(@tmplist, "$root/man.$stem/$page.$section"); # perhaps it is compressed ? } elsif (-f "$root/man.$stem.z/$page.$section") { push(@tmplist, "$root/man.$stem.z/$page.$section"); } elsif (-f "$root/man.$stem/$page.$section.z") { push(@tmplist, "$root/man.$stem/$page.$section.z"); # perhaps a strange section (i.e. 1m)? } elsif (-f "$root/man.$section/$page.$section") { push(@tmplist, "$root/man.$section/$page.$section"); # perhaps a strange section (i.e. 1m) AND compressed? } elsif (-f "$root/man.$section.z/$page.$section") { push(@tmplist, "$root/man.$section.z/$page.$section"); } elsif (-f "$root/man.$section/$page.$section.z") { push(@tmplist, "$root/man.$section/$page.$section.z"); } else { printf STDERR "%s: %s.%s has disappeared from %s/man%s\n", $program, $page, $section, $root, $stem; last; } } } push(@retlist, sort bysection @tmplist); } return &trimdups(@retlist); } -- Until the next disk seek... -- Brad Lanam ...!uunet!{seeker|unisoft}!seer!bll bll@seer.uucp
nagel@wintermute.ics.uci.edu (Mark Nagel) (09/06/90)
bll@seer.UUCP (Brad Lanam) writes: > I just brought perl up to patchlevel 28, and everything except >Tom Christiansen's man program seems to work. It can't seem to find >anything in the dbm database. I rebuilt the database, but that didn't >help. He uses those eval things... I can't figure out how to print >out what is in the dbm array. > Has anyone else had this problem? > I'm running Xenix 2.3.2. Yes. I'm running pl28 on a Sequent Symmetry (Dynix 3.0.12) and it also exhibits the same problem. While in the debugger, I can print keys(dbm00) and values(dbm00), but actually referencing $dbm00{some_key} fails for whatever (valid) key is used. I don't think it is a bug in man, but a bug in dbm access under pl28. -- Mark Nagel UC Irvine Depertment of ICS +----------------------------------------+ ARPA: nagel@ics.uci.edu | If you improve something long enough | UUCP: ucbvax!ucivax!nagel | eventually you will throw it away. |
tchrist@convex.COM (Tom Christiansen) (09/06/90)
In article <578@seer.UUCP> bll@seer.UUCP (Brad Lanam) writes: > > I just brought perl up to patchlevel 28, and everything except >Tom Christiansen's man program seems to work. It can't seem to find >anything in the dbm database. I rebuilt the database, but that didn't >help. He uses those eval things... I can't figure out how to print >out what is in the dbm array. You should say 'those damn eval things.' :-) > Has anyone else had this problem? Yes. Here's mail I received on this. I must shamefully admit that I've not gone to PL28 yet, so haven't seen it -- yet. Maybe Larry can explain. ------- Forwarded Message Date: Fri, 17 Aug 90 14:44:48 METDST From: Jan Dj{rv <jhd@irfu.se> Subject: Perl PL 28 has made your man unoperational :-( To: tchrist@irfu.se (Tom Christiansen) Hi, I installed perl PL 28 today. After installation I did 'man perl'. To my big surprise I get No dbm file for /usr/local/man/whatis: Permission denied No dbm file for /usr/contrib/man/whatis: Permission denied No dbm file for /usr/man/whatis: Permission denied A bit of poking around shows that patch 22 disabled the ability to dbmopen a file readonly. (I've sent Larry a letter about this, but since the machine that supply me with News is down, nothing to comp.lang.perl). Here's my patch in case you are interested: *** hash.c.orig Fri Aug 17 12:21:04 1990 - --- hash.c Fri Aug 17 12:22:45 1990 *************** *** 538,543 **** - --- 538,545 ---- tb->tbl_dbm = dbm_open(fname, O_RDWR|O_CREAT, mode); if (!tb->tbl_dbm) tb->tbl_dbm = dbm_open(fname, O_RDWR, mode); + if (!tb->tbl_dbm) + tb->tbl_dbm = dbm_open(fname, O_RDONLY, mode); #else if (dbmrefcnt++) fatal("Old dbm can only open one database"); Could you perhaps post something about it to c.l.p (if not already done by somebody else) ? OK, I tried it again: % man perl No manual entry for perl. Rerun makewhatis. Same thing. Everything I try to man gives me 'No manual entry for ...'. Have you seen any of this? Do you know whats going on? In the meantime I'm back to non-perlian man :-( Jan D. - -- ------------------------------------------------------------------------ Swedish Institute of Space Physics, S-755 91 Uppsala, Sweden Phone: (+46) 18-403005. Telex: 76036 (IRFUPP S). Fax: (+46) 18-403100 INTERNET: jhd@irfu.se UUCP: ...!uunet!mcvax!sunic!irfu!jhd ------------------------------------------------------------------------ ------- End of Forwarded Message -- "UNIX was never designed to keep people from doing stupid things, because that policy would also keep them from doing clever things." [Doug Gwyn]
jand@kuling.UUCP (Jan Dj{rv) (09/06/90)
In article <578@seer.UUCP> bll@seer.UUCP (Brad Lanam) writes: > > I just brought perl up to patchlevel 28, and everything except >Tom Christiansen's man program seems to work. It can't seem to find >anything in the dbm database. I rebuilt the database, but that didn't >help. He uses those eval things... I can't figure out how to print >out what is in the dbm array. > > Has anyone else had this problem? The man program uses ndbm and PL 28 has problems with it. It's not anything wrong with Tom's program, it's perl. The first problem is that perl doesn't allow open of a dbm file readonly. Here's my patch for that: *** hash.c.Distributed Fri Aug 17 12:26:43 1990 --- hash.c Mon Aug 20 09:19:37 1990 *************** *** 538,543 **** --- 538,545 ---- tb->tbl_dbm = dbm_open(fname, O_RDWR|O_CREAT, mode); if (!tb->tbl_dbm) tb->tbl_dbm = dbm_open(fname, O_RDWR, mode); + if (!tb->tbl_dbm) + tb->tbl_dbm = dbm_open(fname, O_RDONLY, mode); #else if (dbmrefcnt++) fatal("Old dbm can only open one database"); *************** *** 551,556 **** --- 553,560 ---- } tb->tbl_dbm = dbminit(fname) >= 0; #endif + if (!tb->tbl_array && tb->tbl_dbm != 0) + Newz(507,tb->tbl_array, tb->tbl_max + 1, HENT*); return tb->tbl_dbm != 0; } The other problem (the one you encountered) was discovered by Andrew Vignaux <Andrew.Vignaux@comp.vuw.ac.nz>. I include his posting here. With these two patches Tom's man works OK for me. Jan D. Andrew Vignaux writes: I think the problem is in the lazy array creation that went in in pl.28. hfetch() only creates the array if the access is an lval and it hasn't been stored into already. Unfortunately, dbm files can already have stuff in them. The local fix: if (!tb->tbl_array) { ! if (lval) Newz(503,tb->tbl_array, tb->tbl_max + 1, HENT*); to if (!tb->tbl_array) { ! if (lval || tb->tbl_dbm) Newz(503,tb->tbl_array, tb->tbl_max + 1, HENT*); works, but it means that dbmopen(FOO,"foo",0666); print defined(%FOO), "\n"; still prints 0. Here's a completely unofficial patch that (I think) fixes this problem. I'm posting this because I can't believe I'm the only one who depends on dbm files in perl. I don't want to go back to 18 because of the lack of dbmopen(FOO, "foo", undef) ;-) *** ./hash.c~ Tue Aug 14 21:17:53 1990 --- ./hash.c Sat Aug 18 14:22:50 1990 *************** *** 551,556 **** --- 551,558 ---- } tb->tbl_dbm = dbminit(fname) >= 0; #endif + if (!tb->tbl_array && tb->tbl_dbm != 0) + Newz(507,tb->tbl_array, tb->tbl_max + 1, HENT*); return tb->tbl_dbm != 0; } This fix also means that dbmopen(FOO,"foo",undef); print defined(%FOO), "\n"; and dbmopen(BAR,"bar",0666); print defined(%BAR), "\n"; prints 0 if "foo.dir" doesn't exist, or "bar.{dir,pag}" can't be created. Both "fixes" pass make test on a MORE/bsd hp300. Andrew -- Domain address: Andrew.Vignaux@comp.vuw.ac.nz