This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
the return value of start_subparse() can legally be ignored
[perl5.git] / perlio.c
index 9cd24d2..86cc827 100644 (file)
--- a/perlio.c
+++ b/perlio.c
@@ -66,7 +66,7 @@ int mkstemp(char*);
 /* Call the callback or PerlIOBase, and return failure. */
 #define Perl_PerlIO_or_Base(f, callback, base, failure, args)  \
        if (PerlIOValid(f)) {                                   \
-               const PerlIO_funcs *tab = PerlIOBase(f)->tab;   \
+               const PerlIO_funcs * const tab = PerlIOBase(f)->tab;\
                if (tab && tab->callback)                       \
                        return (*tab->callback) args;           \
                else                                            \
@@ -79,7 +79,7 @@ int mkstemp(char*);
 /* Call the callback or fail, and return failure. */
 #define Perl_PerlIO_or_fail(f, callback, failure, args)        \
        if (PerlIOValid(f)) {                                   \
-               const PerlIO_funcs *tab = PerlIOBase(f)->tab;   \
+               const PerlIO_funcs * const tab = PerlIOBase(f)->tab;\
                if (tab && tab->callback)                       \
                        return (*tab->callback) args;           \
                SETERRNO(EINVAL, LIB_INVARG);                   \
@@ -91,7 +91,7 @@ int mkstemp(char*);
 /* Call the callback or PerlIOBase, and be void. */
 #define Perl_PerlIO_or_Base_void(f, callback, base, args)      \
        if (PerlIOValid(f)) {                                   \
-               const PerlIO_funcs *tab = PerlIOBase(f)->tab;   \
+               const PerlIO_funcs * const tab = PerlIOBase(f)->tab;\
                if (tab && tab->callback)                       \
                        (*tab->callback) args;                  \
                else                                            \
@@ -103,7 +103,7 @@ int mkstemp(char*);
 /* Call the callback or fail, and be void. */
 #define Perl_PerlIO_or_fail_void(f, callback, args)            \
        if (PerlIOValid(f)) {                                   \
-               const PerlIO_funcs *tab = PerlIOBase(f)->tab;   \
+               const PerlIO_funcs * const tab = PerlIOBase(f)->tab;\
                if (tab && tab->callback)                       \
                        (*tab->callback) args;                  \
                else                                            \
@@ -747,7 +747,7 @@ PerlIO_find_layer(pTHX_ const char *name, STRLEN len, int load)
     if ((SSize_t) len <= 0)
        len = strlen(name);
     for (i = 0; i < PL_known_layers->cur; i++) {
-       PerlIO_funcs *f = PL_known_layers->array[i].funcs;
+       PerlIO_funcs * const f = PL_known_layers->array[i].funcs;
        if (memEQ(f->name, name, len) && f->name[len] == 0) {
            PerlIO_debug("%.*s => %p\n", (int) len, name, (void*)f);
            return f;
@@ -759,10 +759,10 @@ PerlIO_find_layer(pTHX_ const char *name, STRLEN len, int load)
            Perl_croak(aTHX_ "Recursive call to Perl_load_module in PerlIO_find_layer");
            return NULL;
        } else {
-           SV *pkgsv = newSVpvn("PerlIO", 6);
-           SV *layer = newSVpvn(name, len);
-           CV *cv  = get_cv("PerlIO::Layer::NoWarnings", FALSE);
-           ENTER;
+           SV * const pkgsv = newSVpvn("PerlIO", 6);
+           SV * const layer = newSVpvn(name, len);
+           CV * const cv    = get_cv("PerlIO::Layer::NoWarnings", FALSE);
+           ENTER;
            SAVEINT(PL_in_load_module);
            if (cv) {
                SAVEGENERICSV(PL_warnhook);
@@ -866,8 +866,8 @@ XS(XS_io_MODIFY_SCALAR_ATTRIBUTES)
 SV *
 PerlIO_tab_sv(pTHX_ PerlIO_funcs *tab)
 {
-    HV *stash = gv_stashpv("PerlIO::Layer", TRUE);
-    SV *sv = sv_bless(newRV_noinc(newSViv(PTR2IV(tab))), stash);
+    HV * const stash = gv_stashpv("PerlIO::Layer", TRUE);
+    SV * const sv = sv_bless(newRV_noinc(newSViv(PTR2IV(tab))), stash);
     return sv;
 }
 
@@ -889,9 +889,9 @@ XS(XS_PerlIO__Layer__find)
        Perl_croak(aTHX_ "Usage class->find(name[,load])");
     else {
        STRLEN len;
-       const char *name = SvPV_const(ST(1), len);
+       const char * const name = SvPV_const(ST(1), len);
        const bool load = (items > 2) ? SvTRUE(ST(2)) : 0;
-       PerlIO_funcs *layer = PerlIO_find_layer(aTHX_ name, len, load);
+       PerlIO_funcs * const layer = PerlIO_find_layer(aTHX_ name, len, load);
        ST(0) =
            (layer) ? sv_2mortal(PerlIO_tab_sv(aTHX_ layer)) :
            &PL_sv_undef;
@@ -979,7 +979,7 @@ PerlIO_parse_layers(pTHX_ PerlIO_list_t *av, const char *names)
                    }
                }
                if (e > s) {
-                   PerlIO_funcs *layer =
+                   PerlIO_funcs * const layer =
                        PerlIO_find_layer(aTHX_ s, llen, 1);
                    if (layer) {
                        PerlIO_list_push(aTHX_ av, layer,
@@ -1134,7 +1134,7 @@ Perl_boot_core_PerlIO(pTHX)
 PerlIO_funcs *
 PerlIO_default_layer(pTHX_ I32 n)
 {
-    PerlIO_list_t *av = PerlIO_default_layers(aTHX);
+    PerlIO_list_t * const av = PerlIO_default_layers(aTHX);
     if (n < 0)
        n += av->cur;
     return PerlIO_layer_fetch(aTHX_ av, n, PERLIO_FUNCS_CAST(&PerlIO_stdio));
@@ -1351,7 +1351,7 @@ int
 PerlIO__close(pTHX_ PerlIO *f)
 {
     if (PerlIOValid(f)) {
-       PerlIO_funcs *tab = PerlIOBase(f)->tab;
+       PerlIO_funcs * const tab = PerlIOBase(f)->tab;
        if (tab && tab->Close)
            return (*tab->Close)(aTHX_ f);
        else
@@ -1445,7 +1445,7 @@ PerlIO_resolve_layers(pTHX_ const char *layers,
         * for it
         */
        if (SvROK(arg) && !sv_isobject(arg)) {
-           PerlIO_funcs *handler = PerlIO_layer_from_ref(aTHX_ SvRV(arg));
+           PerlIO_funcs * const handler = PerlIO_layer_from_ref(aTHX_ SvRV(arg));
            if (handler) {
                def = PerlIO_list_alloc(aTHX);
                PerlIO_list_push(aTHX_ def, handler, &PL_sv_undef);
@@ -1512,7 +1512,7 @@ PerlIO_openn(pTHX_ const char *layers, const char *mode, int fd,
            PerlIOl *l = *f;
            layera = PerlIO_list_alloc(aTHX);
            while (l) {
-               SV *arg = (l->tab->Getarg)
+               SV * const arg = (l->tab->Getarg)
                        ? (*l->tab->Getarg) (aTHX_ &l, NULL, 0)
                        : &PL_sv_undef;
                PerlIO_list_push(aTHX_ layera, l->tab, arg);
@@ -1530,7 +1530,7 @@ PerlIO_openn(pTHX_ const char *layers, const char *mode, int fd,
         */
        n = layera->cur - 1;
        while (n >= 0) {
-           PerlIO_funcs *t = PerlIO_layer_fetch(aTHX_ layera, n, NULL);
+           PerlIO_funcs * const t = PerlIO_layer_fetch(aTHX_ layera, n, NULL);
            if (t && t->Open) {
                tab = t;
                break;
@@ -1709,7 +1709,7 @@ int
 PerlIO_has_base(PerlIO *f)
 {
      if (PerlIOValid(f)) {
-          const PerlIO_funcs *tab = PerlIOBase(f)->tab;
+         const PerlIO_funcs * const tab = PerlIOBase(f)->tab;
 
          if (tab)
               return (tab->Get_base != NULL);
@@ -1725,7 +1725,7 @@ int
 PerlIO_fast_gets(PerlIO *f)
 {
     if (PerlIOValid(f) && (PerlIOBase(f)->flags & PERLIO_F_FASTGETS)) {
-        const PerlIO_funcs *tab = PerlIOBase(f)->tab;
+        const PerlIO_funcs * const tab = PerlIOBase(f)->tab;
 
         if (tab)
              return (tab->Set_ptrcnt != NULL);
@@ -1741,7 +1741,7 @@ int
 PerlIO_has_cntptr(PerlIO *f)
 {
     if (PerlIOValid(f)) {
-       const PerlIO_funcs *tab = PerlIOBase(f)->tab;
+       const PerlIO_funcs * const tab = PerlIOBase(f)->tab;
 
        if (tab)
             return (tab->Get_ptr != NULL && tab->Get_cnt != NULL);
@@ -1757,7 +1757,7 @@ int
 PerlIO_canset_cnt(PerlIO *f)
 {
     if (PerlIOValid(f)) {
-         const PerlIO_funcs *tab = PerlIOBase(f)->tab;
+         const PerlIO_funcs * const tab = PerlIOBase(f)->tab;
 
          if (tab)
               return (tab->Set_ptrcnt != NULL);
@@ -2066,6 +2066,8 @@ PerlIOBase_read(pTHX_ PerlIO *f, void *vbuf, Size_t count)
            return 0;
        }
        while (count > 0) {
+        get_cnt:
+         {
            SSize_t avail = PerlIO_get_cnt(f);
            SSize_t take = 0;
            if (avail > 0)
@@ -2076,11 +2078,14 @@ PerlIOBase_read(pTHX_ PerlIO *f, void *vbuf, Size_t count)
                PerlIO_set_ptrcnt(f, ptr + take, (avail -= take));
                count -= take;
                buf += take;
+               if (avail == 0)         /* set_ptrcnt could have reset avail */
+                   goto get_cnt;
            }
            if (count > 0 && avail <= 0) {
                if (PerlIO_fill(f) != 0)
                    break;
            }
+         }
        }
        return (buf - (STDCHAR *) vbuf);
     }
@@ -2667,7 +2672,7 @@ PerlIOStdio_pushed(pTHX_ PerlIO *f, const char *mode, SV *arg, PerlIO_funcs *tab
 {
     PerlIO *n;
     if (PerlIOValid(f) && PerlIOValid(n = PerlIONext(f))) {
-        PerlIO_funcs *toptab = PerlIOBase(n)->tab;
+       PerlIO_funcs * const toptab = PerlIOBase(n)->tab;
         if (toptab == tab) {
            /* Top is already stdio - pop self (duplicate) and use original */
            PerlIO_pop(aTHX_ f);
@@ -3538,7 +3543,11 @@ PerlIOBuf_open(pTHX_ PerlIO_funcs *self, PerlIO_list_t *layers,
 
 /*
  * This "flush" is akin to sfio's sync in that it handles files in either
- * read or write state
+ * read or write state.  For write state, we put the postponed data through
+ * the next layers.  For read state, we seek() the next layers to the
+ * offset given by current position in the buffer, and discard the buffer
+ * state (XXXX supposed to be for seek()able buffers only, but now it is done
+ * in any case?).  Then the pass the stick further in chain.
  */
 IV
 PerlIOBuf_flush(pTHX_ PerlIO *f)
@@ -3597,6 +3606,10 @@ PerlIOBuf_flush(pTHX_ PerlIO *f)
     return code;
 }
 
+/* This discards the content of the buffer after b->ptr, and rereads
+ * the buffer from the position off in the layer downstream; here off
+ * is at offset corresponding to b->ptr - b->buf.
+ */
 IV
 PerlIOBuf_fill(pTHX_ PerlIO *f)
 {
@@ -3607,7 +3620,7 @@ PerlIOBuf_fill(pTHX_ PerlIO *f)
      * Down-stream flush is defined not to loose read data so is harmless.
      * we would not normally be fill'ing if there was data left in anycase.
      */
-    if (PerlIO_flush(f) != 0)
+    if (PerlIO_flush(f) != 0)  /* XXXX Check that its seek() succeeded?! */
        return -1;
     if (PerlIOBase(f)->flags & PERLIO_F_TTY)
        PerlIOBase_flush_linebuf(aTHX);
@@ -4083,6 +4096,14 @@ PERLIO_FUNCS_DECL(PerlIO_pending) = {
  * crlf - translation On read translate CR,LF to "\n" we do this by
  * overriding ptr/cnt entries to hand back a line at a time and keeping a
  * record of which nl we "lied" about. On write translate "\n" to CR,LF
+ *
+ * c->nl points on the first byte of CR LF pair when it is temporarily
+ * replaced by LF, or to the last CR of the buffer.  In the former case
+ * the caller thinks that the buffer ends at c->nl + 1, in the latter
+ * that it ends at c->nl; these two cases can be distinguished by
+ * *c->nl.  c->nl is set during _getcnt() call, and unset during
+ * _unread() and _flush() calls.
+ * It only matters for read operations.
  */
 
 typedef struct {
@@ -4127,7 +4148,7 @@ SSize_t
 PerlIOCrlf_unread(pTHX_ PerlIO *f, const void *vbuf, Size_t count)
 {
     PerlIOCrlf *c = PerlIOSelf(f, PerlIOCrlf);
-    if (c->nl) {
+    if (c->nl) {       /* XXXX Shouldn't it be done only if b->ptr > c->nl? */
        *(c->nl) = 0xd;
        c->nl = NULL;
     }
@@ -4157,8 +4178,10 @@ PerlIOCrlf_unread(pTHX_ PerlIO *f, const void *vbuf, Size_t count)
                        count--;
                    }
                    else {
-                       buf++;
-                       break;
+                   /* If b->ptr - 1 == b->buf, we are undoing reading 0xa */
+                       *--(b->ptr) = 0xa;      /* Works even if 0xa == '\r' */
+                       unread++;
+                       count--;
                    }
                }
                else {
@@ -4172,6 +4195,7 @@ PerlIOCrlf_unread(pTHX_ PerlIO *f, const void *vbuf, Size_t count)
     }
 }
 
+/* XXXX This code assumes that buffer size >=2, but does not check it... */
 SSize_t
 PerlIOCrlf_get_cnt(pTHX_ PerlIO *f)
 {