[Templates-cvs] cvs commit: Template2/xs Stash.xs

cvs@template-toolkit.org cvs@template-toolkit.org


cvs         06/01/30 13:33:25

  Modified:    xs       Stash.xs
  Log:
  * ported to the XS Stash Dave Howorth's fix to make stash stricter
    about what it considers to be a missing object method.
  
  Revision  Changes    Path
  1.18      +30 -9     Template2/xs/Stash.xs
  
  Index: Stash.xs
  ===================================================================
  RCS file: /template-toolkit/Template2/xs/Stash.xs,v
  retrieving revision 1.17
  retrieving revision 1.18
  diff -u -r1.17 -r1.18
  --- Stash.xs	2006/01/29 11:36:10	1.17
  +++ Stash.xs	2006/01/30 13:33:25	1.18
  @@ -26,7 +26,7 @@
   *
   *---------------------------------------------------------------------
   *
  -* $Id: Stash.xs,v 1.17 2006/01/29 11:36:10 abw Exp $
  +* $Id: Stash.xs,v 1.18 2006/01/30 13:33:25 abw Exp $
   *
   *=====================================================================*/
   
  @@ -89,8 +89,12 @@
   static SV*      scalar_dot_defined(pTHX_ SV*, AV*);
   static SV*      scalar_dot_length(pTHX_ SV*, AV*);
   
  -static char rcsid[] = "$Id: Stash.xs,v 1.17 2006/01/29 11:36:10 abw Exp $";
  +static char rcsid[]  = "$Id: Stash.xs,v 1.18 2006/01/30 13:33:25 abw Exp $";
   
  +#define THROW_SIZE 64
  +static char throw_str[THROW_SIZE+1];
  +static char throw_fmt[] = "Can't locate object method \"%s\"";
  +
   /* dispatch table for XS versions of special "virtual methods",
    * names must be in alphabetical order 		
    */
  @@ -300,6 +304,7 @@
               SV **svp;
               HV *stash = SvSTASH((SV *) SvRV(root));
               GV *gv;
  +            char *error_string;
               result = NULL;
               
               if ((gv = gv_fetchmethod_autoload(stash, item, 1))) {
  @@ -318,15 +323,31 @@
                       (void) POPs;		/* remove undef from stack */
                       PUTBACK;
                       result = NULL;
  -                    
  -                    /* temporary hack - required to propogate errors thrown
  -                       by views; if $@ is a ref (e.g. Template::Exception)
  -                       object then we assume it's a real error that needs
  -                       real throwing */
                       
  -                    if (SvROK(ERRSV) || !strstr(SvPV(ERRSV, PL_na), 
  -                                                "Can't locate object method")) {
  +                    /* if we get an exception object throw ($@ is a
  +                     * ref) or a error other than "Can't locate object
  +                     * method "blah"" then it's a real error that need
  +                     * to be re-thrown.
  +                     */
  +
  +                            
  +                    if (SvROK(ERRSV)) {
                           die_object(aTHX_ ERRSV);
  +                    }
  +                    else {
  +                        /* We use throw_str to construct the error
  +                         * message that indicates a missing method.
  +                         * We use snprintf() to avoid overflowing 
  +                         * throw_str, and always ensure the last character
  +                         * is NULL (if the item name is too long to fit
  +                         * into throw_str then snprintf() doesn't add the 
  +                         * terminating NULL
  +                         */
  +                        snprintf( throw_str, THROW_SIZE, throw_fmt, item);
  +                        throw_str[THROW_SIZE] = '\0';
  +
  +                        if (! strstr( SvPV(ERRSV, PL_na), throw_str)) 
  +                            die_object(aTHX_ ERRSV);
                       }
                   } else {
                       result = fold_results(aTHX_ n);