m4-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

FYI: erenamesyms and renamesyms builtins [m4--devo--1.0--patch-15]


From: Gary V. Vaughan
Subject: FYI: erenamesyms and renamesyms builtins [m4--devo--1.0--patch-15]
Date: Sun, 8 May 2005 01:39:17 +0100 (BST)
User-agent: mailnotify/0.6

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Applied to HEAD.

  * looking for address@hidden/m4--devo--1.0--patch-14 to compare with
  * comparing to address@hidden/m4--devo--1.0--patch-14
  M  ChangeLog
  M  m4/symtab.c
  M  modules/gnu.c
  M  m4/m4module.h
  M  doc/m4.texinfo
  M  tests/generate.awk
  
  * modified files
  
  Index: Changelog
  from  Gary V. Vaughan  <address@hidden>
  
        * m4/symtab.c (m4_symbol_rename): New function that performs a low
        level symbol rename.
        * m4/m4module.h (m4_symbol_rename): Declare it as part of the API.
        * modules/gnu.c (regsub): Factored out of m4_epatsubst_do...
        (m4_patsubst_do, m4_renamesyms_do): ...wrappers that use
        regsub...
        (erenamesyms, renamesyms): ...builtins that use these to implement
        macro renaming by regular expression.
        * doc/m4.texinfo (Erenamesyms and Renamesyms): Document them.
        * tests/generate.awk: Allow some forbidden `m4_' prefixed symbols
        to stop the new generated tests from choking.
  
  --- orig/doc/m4.texinfo
  +++ mod/doc/m4.texinfo
  @@ -22,8 +22,7 @@
   @ifinfo
   This file documents GNU @code{m4} @value{VERSION}
   
  -Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 1998, 1999, 2000,
  -2001, 2004
  +Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 1998, 1999, 2000, 2001, 
2004, 2005
   Free Software Foundation, Inc.
   
   Permission is granted to copy, distribute and/or modify this document
  @@ -50,8 +49,7 @@
   
   @page
   @vskip 0pt plus 1filll
  -Copyright @copyright{} 1989, 1990, 1991, 1992, 1993, 1994, 1998, 1999,
  -2000, 2001 Free Software Foundation, Inc.
  +Copyright @copyright{} 1989, 1990, 1991, 1992, 1993, 1994, 1998, 1999, 2000, 
2001, 2004, 2005 Free Software Foundation, Inc.
   
   Permission is granted to copy, distribute and/or modify this document
   under the terms of the GNU Free Documentation License, Version 1.1
  @@ -158,6 +156,7 @@
   * Undefine::                    Deleting a macro
   * Defn::                        Renaming macros
   * Pushdef::                     Temporarily redefining macros
  +* Erenamesyms and Renamesyms::  Renaming macros with regular expressions
   
   * Indir::                       Indirect call of macros
   * Builtin::                     Indirect call of builtins
  @@ -996,6 +995,7 @@
   * Undefine::                    Deleting a macro
   * Defn::                        Renaming macros
   * Pushdef::                     Temporarily redefining macros
  +* Erenamesyms and Renamesyms::  Renaming macros with regular expressions
   
   * Indir::                       Indirect call of macros
   * Builtin::                     Indirect call of builtins
  @@ -1379,6 +1379,65 @@
   It is possible to temporarily redefine a builtin with @code{pushdef}
   and @code{defn}.
   
  address@hidden Erenamesyms and Renamesyms
  address@hidden Renaming macros with regular expressions
  +
  address@hidden regular expressions
  address@hidden macros, how to rename
  address@hidden renaming macros
  address@hidden GNU extensions
  address@hidden {Builtin (gnu)} erenamesyms (@var{regexp}, @var{replacement})
  +Global renaming of macros is done by @code{erenamesyms}, which selects
  +all macros with names that match @var{regexp}, and renames each match
  +according to @var{replacement}.
  +
  +A macro that does not have a name that matches @var{regexp} is left
  +with its original name.  If only part of the name matches, any part of
  +the name that is not covered by @var{regexp} is copied to the
  +replacement name.  Whenever a match is found in the name, the search
  +proceeds from the end of the match, so no character in the original
  +name can be substituted twice.  If @var{regexp} matches a string of
  +zero length, the start position for the continued search is
  +incremented to avoid infinite loops.
  +
  +Where a replacement is to be made, @var{replacement} replaces the
  +matched text in the original name, with @address@hidden substituted by
  +the text matched by the @var{n}th parenthesized sub-expression of
  address@hidden, and @samp{\&} being the text matched by the entire
  +regular expression.
  +
  +The builtin macro @code{erenamesyms} is recognized only when given
  +arguments.
  address@hidden deffn
  +
  +Here is an example that performs the same renaming as the
  address@hidden option.  Where @option{--prefix-builtins}
  +only renames M4 builtin macros, @code{erenamesyms} will rename any
  +macros that match when it runs, including text macros.
  +
  address@hidden
  +erenamesyms(`^.*$', `m4_\&')
  address@hidden
  address@hidden example
  +
  +Here is a more realistic example that performs a similar renaming on
  +macros with lowercase names, except that it ignores macros with names
  +that begin with @samp{_}, and avoids creating macros with names that
  +begin with @samp{m4_m4}.
  +
  address@hidden
  +erenamesyms(`^[^_]\w*$', `m4_\&')
  address@hidden
  +m4_erenamesyms(`^m4_m4(\w*)$', `m4_\1')
  address@hidden
  address@hidden example
  +
  address@hidden {Builtin (gnu)} renamesyms (@var{regexp}, @var{replacement})
  +Same as @code{erenamesyms}, but using Basic Regular Expression syntax,
  +see @xref{Eregexp and Regexp}, for more details.
  address@hidden deffn
  +
  +
   @node Indir
   @section Indirect call of macros
   
  @@ -3034,7 +3093,7 @@
   @cindex substitution by regular expression
   @cindex GNU extensions
   @deffn {Builtin (gnu)} epatsubst (@var{string}, @var{regexp}, @w{opt 
@var{replacement})}
  -Global substitution in a string is done by @code{patsubst}, which
  +Global substitution in a string is done by @code{epatsubst}, which
   searches @var{string} for matches of @var{regexp}, and substitutes
   @var{replacement} for each match.  It uses Extended Regular Expressions
   syntax.
  @@ -3054,7 +3113,7 @@
   The @var{replacement} argument can be omitted, in which case the text
   matched by @var{regexp} is deleted.
   
  -The builtin macro @code{patsubst} is recognized only when given
  +The builtin macro @code{epatsubst} is recognized only when given
   arguments.
   @end deffn
   
  
  
  --- orig/m4/m4module.h
  +++ mod/m4/m4module.h
  @@ -1,5 +1,7 @@
   /* GNU m4 -- A simple macro processor
  -   Copyright (C) 1989-1994, 1999, 2000, 2003, 2004 Free Software Foundation, 
Inc.
  +
  +   Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 1999, 2000, 2003,
  +   2004, 2005 Free Software Foundation, Inc.
   
      This program is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published by
  @@ -176,6 +178,9 @@
   extern m4_symbol *m4_symbol_define  (m4_symbol_table*,
                                     const char *, m4_symbol_value *);
   extern void       m4_symbol_popdef  (m4_symbol_table*, const char *);
  +extern m4_symbol *m4_symbol_rename  (m4_symbol_table*, const char *,
  +                                  const char *);
  +
   extern void       m4_symbol_delete  (m4_symbol_table*, const char *);
   
   #define m4_symbol_delete(symtab, name)                       M4_STMT_START { 
\
  
  
  --- orig/m4/symtab.c
  +++ mod/m4/symtab.c
  @@ -1,5 +1,5 @@
   /* GNU m4 -- A simple macro processor
  -   Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 2001
  +   Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 2001, 2005
      Free Software Foundation, Inc.
   
      This program is free software; you can redistribute it and/or modify
  @@ -285,7 +285,6 @@
         }
   }
   
  -
   static void
   symbol_popval (m4_symbol *symbol)
   {
  @@ -310,6 +309,37 @@
       }
   }
   
  +m4_symbol *
  +m4_symbol_rename (m4_symbol_table *symtab, const char *name, const char 
*rename)
  +{
  +  m4_symbol *symbol  = NULL;
  +  m4_symbol **psymbol;
  +
  +  assert (symtab);
  +  assert (name);
  +  assert (rename);
  +
  +  /* Use a low level hash fetch, so we can save the symbol value when
  +     removing the symbol name from the symbol table.  */
  +  psymbol = (m4_symbol **) m4_hash_lookup (symtab->table, name);
  +
  +  if (psymbol)
  +    {
  +      symbol = *psymbol;
  +
  +      /* Remove the old name from the symbol table.  */
  +      free (m4_hash_remove (symtab->table, name));
  +      assert (!m4_hash_lookup (symtab->table, name));
  +
  +      m4_hash_insert (symtab->table, xstrdup (rename), *psymbol);
  +    }
  +  /* else
  +       NAME does not name a symbol in symtab->table!  */
  +
  +  return symbol;
  +}
  +
  +
   /* Callback used by m4_symbol_popdef () to release the memory used
      by values in the arg_signature hash.  */
   static void *
  
  
  --- orig/modules/gnu.c
  +++ mod/modules/gnu.c
  @@ -1,5 +1,6 @@
   /* GNU m4 -- A simple macro processor
  -   Copyright (C) 2000,2004 Free Software Foundation, Inc.
  +
  +  Copyright (C) 2000, 2004, 2005 Free Software Foundation, Inc.
   
      This program is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published by
  @@ -37,6 +38,8 @@
   int errno;
   #endif
   
  +#include <assert.h>
  +
   #ifdef NDEBUG
   #  include "m4private.h"
   #endif
  @@ -78,11 +81,13 @@
        BUILTIN(debugfile,      false,  false,  1,      2  )    \
        BUILTIN(eregexp,        false,  true,   3,      4  )    \
        BUILTIN(epatsubst,      false,  true,   3,      4  )    \
  +     BUILTIN(erenamesyms,    false,  true,   3,      3  )    \
        BUILTIN(esyscmd,        false,  true,   2,      2  )    \
        BUILTIN(format,         false,  true,   2,      -1 )    \
        BUILTIN(indir,          false,  true,   2,      -1 )    \
        BUILTIN(patsubst,       false,  true,   3,      4  )    \
        BUILTIN(regexp,         false,  true,   3,      4  )    \
  +     BUILTIN(renamesyms,     false,  true,   3,      3  )    \
        BUILTIN(symbols,        false,  false,  0,      -1 )    \
        BUILTIN(syncoutput,     false,  true,   2,      2  )    \
   
  @@ -120,10 +125,19 @@
     { 0, 0 },
   };
   
  -static void substitute (m4 *context, m4_obstack *obs, const char *victim,
  -                     const char *repl, struct re_registers *regs);
  -static void m4_patsubst_do (m4 *context, m4_obstack *obs, int argc,
  -                         m4_symbol_value **argv, int syntax);
  +static bool regsub   (m4 *context, m4_obstack *obs, const char *caller,
  +                      const char *victim, int length, const char *regexp,
  +                      struct re_pattern_buffer *buf, const char *replace,
  +                      bool ignore_duplicates);
  +static void substitute       (m4 *context, m4_obstack *obs, const char 
*victim,
  +                      const char *repl, struct re_registers *regs);
  +
  +static void m4_regexp_do     (m4 *context, m4_obstack *obs, int argc,
  +                              m4_symbol_value **argv, int syntax);
  +static void m4_patsubst_do   (m4 *context, m4_obstack *obs, int argc,
  +                              m4_symbol_value **argv, int syntax);
  +static void m4_renamesyms_do (m4 *context, m4_obstack *obs, int argc,
  +                              m4_symbol_value **argv, int syntax);
   
   
   /* The builtin "builtin" allows calls to builtin macros, even if their
  @@ -376,27 +390,39 @@
   {
     const char *victim;                /* first argument */
     const char *regexp;                /* regular expression */
  +  int length;                        /* length of first argument */
   
     struct re_pattern_buffer *buf;/* compiled regular expression */
  -  struct re_registers regs;  /* for subexpression matches */
  -  int matchpos;                      /* start position of match */
  -  int offset;                        /* current match offset */
  -  int length;                        /* length of first argument */
   
  -  regexp = M4ARG (2);
     victim = M4ARG (1);
     length = strlen (victim);
  +  regexp = M4ARG (2);
   
     buf = m4_regexp_compile (context, M4ARG(0), regexp, syntax);
     if (!buf)
       return;
   
  -  offset = 0;
  -  matchpos = 0;
  +  regsub (context, obs, M4ARG(0), victim, length,
  +       regexp, buf, M4ARG(3), false);
  +}
  +
  +
  +static bool
  +regsub (m4 *context, m4_obstack *obs, const char *caller,
  +     const char *victim, int length, const char *regexp,
  +     struct re_pattern_buffer *buf, const char *replace,
  +     bool ignore_duplicates)
  +{
  +  struct re_registers regs;  /* for subexpression matches */
  +
  +  int matchpos       = 0;            /* start position of match */
  +  int offset = 0;            /* current match offset */
  +
     while (offset < length)
       {
         matchpos = re_search (buf, victim, length,
                            offset, length - offset, &regs);
  +
         if (matchpos < 0)
        {
   
  @@ -407,8 +433,8 @@
          if (matchpos == -2)
            M4ERROR ((m4_get_warning_status_opt (context), 0,
                      _("%s: error matching regular expression `%s'"),
  -                   M4ARG (0), regexp));
  -       else if (offset < length)
  +                   caller, regexp));
  +       else if (!ignore_duplicates && (offset < length))
            obstack_grow (obs, victim + offset, length - offset);
          break;
        }
  @@ -420,7 +446,7 @@
   
         /* Handle the part of the string that was covered by the match.  */
   
  -      substitute (context, obs, victim, M4ARG (3), &regs);
  +      substitute (context, obs, victim, replace, &regs);
   
         /* Update the offset to the end of the match.  If the regexp
         matched a null string, advance offset one more, to avoid
  @@ -430,11 +456,14 @@
         if (regs.start[0] == regs.end[0])
        obstack_1grow (obs, victim[offset++]);
       }
  -  obstack_1grow (obs, '\0');
   
  -  return;
  +  if (!ignore_duplicates || (matchpos >= 0))
  +    obstack_1grow (obs, '\0');
  +
  +  return (matchpos >= 0);
   }
   
  +
   /**
    * patsubst(STRING, REGEXP, [REPLACEMENT])
    **/
  @@ -478,6 +507,8 @@
        }
         obstack_free (&data_obs, NULL);
       }
  +  else
  +    assert (!"Unable to import from m4 module");
   }
   
   
  @@ -537,6 +568,74 @@
       }
   }
   
  +
  +
  +/**
  + * renamesyms(REGEXP, REPLACEMENT)
  + **/
  +M4BUILTIN_HANDLER (renamesyms)
  +{
  +  m4_renamesyms_do (context, obs, argc, argv, RE_SYNTAX_BRE);
  +}
  +
  +/**
  + * erenamesyms(REGEXP, REPLACEMENT)
  + **/
  +M4BUILTIN_HANDLER (erenamesyms)
  +{
  +  m4_renamesyms_do (context, obs, argc, argv, RE_SYNTAX_ERE);
  +}
  +
  +
  +
  +static void
  +m4_renamesyms_do (m4 *context, m4_obstack *obs, int argc,
  +               m4_symbol_value **argv, int syntax)
  +{
  +  const char *regexp;                /* regular expression string */
  +  const char *replace;               /* replacement expression string */
  +
  +  struct re_pattern_buffer *buf;/* compiled regular expression */
  +
  +  m4_dump_symbol_data        data;
  +  m4_obstack         data_obs;
  +  m4_obstack         rename_obs;
  +
  +  M4_MODULE_IMPORT (m4, m4_dump_symbols);
  +
  +  assert (m4_dump_symbols);
  +
  +  regexp = M4ARG(1);
  +  replace = M4ARG(2);
  +
  +  buf = m4_regexp_compile (context, M4ARG(0), regexp, syntax);
  +  if (!buf)
  +    return;
  +
  +  obstack_init (&rename_obs);
  +  obstack_init (&data_obs);
  +  data.obs = &data_obs;
  +
  +  m4_dump_symbols (context, &data, 1, argv, false);
  +
  +  for (; data.size > 0; --data.size, data.base++)
  +    {
  +      const char *   name    = data.base[0];
  +      int            length  = strlen (name);
  +
  +      if (regsub (context, &rename_obs, M4ARG(0), name, length,
  +               regexp, buf, replace, true))
  +     {
  +       const char *renamed = obstack_finish (&rename_obs);
  +
  +       m4_symbol_rename (M4SYMTAB, name, renamed);
  +     }
  +    }
  +
  +  obstack_free (&data_obs, NULL);
  +  obstack_free (&rename_obs, NULL);
  +}
  +
   /* Frontend for printf like formatting.  The function format () lives in
      the file format.c.  */
   
  
  
  --- orig/tests/generate.awk
  +++ mod/tests/generate.awk
  @@ -31,6 +31,9 @@
     print ;
     print "AT_BANNER([Documentation examples.])";
     print ;
  +  # stop spurious warnings in the erenamesyms checks
  +  print "m4_pattern_allow([^m4_(m4|erenamesyms|)$])"
  +  print ;
   }
   
   /address@hidden / {
  
  
  
- -- 
Gary V. Vaughan      ())_.  address@hidden,gnu.org}
Research Scientist   ( '/   http://tkd.kicks-ass.net
GNU Hacker           / )=   http://www.gnu.org/software/libtool
Technical Author   `(_~)_   http://sources.redhat.com/autobook
_________________________________________________________
This patch notification generated by tlaapply version 0.9
http://tkd.kicks-ass.net/arch/address@hidden/cvs-utils--tla--1.0
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (Darwin)

iD8DBQFCfV+0FRMICSmD1gYRAuPvAKC3swldQ7cIXIdcMqVFq1O0vegROwCgnX3/
DuEL0baVPfiNs4yURYc8HDI=
=jGAN
-----END PGP SIGNATURE-----




reply via email to

[Prev in Thread] Current Thread [Next in Thread]