Front page | perl.perl5.porters |
Postings from September 2003
<DIRHANDLE>
Thread Previous
|
Thread Next
From:
Abhijit Menon-Sen
Date:
September 5, 2003 16:34
Subject:
<DIRHANDLE>
Message ID:
20030906050328.A22717@lustre.dyn.wiw.org
The appended patch implements <>/readline() for directory handles, and
makes it return a filename for each line read.
What do people think of this idea?
(I know the actual code could stand some improvement, such as renaming
readdir_helper and moving it to util.c, eliminating more repeated code
from readline, and so on. But I'll bother with all that only if anyone
is actually interested in the patch.)
In any case, pp_readdir() deserves to be cleaned up. I will.
-- ams
==== //depot/perl/pp_hot.c#326 - /home/ams/build/perl/current/pp_hot.c ====
--- /tmp/tmp.22706.0 Sat Sep 6 04:48:19 2003
+++ /home/ams/build/perl/current/pp_hot.c Sat Sep 6 04:34:37 2003
@@ -1471,14 +1471,35 @@ Perl_do_readline(pTHX)
}
fp = nextargv(PL_last_in_gv);
if (!fp) { /* Note: fp != IoIFP(io) */
- (void)do_close(PL_last_in_gv, FALSE); /* now it does*/
+ (void)do_close(PL_last_in_gv, FALSE); /* now it does */
}
}
- else if (type == OP_GLOB)
+ else if (type == OP_GLOB) {
fp = Perl_start_glob(aTHX_ POPs, io);
+ }
+ else if (IoDIRP(io)) {
+ extern int readdir_helper(IO *io, SV *sv);
+ if (gimme == G_SCALAR) {
+ if (readdir_helper(io, TARG) < 0)
+ RETPUSHUNDEF;
+ PUSHTARG;
+ RETURN;
+ }
+ else {
+ do {
+ SV *sv = sv_2mortal(newSVpvn("", 0));
+ if (readdir_helper(io, sv) < 0)
+ break;
+ XPUSHs(sv);
+ }
+ while (1);
+ RETURN;
+ }
+ }
}
- else if (type == OP_GLOB)
+ else if (type == OP_GLOB) {
SP--;
+ }
else if (ckWARN(WARN_IO) && IoTYPE(io) == IoTYPE_WRONLY) {
report_evil_fh(PL_last_in_gv, io, OP_phoney_OUTPUT_ONLY);
}
==== //depot/perl/pp_sys.c#355 - /home/ams/build/perl/current/pp_sys.c ====
--- /tmp/tmp.22706.1 Sat Sep 6 04:48:33 2003
+++ /home/ams/build/perl/current/pp_sys.c Sat Sep 6 04:21:08 2003
@@ -3794,62 +3794,61 @@ nope:
#endif
}
-PP(pp_readdir)
+int
+readdir_helper(register IO *io, SV *sv)
{
-#if defined(Direntry_t) && defined(HAS_READDIR)
- dSP;
+#if !defined(Direntry_t) || !defined(HAS_READDIR)
+ DIE(aTHX_ PL_no_dir_func, "readdir");
+#else
#if !defined(I_DIRENT) && !defined(VMS)
Direntry_t *readdir (DIR *);
#endif
register Direntry_t *dp;
- GV *gv = (GV*)POPs;
- register IO *io = GvIOn(gv);
- SV *sv;
if (!io || !IoDIRP(io))
- goto nope;
+ goto nope;
- if (GIMME == G_ARRAY) {
- /*SUPPRESS 560*/
- while ((dp = (Direntry_t *)PerlDir_read(IoDIRP(io)))) {
+ dp = (Direntry_t *)PerlDir_read(IoDIRP(io));
+ if (dp) {
#ifdef DIRNAMLEN
- sv = newSVpvn(dp->d_name, dp->d_namlen);
+ sv_setpvn(sv, dp->d_name, dp->d_namlen);
#else
- sv = newSVpv(dp->d_name, 0);
+ sv_setpv(sv, dp->d_name);
#endif
#ifndef INCOMPLETE_TAINTS
- if (!(IoFLAGS(io) & IOf_UNTAINT))
- SvTAINTED_on(sv);
+ if (!(IoFLAGS(io) & IOf_UNTAINT))
+ SvTAINTED_on(sv);
#endif
- XPUSHs(sv_2mortal(sv));
- }
+ return 0;
}
- else {
- if (!(dp = (Direntry_t *)PerlDir_read(IoDIRP(io))))
- goto nope;
-#ifdef DIRNAMLEN
- sv = newSVpvn(dp->d_name, dp->d_namlen);
-#else
- sv = newSVpv(dp->d_name, 0);
-#endif
-#ifndef INCOMPLETE_TAINTS
- if (!(IoFLAGS(io) & IOf_UNTAINT))
- SvTAINTED_on(sv);
-#endif
- XPUSHs(sv_2mortal(sv));
- }
- RETURN;
nope:
if (!errno)
- SETERRNO(EBADF,RMS_ISI);
- if (GIMME == G_ARRAY)
- RETURN;
- else
- RETPUSHUNDEF;
-#else
- DIE(aTHX_ PL_no_dir_func, "readdir");
+ SETERRNO(EBADF,RMS_ISI);
+ return -1;
#endif
+}
+
+PP(pp_readdir)
+{
+ dSP;
+ int n = 0;
+ int gimme = GIMME;
+ GV *gv = (GV *)POPs;
+
+ do {
+ SV *sv = sv_2mortal(newSVpvn("", 0));
+
+ if (readdir_helper(GvIOn(gv), sv) < 0)
+ break;
+ XPUSHs(sv);
+ n++;
+ }
+ while (gimme == G_ARRAY);
+
+ if (n == 0 && gimme != G_ARRAY)
+ RETPUSHUNDEF;
+ RETURN;
}
PP(pp_telldir)
Thread Previous
|
Thread Next