RPM Package Manager, CVS Repository
  http://rpm5.org/cvs/
  ____________________________________________________________________________

  Server: rpm5.org                         Name:   Jeff Johnson
  Root:   /v/rpm/cvs                       Email:  j...@rpm5.org
  Module: rpm                              Date:   21-Sep-2014 08:49:40
  Branch: rpm-5_4                          Handle: 2014092106494000

  Modified files:           (Branch: rpm-5_4)
    rpm/rpmio               pcrs.c pcrs.h pcrsed.c

  Log:
    - WIP.

  Summary:
    Revision    Changes     Path
    1.1.2.2     +501 -714   rpm/rpmio/pcrs.c
    1.1.2.2     +47 -131    rpm/rpmio/pcrs.h
    1.1.2.2     +48 -84     rpm/rpmio/pcrsed.c
  ____________________________________________________________________________

  patch -p0 <<'@@ .'
  Index: rpm/rpmio/pcrs.c
  ============================================================================
  $ cvs diff -u -r1.1.2.1 -r1.1.2.2 pcrs.c
  --- rpm/rpmio/pcrs.c  20 Sep 2014 17:52:06 -0000      1.1.2.1
  +++ rpm/rpmio/pcrs.c  21 Sep 2014 06:49:40 -0000      1.1.2.2
  @@ -1,5 +1,3 @@
  -const char pcrs_rcs[] = "$Id: pcrs.c,v 1.19.2.3 2003/12/04 12:32:45 oes Exp 
$";
  - 
   /*********************************************************************
    *
    * File        :  $Source: /cvsroot/ijbswa/current/Attic/pcrs.c,v $
  @@ -31,129 +29,19 @@
    *                or write to the Free Software Foundation, Inc., 59
    *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    *
  - * Revisions   :
  - *    $Log: pcrs.c,v $
  - *    Revision 1.19.2.3  2003/12/04 12:32:45  oes
  - *    Append a trailing nullbyte to result to facilitate string processing
  - *
  - *    Revision 1.19.2.2  2002/10/08 16:22:28  oes
  - *    Bugfix: Need to check validity of backreferences explicitly,
  - *    because when max_matches are reached and matches is expanded,
  - *    realloc() does not zero the memory. Fixes Bug # 606227
  - *
  - *    Revision 1.19.2.1  2002/08/10 11:23:40  oes
  - *    [Irrelevant for stand-alone pcrs]
  - *
  - *    Revision 1.19  2002/03/08 14:47:48  oes
  - *    Cosmetics
  - *
  - *    Revision 1.18  2002/03/08 14:17:14  oes
  - *    Fixing -Wconversion warnings
  - *
  - *    Revision 1.17  2002/03/08 13:45:48  oes
  - *    Hiding internal functions
  - *
  - *    Revision 1.16  2001/11/30 21:32:14  jongfoster
  - *    Fixing signed/unsigned comparison (Andreas please check this!)
  - *    One tab->space
  - *
  - *    Revision 1.15  2001/09/20 16:11:06  steudten
  - *
  - *    Add casting for some string functions.
  - *
  - *    Revision 1.14  2001/09/09 21:41:57  oes
  - *    Fixing yet another silly bug
  - *
  - *    Revision 1.13  2001/09/06 14:05:59  oes
  - *    Fixed silly bug
  - *
  - *    Revision 1.12  2001/08/18 11:35:00  oes
  - *    - Introduced pcrs_strerror()
  - *    - made some NULL arguments non-fatal
  - *    - added support for \n \r \e \b \t \f \a \0 in substitute
  - *    - made quoting adhere to standard rules
  - *    - added warning for bad backrefs
  - *    - added pcrs_execute_list()
  - *    - fixed comments
  - *    - bugfix & cosmetics
  - *
  - *    Revision 1.11  2001/08/15 15:32:03  oes
  - *     - Added support for Perl's special variables $+, $' and $`
  - *     - Improved the substitute parser
  - *     - Replaced the hard limit for the maximum number of matches
  - *       by dynamic reallocation
  - *
  - *    Revision 1.10  2001/08/05 13:13:11  jongfoster
  - *    Making parameters "const" where possible.
  - *
  - *    Revision 1.9  2001/07/18 17:27:00  oes
  - *    Changed interface; Cosmetics
  - *
  - *    Revision 1.8  2001/06/29 21:45:41  oes
  - *    Indentation, CRLF->LF, Tab-> Space
  - *
  - *    Revision 1.7  2001/06/29 13:33:04  oes
  - *    - Cleaned up, renamed and reordered functions,
  - *      improved comments
  - *    - Removed my_strsep
  - *    - Replaced globalflag with a general flags int
  - *      that holds PCRS_GLOBAL, PCRS_SUCCESS, and PCRS_TRIVIAL
  - *    - Introduced trivial option that will prevent pcrs
  - *      from honouring backreferences in the substitute,
  - *      which is useful for large substitutes that are
  - *      red in from somewhere and saves the pain of escaping
  - *      the backrefs
  - *    - Introduced convenience function pcrs_free_joblist()
  - *    - Split pcrs_make_job() into pcrs_compile(), which still
  - *      takes a complete s/// comand as argument and parses it,
  - *      and a new function pcrs_make_job, which takes the
  - *      three separate components. This should make for a
  - *      much friendlier frontend.
  - *    - Removed create_pcrs_job() which was useless
  - *    - Fixed a bug in pcrs_execute
  - *    - Success flag is now handled by pcrs instead of user
  - *
  - *    Revision 1.6  2001/06/03 19:12:45  oes
  - *    added FIXME
  - *
  - *    Revision 1.5  2001/05/29 09:50:24  jongfoster
  - *    (Fixed one int -> size_t)
  - *
  - *    Revision 1.4  2001/05/25 14:12:40  oes
  - *    Fixed bug: Empty substitutes now detected
  - *
  - *    Revision 1.3  2001/05/25 11:03:55  oes
  - *    Added sanity check for NULL jobs to pcrs_exec_substitution
  - *
  - *    Revision 1.2  2001/05/22 18:46:04  oes
  - *
  - *      Added support for PCRE_UNGREEDY behaviour to pcrs,
  - *      which is selected by the (nonstandard and therefore
  - *      capital) letter 'U' in the option string.
  - *      It causes the quantifiers to be ungreedy by default.
  - *      Appending a ? turns back to greedy (!).
  - *
  - *    Revision 1.1.1.1  2001/05/15 13:59:02  oes
  - *    Initial import of version 2.9.3 source tree
  - *
  - *
    *********************************************************************/
  -
   
  -#include <string.h>
  -#include <ctype.h>
  +#include "system.h"
   
   #include "pcrs.h"
   
  -const char pcrs_h_rcs[] = PCRS_H_VERSION;
  +#include "debug.h"
   
  -/*
  - * Internal prototypes
  - */
  -
  -static int              pcrs_parse_perl_options(const char *optstring, int 
*flags);
  -static pcrs_substitute *pcrs_compile_replacement(const char *replacement, 
int trivialflag,
  -                        int capturecount, int *errptr);
  +#define PCRS_H_VERSION "$Id: pcrs.h,v 1.11 2002/03/08 14:18:23 oes Exp $"
  +static const char pcrs_h_rcs[] = PCRS_H_VERSION;
  +
  +#define FALSE 0
  +#define TRUE 1
   
   /*********************************************************************
    *
  @@ -169,40 +57,49 @@
    *********************************************************************/
   const char *pcrs_strerror(const int error)
   {
  -   if (error < 0)
  -   {
  -      switch (error)
  -      {
  -         /* Passed-through PCRE error: */
  -         case PCRE_ERROR_NOMEMORY:     return "(pcre:) No memory";
  -
  -         /* Shouldn't happen unless PCRE or PCRS bug, or user messed with 
compiled job: */
  -         case PCRE_ERROR_NULL:         return "(pcre:) NULL code or subject 
or ovector";
  -         case PCRE_ERROR_BADOPTION:    return "(pcre:) Unrecognized option 
bit";
  -         case PCRE_ERROR_BADMAGIC:     return "(pcre:) Bad magic number in 
code";
  -         case PCRE_ERROR_UNKNOWN_NODE: return "(pcre:) Bad node in pattern";
  -
  -         /* Can't happen / not passed: */
  -         case PCRE_ERROR_NOSUBSTRING:  return "(pcre:) Fire in power 
supply"; 
  -         case PCRE_ERROR_NOMATCH:      return "(pcre:) Water in power 
supply";
  -
  -         /* PCRS errors: */
  -         case PCRS_ERR_NOMEM:          return "(pcrs:) No memory";
  -         case PCRS_ERR_CMDSYNTAX:      return "(pcrs:) Syntax error while 
parsing command";
  -         case PCRS_ERR_STUDY:          return "(pcrs:) PCRE error while 
studying the pattern";
  -         case PCRS_ERR_BADJOB:         return "(pcrs:) Bad job - NULL job, 
pattern or substitute";
  -         case PCRS_WARN_BADREF:        return "(pcrs:) Backreference out of 
range";
  -
  -         /* What's that? */
  -         default:  return "Unknown error";
  -      }
  -   }
  -   /* error >= 0: No error */
  -   return "(pcrs:) Everything's just fine. Thanks for asking.";
  +    if (error < 0)
  +     switch (error) {
  +         /* Passed-through PCRE error: */
  +     case PCRE_ERROR_NOMEMORY:
  +         return "(pcre:) No memory";
  +
  +         /* Shouldn't happen unless PCRE or PCRS bug, or user messed with 
compiled job: */
  +     case PCRE_ERROR_NULL:
  +         return "(pcre:) NULL code or subject or ovector";
  +     case PCRE_ERROR_BADOPTION:
  +         return "(pcre:) Unrecognized option bit";
  +     case PCRE_ERROR_BADMAGIC:
  +         return "(pcre:) Bad magic number in code";
  +     case PCRE_ERROR_UNKNOWN_NODE:
  +         return "(pcre:) Bad node in pattern";
  +
  +         /* Can't happen / not passed: */
  +     case PCRE_ERROR_NOSUBSTRING:
  +         return "(pcre:) Fire in power supply";
  +     case PCRE_ERROR_NOMATCH:
  +         return "(pcre:) Water in power supply";
  +
  +         /* PCRS errors: */
  +     case PCRS_ERR_NOMEM:
  +         return "(pcrs:) No memory";
  +     case PCRS_ERR_CMDSYNTAX:
  +         return "(pcrs:) Syntax error while parsing command";
  +     case PCRS_ERR_STUDY:
  +         return "(pcrs:) PCRE error while studying the pattern";
  +     case PCRS_ERR_BADJOB:
  +         return "(pcrs:) Bad job - NULL job, pattern or substitute";
  +     case PCRS_WARN_BADREF:
  +         return "(pcrs:) Backreference out of range";
  +
  +         /* What's that? */
  +     default:
  +         return "Unknown error";
  +     }
  +    /* error >= 0: No error */
  +    return "(pcrs:) Everything's just fine. Thanks for asking.";
   
   }
   
  -
   /*********************************************************************
    *
    * Function    :  pcrs_parse_perl_options
  @@ -224,32 +121,44 @@
    *********************************************************************/
   static int pcrs_parse_perl_options(const char *optstring, int *flags)
   {
  -   size_t i;
  -   int rc = 0;
  -   *flags = 0;
  -
  -   if (NULL == optstring) return 0;
  -
  -   for (i = 0; i < strlen(optstring); i++)
  -   {
  -      switch(optstring[i])
  -      {
  -         case 'e': break; /* ToDo ;-) */
  -         case 'g': *flags |= PCRS_GLOBAL; break;
  -         case 'i': rc |= PCRE_CASELESS; break;
  -         case 'm': rc |= PCRE_MULTILINE; break;
  -         case 'o': break;
  -         case 's': rc |= PCRE_DOTALL; break;
  -         case 'x': rc |= PCRE_EXTENDED; break;
  -         case 'U': rc |= PCRE_UNGREEDY; break;
  -         case 'T': *flags |= PCRS_TRIVIAL; break;
  -         default: break;
  -      }
  -   }
  -   return rc;
  +    size_t i;
  +    int rc = 0;
   
  -}
  +    *flags = 0;
   
  +    if (optstring)
  +     for (i = 0; i < strlen(optstring); i++)
  +         switch (optstring[i]) {
  +         case 'e':
  +             break;          /* ToDo ;-) */
  +         case 'g':
  +             *flags |= PCRS_GLOBAL;
  +             break;
  +         case 'i':
  +             rc |= PCRE_CASELESS;
  +             break;
  +         case 'm':
  +             rc |= PCRE_MULTILINE;
  +             break;
  +         case 'o':
  +             break;
  +         case 's':
  +             rc |= PCRE_DOTALL;
  +             break;
  +         case 'x':
  +             rc |= PCRE_EXTENDED;
  +             break;
  +         case 'U':
  +             rc |= PCRE_UNGREEDY;
  +             break;
  +         case 'T':
  +             *flags |= PCRS_TRIVIAL;
  +             break;
  +         default:
  +             break;
  +         }
  +    return rc;
  +}
   
   /*********************************************************************
    *
  @@ -275,183 +184,126 @@
    *                the reason.
    *
    *********************************************************************/
  -static pcrs_substitute *pcrs_compile_replacement(const char *replacement, 
int trivialflag, int capturecount, int *errptr)
  +static pcrs_substitute *pcrs_compile_replacement(const char *replacement,
  +             int trivialflag, int capturecount, int *errptr)
   {
  -   int i, k, l, quoted;
  -   size_t length;
  -   char *text;
  -   pcrs_substitute *r;
  -
  -   i = k = l = quoted = 0;
  -
  -   /*
  -    * Sanity check
  -    */
  -   if (NULL == replacement)
  -   {
  -      replacement = "";
  -   }
  -
  -   /*
  -    * Get memory or fail
  -    */
  -   if (NULL == (r = (pcrs_substitute *)malloc(sizeof(pcrs_substitute))))
  -   {
  -      *errptr = PCRS_ERR_NOMEM;
  -      return NULL;
  -   }
  -   memset(r, '\0', sizeof(pcrs_substitute));
  -
  -   length = strlen(replacement);
  -
  -   if (NULL == (text = (char *)malloc(length + 1)))
  -   {
  -      free(r);
  -      *errptr = PCRS_ERR_NOMEM;
  -      return NULL;
  -   }
  -   memset(text, '\0', length + 1);
  -   
  -
  -   /*
  -    * In trivial mode, just copy the substitute text
  -    */
  -   if (trivialflag)
  -   {
  -      text = strncpy(text, replacement, length + 1);
  -      k = length;
  -   }
  -
  -   /*
  -    * Else, parse, cut out and record all backreferences
  -    */
  -   else
  -   {
  -      while (i < (int)length)
  -      {
  -         /* Quoting */
  -         if (replacement[i] == '\\')
  -         {
  -            if (quoted)
  -            {
  -               text[k++] = replacement[i++];
  -               quoted = 0;
  -            }
  -            else
  -            {
  -               if (replacement[i+1] && strchr("tnrfae0", replacement[i+1]))
  -               {
  -                  switch (replacement[++i])
  -                  {
  -                  case 't':
  -                     text[k++] = '\t';
  -                     break;
  -                  case 'n':
  -                     text[k++] = '\n';
  -                     break;
  -                  case 'r':
  -                     text[k++] = '\r';
  -                     break;
  -                  case 'f':
  -                     text[k++] = '\f';
  -                     break;
  -                  case 'a':
  -                     text[k++] = 7;
  -                     break;
  -                  case 'e':
  -                     text[k++] = 27;
  -                     break;
  -                  case '0':
  -                     text[k++] = '\0';
  -                     break;
  -                  }
  -                  i++;
  -               }
  -               else
  -               {
  -                  quoted = 1;
  -                  i++;
  -               }
  -            }
  -            continue;
  -         }
  -
  -         /* Backreferences */
  -         if (replacement[i] == '$' && !quoted && i < (int)(length - 1))
  -         {
  -            char *symbol, symbols[] = "'`+&";
  -            r->block_length[l] = k - r->block_offset[l];
  -
  -            /* Numerical backreferences */
  -            if (isdigit((int)replacement[i + 1]))
  -            {
  -               while (i < (int)length && isdigit((int)replacement[++i]))
  -               {
  -                  r->backref[l] = r->backref[l] * 10 + replacement[i] - 48;
  -               }
  -               if (r->backref[l] > capturecount)
  -               {
  -                  *errptr = PCRS_WARN_BADREF;
  -               }
  -            }
  -
  -            /* Symbolic backreferences: */
  -            else if (NULL != (symbol = strchr(symbols, replacement[i + 1])))
  -            {
  -               
  -               if (symbol - symbols == 2) /* $+ */
  -               {
  -                  r->backref[l] = capturecount;
  -               }
  -               else if (symbol - symbols == 3) /* $& */
  -               {
  -                  r->backref[l] = 0;
  -               }
  -               else /* $' or $` */
  -               {
  -                  r->backref[l] = PCRS_MAX_SUBMATCHES + 1 - (symbol - 
symbols);
  -               }
  -               i += 2;
  -            }
  -
  -            /* Invalid backref -> plain '$' */
  -            else
  -            {
  -               goto plainchar;
  -            }
  -
  -            /* Valid and in range? -> record */
  -            if (r->backref[l] < PCRS_MAX_SUBMATCHES + 2)
  -            {
  -               r->backref_count[r->backref[l]] += 1;
  -               r->block_offset[++l] = k;
  -            }
  -            else
  -            {
  -               *errptr = PCRS_WARN_BADREF;
  -            }   
  -            continue;
  -         }
  -         
  -plainchar:
  -         /* Plain chars are copied */
  -         text[k++] = replacement[i++];
  -         quoted = 0;
  -      }
  -   } /* -END- if (!trivialflag) */
  -
  -   /*
  -    * Finish & return
  -    */
  -   r->text = text;
  -   r->backrefs = l;
  -   r->block_length[l] = k - r->block_offset[l];
  -
  -   return r;
  +    int i = 0;
  +    int k = 0;
  +    int l = 0;
  +    int quoted = 0;
  +    size_t length;
  +    char *text;
  +    pcrs_substitute *r;
  +
  +    /* Sanity check */
  +    if (replacement == NULL)
  +     replacement = "";
  +
  +    /* Get memory or fail */
  +    r = (pcrs_substitute *) xcalloc(1, sizeof(pcrs_substitute));
  +
  +    length = strlen(replacement);
  +
  +    text = (char *) xcalloc(1, length + 1);
  +
  +    if (trivialflag) {       /* In trivial mode, just copy the substitute 
text */
  +     text = strncpy(text, replacement, length + 1);
  +     k = length;
  +    } else {         /* Else, parse, cut out and record all backreferences */
  +     while (i < (int) length) {
  +         /* Quoting */
  +         if (replacement[i] == '\\') {
  +             if (quoted) {
  +                 text[k++] = replacement[i++];
  +                 quoted = 0;
  +             } else {
  +                 if (replacement[i+1] && strchr("tnrfae0", replacement[i+1]))
  +                 {
  +                     switch (replacement[++i]) {
  +                     case 't':
  +                         text[k++] = '\t';
  +                         break;
  +                     case 'n':
  +                         text[k++] = '\n';
  +                         break;
  +                     case 'r':
  +                         text[k++] = '\r';
  +                         break;
  +                     case 'f':
  +                         text[k++] = '\f';
  +                         break;
  +                     case 'a':
  +                         text[k++] = 7;
  +                         break;
  +                     case 'e':
  +                         text[k++] = 27;
  +                         break;
  +                     case '0':
  +                         text[k++] = '\0';
  +                         break;
  +                     }
  +                 } else
  +                     quoted = 1;
  +                 i++;
  +             }
  +             continue;
  +         }
  +
  +         /* Backreferences */
  +         if (replacement[i] == '$' && !quoted && i < (int)(length - 1)) {
  +             static char symbols[] = "'`+&";
  +             char *symbol;
  +             r->block_length[l] = k - r->block_offset[l];
  +
  +             /* Numerical backreferences */
  +             if (isdigit((int) replacement[i + 1])) {
  +                 while (i < (int) length && isdigit((int) replacement[++i]))
  +                     r->backref[l] = r->backref[l]*10 + replacement[i] - 48;
  +                 if (r->backref[l] > capturecount)
  +                     *errptr = PCRS_WARN_BADREF;
  +             } else /* Symbolic backreferences: */
  +             if ((symbol = strchr(symbols, replacement[i + 1])) != NULL) {
  +
  +                 switch (symbol - symbols) {
  +                 case 2:
  +                     r->backref[l] = capturecount;
  +                     break;  /* $+ */
  +                 case 3:
  +                     r->backref[l] = 0;
  +                     break;  /* $& */
  +                 default:    /* $' or $` */
  +                     r->backref[l] =
  +                         PCRS_MAX_SUBMATCHES + 1 - (symbol - symbols);
  +                     break;
  +                 }
  +                 i += 2;
  +             } else          /* Invalid backref -> plain '$' */
  +                 goto plainchar;
  +
  +             /* Valid and in range? -> record */
  +             if (r->backref[l] < PCRS_MAX_SUBMATCHES + 2) {
  +                 r->backref_count[r->backref[l]] += 1;
  +                 r->block_offset[++l] = k;
  +             } else
  +                 *errptr = PCRS_WARN_BADREF;
  +             continue;
  +         }
  +
  +       plainchar:
  +         /* Plain chars are copied */
  +         text[k++] = replacement[i++];
  +         quoted = 0;
  +     }
  +    }                                /* -END- if (!trivialflag) */
  +
  +    /* Finish & return */
  +    r->text = text;
  +    r->backrefs = l;
  +    r->block_length[l] = k - r->block_offset[l];
   
  +    return r;
   }
   
  -
   /*********************************************************************
    *
    * Function    :  pcrs_free_job
  @@ -466,31 +318,26 @@
    *                NULL otherwise. 
    *
    *********************************************************************/
  -pcrs_job *pcrs_free_job(pcrs_job *job)
  +pcrs_job *pcrs_free_job(pcrs_job * job)
   {
  -   pcrs_job *next;
  -
  -   if (job == NULL)
  -   {
  -      return NULL;
  -   }
  -   else
  -   {
  -      next = job->next;
  -      if (job->pattern != NULL) free(job->pattern);
  -      if (job->hints != NULL) free(job->hints);
  -      if (job->substitute != NULL)
  -      {
  -         if (job->substitute->text != NULL) free(job->substitute->text);
  -         free(job->substitute);
  -      }
  -      free(job);
  -   }
  -   return next;
  +    pcrs_job *next;
   
  +    if (job == NULL)
  +     return NULL;
  +    next = job->next;
  +    if (job->pattern != NULL)
  +     free(job->pattern);
  +    if (job->hints != NULL)
  +     free(job->hints);
  +    if (job->substitute != NULL) {
  +     if (job->substitute->text != NULL)
  +         free(job->substitute->text);
  +     free(job->substitute);
  +    }
  +    free(job);
  +    return next;
   }
   
  -
   /*********************************************************************
    *
    * Function    :  pcrs_free_joblist
  @@ -505,15 +352,15 @@
    * Returns     :  N/A
    *
    *********************************************************************/
  -void pcrs_free_joblist(pcrs_job *joblist)
  +void pcrs_free_joblist(pcrs_job * joblist)
   {
  -   while ( NULL != (joblist = pcrs_free_job(joblist)) ) {};
  +    while (NULL != (joblist = pcrs_free_job(joblist)))
  +     { };
   
  -   return;
  +    return;
   
   }
   
  -
   /*********************************************************************
    *
    * Function    :  pcrs_compile_command
  @@ -535,74 +382,56 @@
    *********************************************************************/
   pcrs_job *pcrs_compile_command(const char *command, int *errptr)
   {
  -   int i, k, l, quoted = FALSE;
  -   size_t limit;
  -   char delimiter;
  -   char *tokens[4];   
  -   pcrs_job *newjob;
  -   
  -   i = k = l = 0;
  -   
  -   /*
  -    * Tokenize the perl command
  -    */
  -   limit = strlen(command);
  -   if (limit < 4)
  -   {
  -      *errptr = PCRS_ERR_CMDSYNTAX;
  -      return NULL;
  -   }
  -   else
  -   {
  -      delimiter = command[1];
  -   }
  -
  -   tokens[l] = (char *) malloc(limit + 1);
  -
  -   for (i = 0; i <= (int)limit; i++)
  -   {
  -      
  -      if (command[i] == delimiter && !quoted)
  -      {
  -         if (l == 3)
  -         {
  -            l = -1;
  -            break;
  -         }
  -         tokens[0][k++] = '\0';
  -         tokens[++l] = tokens[0] + k;
  -         continue;
  -      }
  -      
  -      else if (command[i] == '\\' && !quoted)
  -      {
  -         quoted = TRUE;
  -         if (command[i+1] == delimiter) continue;
  -      }
  -      else
  -      {
  -         quoted = FALSE;
  -      }
  -      tokens[0][k++] = command[i];
  -   }
  -
  -   /*
  -    * Syntax error ?
  -    */
  -   if (l != 3)
  -   {
  -      *errptr = PCRS_ERR_CMDSYNTAX;
  -      free(tokens[0]);
  -      return NULL;
  -   }
  -   
  -   newjob = pcrs_compile(tokens[1], tokens[2], tokens[3], errptr);
  -   free(tokens[0]);
  -   return newjob;
  -   
  +    size_t limit;
  +    char delimiter;
  +    char *tokens[4] = { NULL, NULL, NULL, NULL };
  +    pcrs_job *newjob = NULL; /* assume error */
  +    int quoted = FALSE;
  +    int i = 0;
  +    int k = 0;
  +    int l = 0;
  +
  +    /* Tokenize the perl command */
  +    limit = strlen(command);
  +    if (limit < sizeof("s///") - 1)
  +     goto exit;
  +    delimiter = command[1];
  +
  +    tokens[0] = (char *) xmalloc(limit + 1);
  +
  +    for (i = 0; i <= (int) limit; i++) {
  +
  +     if (command[i] == delimiter && !quoted) {
  +         if (l == 3) {
  +             l = -1;
  +             break;
  +         }
  +         tokens[0][k++] = '\0';
  +         tokens[++l] = tokens[0] + k;
  +         continue;
  +     } else if (command[i] == '\\' && !quoted) {
  +         quoted = TRUE;
  +         if (command[i + 1] == delimiter)
  +             continue;
  +     } else
  +         quoted = FALSE;
  +     tokens[0][k++] = command[i];
  +    }
  +
  +    /* Syntax error ? */
  +    if (l != 3)
  +     goto exit;
  +
  +    newjob = pcrs_compile(tokens[1], tokens[2], tokens[3], errptr);
  +
  +exit:
  +    if (tokens[0])
  +     free(tokens[0]);
  +    if (newjob == NULL)
  +     *errptr = PCRS_ERR_CMDSYNTAX;
  +    return newjob;
   }
   
  -
   /*********************************************************************
    *
    * Function    :  pcrs_compile
  @@ -622,89 +451,73 @@
    *                has the reason.
    *
    *********************************************************************/
  -pcrs_job *pcrs_compile(const char *pattern, const char *substitute, const 
char *options, int *errptr)
  +pcrs_job *pcrs_compile(const char *pattern, const char *substitute,
  +                    const char *options, int *errptr)
   {
  -   pcrs_job *newjob;
  -   int flags;
  -   int capturecount;
  -   const char *error;
  -
  -   *errptr = 0;
  -
  -   /* 
  -    * Handle NULL arguments
  -    */
  -   if (pattern == NULL) pattern = "";
  -   if (substitute == NULL) substitute = "";
  -
  -
  -   /* 
  -    * Get and init memory
  -    */
  -   if (NULL == (newjob = (pcrs_job *)malloc(sizeof(pcrs_job))))
  -   {
  -      *errptr = PCRS_ERR_NOMEM;
  -      return NULL;
  -   }
  -   memset(newjob, '\0', sizeof(pcrs_job));
  -
  -
  -   /*
  -    * Evaluate the options
  -    */
  -   newjob->options = pcrs_parse_perl_options(options, &flags);
  -   newjob->flags = flags;
  -
  -
  -   /*
  -    * Compile the pattern
  -    */
  -   newjob->pattern = pcre_compile(pattern, newjob->options, &error, errptr, 
NULL);
  -   if (newjob->pattern == NULL)
  -   {
  -      pcrs_free_job(newjob);
  -      return NULL;
  -   }
  -
  -
  -   /*
  -    * Generate hints. This has little overhead, since the
  -    * hints will be NULL for a boring pattern anyway.
  -    */
  -   newjob->hints = pcre_study(newjob->pattern, 0, &error);
  -   if (error != NULL)
  -   {
  -      *errptr = PCRS_ERR_STUDY;
  -      pcrs_free_job(newjob);
  -      return NULL;
  -   }
  - 
  -
  -   /* 
  -    * Determine the number of capturing subpatterns. 
  -    * This is needed for handling $+ in the substitute.
  -    */
  -   if (0 > (*errptr = pcre_fullinfo(newjob->pattern, newjob->hints, 
PCRE_INFO_CAPTURECOUNT, &capturecount)))
  -   {
  -      pcrs_free_job(newjob);
  -      return NULL;
  -   }
  - 
  -
  -   /*
  -    * Compile the substitute
  -    */
  -   if (NULL == (newjob->substitute = pcrs_compile_replacement(substitute, 
newjob->flags & PCRS_TRIVIAL, capturecount, errptr)))
  -   {
  -      pcrs_free_job(newjob);
  -      return NULL;
  -   }
  - 
  -   return newjob;
  +    pcrs_job *newjob;
  +    int flags;
  +    int capturecount;
  +    const char *error;
  +
  +    *errptr = 0;
  +
  +    /* Handle NULL arguments */
  +    if (pattern == NULL)
  +     pattern = "";
  +    if (substitute == NULL)
  +     substitute = "";
  +
  +    /* Get and init memory */
  +    newjob = (pcrs_job *) xcalloc(1, sizeof(pcrs_job));
  +
  +    /* Evaluate the options */
  +    newjob->options = pcrs_parse_perl_options(options, &flags);
  +    newjob->flags = flags;
  +
  +    /* Compile the pattern */
  +    newjob->pattern =
  +     pcre_compile(pattern, newjob->options, &error, errptr, NULL);
  +    if (newjob->pattern == NULL) {
  +     pcrs_free_job(newjob);
  +     return NULL;
  +    }
  +
  +    /*
  +     * Generate hints. This has little overhead, since the
  +     * hints will be NULL for a boring pattern anyway.
  +     */
  +    newjob->hints = pcre_study(newjob->pattern, 0, &error);
  +    if (error != NULL) {
  +     *errptr = PCRS_ERR_STUDY;
  +     pcrs_free_job(newjob);
  +     return NULL;
  +    }
  +
  +    /* 
  +     * Determine the number of capturing subpatterns. 
  +     * This is needed for handling $+ in the substitute.
  +     */
  +    *errptr = pcre_fullinfo(newjob->pattern, newjob->hints,
  +                    PCRE_INFO_CAPTURECOUNT, &capturecount);
  +    if (*errptr < 0) {
  +     pcrs_free_job(newjob);
  +     return NULL;
  +    }
  +
  +    /*
  +     * Compile the substitute
  +     */
  +    newjob->substitute =
  +      pcrs_compile_replacement(substitute, newjob->flags & PCRS_TRIVIAL,
  +                               capturecount, errptr);
  +    if (newjob->substitute == NULL) {
  +     pcrs_free_job(newjob);
  +     return NULL;
  +    }
   
  +    return newjob;
   }
   
  -
   /*********************************************************************
    *
    * Function    :  pcrs_execute_list
  @@ -734,39 +547,33 @@
    *                 failiure, which may be translated to text using 
pcrs_strerror().
    *
    *********************************************************************/
  -int pcrs_execute_list(pcrs_job *joblist, char *subject, size_t 
subject_length, char **result, size_t *result_length)
  +int pcrs_execute_list(pcrs_job * joblist, char *s, size_t ns,
  +             char **result, size_t * result_length)
   {
  -   pcrs_job *job;
  -   char *old, *new;
  -   int hits, total_hits;
  - 
  -   old = subject;
  -   *result_length = subject_length;
  -   hits = total_hits = 0;
  -
  -   for (job = joblist; job != NULL; job = job->next)
  -   {
  -      hits = pcrs_execute(job, old, *result_length, &new, result_length);
  -
  -      if (old != subject) free(old);
  -
  -      if (hits < 0)
  -      {
  -         return(hits);
  -      }
  -      else
  -      {
  -         total_hits += hits;
  -         old = new;
  -      }
  -   }
  -
  -   *result = new;
  -   return(total_hits);
  +    pcrs_job *job;
  +    char *old = s;
  +    char *new = NULL;
  +    int hits = 0;
  +    int total_hits = 0;
  +
  +    *result_length = ns;
  +
  +    for (job = joblist; job != NULL; job = job->next) {
  +     hits = pcrs_execute(job, old, *result_length, &new, result_length);
  +
  +     if (old != s)
  +         free(old);
  +
  +     if (hits < 0)
  +         return (hits);
  +     total_hits += hits;
  +     old = new;
  +    }
   
  +    *result = new;
  +    return (total_hits);
   }
   
  -
   /*********************************************************************
    *
    * Function    :  pcrs_execute
  @@ -794,173 +601,153 @@
    *                 failiure, which may be translated to text using 
pcrs_strerror().
    *
    *********************************************************************/
  -int pcrs_execute(pcrs_job *job, char *subject, size_t subject_length, char 
**result, size_t *result_length)
  +int pcrs_execute(pcrs_job * job, char *s, size_t ns,
  +              char **result, size_t * result_length)
   {
  -   int offsets[3 * PCRS_MAX_SUBMATCHES],
  -       offset,
  -       i, k,
  -       matches_found,
  -       submatches,
  -       max_matches = PCRS_MAX_MATCH_INIT;
  -   size_t newsize;
  -   pcrs_match *matches, *dummy;
  -   char *result_offset;
  -
  -   offset = i = k = 0;
  -
  -   /* 
  -    * Sanity check & memory allocation
  -    */
  -   if (job == NULL || job->pattern == NULL || job->substitute == NULL)
  -   {
  -      *result = NULL;
  -      return(PCRS_ERR_BADJOB);
  -   }
  -
  -   if (NULL == (matches = (pcrs_match *)malloc(max_matches * 
sizeof(pcrs_match))))
  -   {
  -      *result = NULL;
  -      return(PCRS_ERR_NOMEM);
  -   }
  -   memset(matches, '\0', max_matches * sizeof(pcrs_match));
  -
  -
  -   /*
  -    * Find the pattern and calculate the space
  -    * requirements for the result
  -    */
  -   newsize = subject_length;
  -
  -   while ((submatches = pcre_exec(job->pattern, job->hints, subject, 
(int)subject_length, offset, 0, offsets, 3 * PCRS_MAX_SUBMATCHES)) > 0)
  -   {
  -      job->flags |= PCRS_SUCCESS;
  -      matches[i].submatches = submatches;
  -
  -      for (k = 0; k < submatches; k++)
  -      {
  -         matches[i].submatch_offset[k] = offsets[2 * k];
  -
  -         /* Note: Non-found optional submatches have length -1-(-1)==0 */
  -         matches[i].submatch_length[k] = offsets[2 * k + 1] - offsets[2 * 
k]; 
  -
  -         /* reserve mem for each submatch as often as it is ref'd */
  -         newsize += matches[i].submatch_length[k] * 
job->substitute->backref_count[k];
  -      }
  -      /* plus replacement text size minus match text size */
  -      newsize += strlen(job->substitute->text) - 
matches[i].submatch_length[0]; 
  -
  -      /* chunk before match */
  -      matches[i].submatch_offset[PCRS_MAX_SUBMATCHES] = 0;
  -      matches[i].submatch_length[PCRS_MAX_SUBMATCHES] = offsets[0];
  -      newsize += offsets[0] * 
job->substitute->backref_count[PCRS_MAX_SUBMATCHES];
  -
  -      /* chunk after match */
  -      matches[i].submatch_offset[PCRS_MAX_SUBMATCHES + 1] = offsets[1];
  -      matches[i].submatch_length[PCRS_MAX_SUBMATCHES + 1] = subject_length - 
offsets[1] - 1;
  -      newsize += (subject_length - offsets[1]) * 
job->substitute->backref_count[PCRS_MAX_SUBMATCHES + 1];
  -
  -      /* Storage for matches exhausted? -> Extend! */
  -      if (++i >= max_matches)
  -      {
  -         max_matches = (int)(max_matches * PCRS_MAX_MATCH_GROW);
  -         if (NULL == (dummy = (pcrs_match *)realloc(matches, max_matches * 
sizeof(pcrs_match))))
  -         {
  -            free(matches);
  -            *result = NULL;
  -            return(PCRS_ERR_NOMEM);
  -         }
  -         matches = dummy;
  -      }
  -
  -      /* Non-global search or limit reached? */
  -      if (!(job->flags & PCRS_GLOBAL)) break;
  -
  -      /* Don't loop on empty matches */
  -      if (offsets[1] == offset)
  -         if ((size_t)offset < subject_length)
  -            offset++;
  -         else
  -            break;
  -      /* Go find the next one */
  -      else
  -         offset = offsets[1];
  -   }
  -   /* Pass pcre error through if (bad) failiure */
  -   if (submatches < PCRE_ERROR_NOMATCH)
  -   {
  -      free(matches);
  -      return submatches;   
  -   }
  -   matches_found = i;
  -
  -
  -   /* 
  -    * Get memory for the result (must be freed by caller!)
  -    * and append terminating null byte.
  -    */
  -   if ((*result = (char *)malloc(newsize + 1)) == NULL)
  -   {
  -      free(matches);
  -      return PCRS_ERR_NOMEM;
  -   }
  -   else
  -   {
  -      (*result)[newsize] = '\0';
  -   }
  -
  -
  -   /* 
  -    * Replace
  -    */
  -   offset = 0;
  -   result_offset = *result;
  -
  -   for (i = 0; i < matches_found; i++)
  -   {
  -      /* copy the chunk preceding the match */
  -      memcpy(result_offset, subject + offset, 
(size_t)matches[i].submatch_offset[0] - offset); 
  -      result_offset += matches[i].submatch_offset[0] - offset;
  -
  -      /* For every segment of the substitute.. */
  -      for (k = 0; k <= job->substitute->backrefs; k++)
  -      {
  -         /* ...copy its text.. */
  -         memcpy(result_offset, job->substitute->text + 
job->substitute->block_offset[k], job->substitute->block_length[k]);
  -         result_offset += job->substitute->block_length[k];
  -
  -         /* ..plus, if it's not the last chunk, i.e.: There *is* a backref.. 
*/
  -         if (k != job->substitute->backrefs
  -             /* ..in legal range.. */
  -             && job->substitute->backref[k] < PCRS_MAX_SUBMATCHES + 2
  -             /* ..and referencing a real submatch.. */
  -             && job->substitute->backref[k] < matches[i].submatches
  -             /* ..that is nonempty.. */
  -             && matches[i].submatch_length[job->substitute->backref[k]] > 0)
  -         {
  -            /* ..copy the submatch that is ref'd. */
  -            memcpy(
  -               result_offset,
  -               subject + 
matches[i].submatch_offset[job->substitute->backref[k]],
  -               matches[i].submatch_length[job->substitute->backref[k]]
  -            );
  -            result_offset += 
matches[i].submatch_length[job->substitute->backref[k]];
  -         }
  -      }
  -      offset =  matches[i].submatch_offset[0] + 
matches[i].submatch_length[0];
  -   }
  -
  -   /* Copy the rest. */
  -   memcpy(result_offset, subject + offset, subject_length - offset);
  -
  -   *result_length = newsize;
  -   free(matches);
  -   return matches_found;
  -
  +    const size_t noffsets = PCRS_MAX_SUBMATCHES;
  +    int offsets[3 * noffsets];
  +    int nmatches = PCRS_MAX_MATCH_INIT;
  +    pcrs_match *matches = NULL;
  +    pcrs_substitute *jsp = (job ? job->substitute : NULL);
  +    size_t soff;
  +    char * te;
  +    char * t = NULL;
  +    size_t nt = 0;
  +    int nfound = PCRS_ERR_BADJOB;    /* assume error */
  +    int i;
  +    int k;
  +
  +    if (job == NULL || job->pattern == NULL || jsp == NULL)
  +     goto exit;
  +
  +    matches = (pcrs_match *) xcalloc(nmatches, sizeof(*matches));
  +
  +    /*
  +     * Find the pattern and calculate the space requirements for the result
  +     */
  +    nt = ns;
  +    soff = 0;
  +    i = 0;
  +    while ((nfound = pcre_exec(job->pattern, job->hints, s, ns, soff,
  +             0, offsets, 3 * noffsets)) > 0)
  +    {
  +     pcrs_match * mip = matches + i;
  +
  +     job->flags |= PCRS_SUCCESS;
  +     mip->submatches = nfound;
  +
  +     for (k = 0; k < nfound; k++) {
  +         mip->submatch_offset[k] = offsets[2 * k];
  +
  +         /* Note: Non-found optional submatches have length -1-(-1)==0 */
  +         mip->submatch_length[k] = offsets[2 * k + 1] - offsets[2 * k];
  +
  +         /* reserve mem for each submatch as often as it is ref'd */
  +         nt += mip->submatch_length[k] * jsp->backref_count[k];
  +     }
  +     /* plus replacement text size minus match text size */
  +     nt += strlen(jsp->text) - mip->submatch_length[0];
  +
  +     /* chunk before match */
  +     mip->submatch_offset[noffsets] = 0;
  +     mip->submatch_length[noffsets] = offsets[0];
  +     nt += offsets[0] * jsp->backref_count[noffsets];
  +
  +     /* chunk after match */
  +     mip->submatch_offset[noffsets + 1] = offsets[1];
  +     mip->submatch_length[noffsets + 1] = ns - offsets[1] - 1;
  +     nt += (ns - offsets[1]) * jsp->backref_count[noffsets + 1];
  +
  +     /* Storage for matches exhausted? -> Extend! */
  +     if (++i >= nmatches) {
  +         pcrs_match *newp;
  +         nmatches = (int) (nmatches * PCRS_MAX_MATCH_GROW);
  +         newp = (pcrs_match *)xrealloc(matches, nmatches * sizeof(*matches));
  +         matches = newp;
  +     }
  +
  +     /* Non-global search or limit reached? */
  +     if (!(job->flags & PCRS_GLOBAL))
  +         break;
  +
  +     /* Don't loop on empty matches */
  +     if (offsets[1] == soff)
  +         if (soff < ns)
  +             soff++;
  +         else
  +             break;
  +     /* Go find the next one */
  +     else
  +         soff = offsets[1];
  +    }
  +    /* Pass pcre error through if (bad) failiure */
  +    if (nfound < PCRE_ERROR_NOMATCH)
  +     goto exit;
  +
  +    nfound = i;
  +
  +    /* 
  +     * Get memory for the result (must be freed by caller!)
  +     * and append terminating null byte.
  +     */
  +    t = (char *) xmalloc(nt + 1);
  +    t[nt] = '\0';
  +
  +    /* 
  +     * Replace
  +     */
  +    for (i = 0, soff = 0, te = t; i < nfound; i++) {
  +     pcrs_match * mip = matches + i;
  +     size_t msoff;
  +     size_t mslen;
  +
  +     /* copy the chunk preceding the match */
  +     msoff = mip->submatch_offset[0];
  +     memcpy(te, s + soff, msoff - soff);
  +     te += msoff - soff;
  +
  +     /* For every segment of the substitute.. */
  +     for (k = 0; k <= jsp->backrefs; k++) {
  +         size_t jboff = jsp->block_offset[k];
  +         size_t jblen = jsp->block_length[k];
  +         size_t kx = jsp->backref[k];
  +
  +
  +         /* ...copy its text.. */
  +         memcpy(te, jsp->text + jboff, jblen);
  +         te += jblen;
  +
  +         /* ..plus, if not the last chunk, i.e.: There *is* a backref.. */
  +         if (!(k != jsp->backrefs
  +             /* ..in legal range.. */
  +          && kx < noffsets + 2
  +             /* ..and referencing a real submatch.. */
  +          && kx < mip->submatches
  +             /* ..that is nonempty.. */
  +          && mslen > 0))
  +             continue;
  +
  +         /* ..copy the submatch that is ref'd. */
  +         msoff = mip->submatch_offset[kx];
  +         mslen = mip->submatch_length[kx];
  +         memcpy(te, s + msoff, mslen);
  +         te += mslen;
  +     }
  +
  +     msoff = mip->submatch_offset[0];
  +     mslen = mip->submatch_length[0];
  +     soff = msoff + mslen;
  +    }
  +
  +    /* Copy the rest. */
  +    memcpy(te, s + soff, ns - soff);
  +    te += (ns - soff);
  +    *te = '\0';
  +
  +exit:
  +    if (matches)
  +     free(matches);
  +    *result = t;
  +    *result_length = nt;
  +    return nfound;
   }
  -
  -
  -/*
  -  Local Variables:
  -  tab-width: 3
  -  end:
  -*/
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/rpmio/pcrs.h
  ============================================================================
  $ cvs diff -u -r1.1.2.1 -r1.1.2.2 pcrs.h
  --- rpm/rpmio/pcrs.h  20 Sep 2014 17:52:06 -0000      1.1.2.1
  +++ rpm/rpmio/pcrs.h  21 Sep 2014 06:49:40 -0000      1.1.2.2
  @@ -1,171 +1,87 @@
  -#ifndef PCRS_H_INCLUDED
  -#define PCRS_H_INCLUDED
  +#ifndef H_PCRS
  +#define H_PCRS
   
  -/*********************************************************************
  - *
  - * File        :  $Source: /cvsroot/ijbswa/current/pcrs.h,v $
  - *
  - * Purpose     :  Header file for pcrs.c
  - *
  - * Copyright   :  see pcrs.c
  - *
  - * Revisions   :
  - *    $Log: pcrs.h,v $
  - *    Revision 1.11  2002/03/08 14:18:23  oes
  - *    Fixing -Wconversion warnings
  - *
  - *    Revision 1.10  2002/03/08 13:44:48  oes
  - *    Hiding internal functions, preventing double inclusion of pcre.h
  - *
  - *    Revision 1.9  2001/08/18 11:35:29  oes
  - *    - Introduced pcrs_strerror()
  - *    - added pcrs_execute_list()
  - *
  - *    Revision 1.8  2001/08/15 15:32:50  oes
  - *    Replaced the hard limit for the maximum number of matches
  - *    by dynamic reallocation
  - *
  - *    Revision 1.7  2001/08/05 13:13:11  jongfoster
  - *    Making parameters "const" where possible.
  - *
  - *    Revision 1.6  2001/07/29 18:52:06  jongfoster
  - *    Renaming _PCRS_H, and adding "extern C {}"
  - *
  - *    Revision 1.5  2001/07/18 17:27:00  oes
  - *    Changed interface; Cosmetics
  - *
  - *    Revision 1.4  2001/06/29 13:33:19  oes
  - *    - Cleaned up, commented and adapted to reflect the
  - *      changes in pcrs.c
  - *    - Introduced the PCRS_* flags
  - *
  - *    Revision 1.3  2001/06/09 10:58:57  jongfoster
  - *    Removing a single unused #define which referenced BUFSIZ
  - *
  - *    Revision 1.2  2001/05/25 11:03:55  oes
  - *    Added sanity check for NULL jobs to pcrs_exec_substitution
  - *
  - *    Revision 1.1.1.1  2001/05/15 13:59:02  oes
  - *    Initial import of version 2.9.3 source tree
  - *
  - *    Revision 1.4  2001/05/11 01:57:02  rodney
  - *    Added new file header standard w/RCS control tags.
  - *
  - *    revision 1.3  2001/05/08 02:38:13  rodney
  - *    Changed C++ "//" style comment to C style comments.
  - *
  - *    revision 1.2  2001/04/30 02:39:24  rodney
  - *    Made this pcrs.h file conditionally included.
  - *
  - *    revision 1.1  2001/04/16 21:10:38  rodney
  - *    Initial checkin
  - *
  - *********************************************************************/
  -
  -#define PCRS_H_VERSION "$Id: pcrs.h,v 1.11 2002/03/08 14:18:23 oes Exp $"
  -
  +/**
  + * \file rpmio/pcrs.h
  + * RPM pattern find&replace.
  + */
   
  -#ifndef _PCRE_H
   #include <pcre.h>
  -#endif
   
   #ifdef __cplusplus
   extern "C" {
   #endif
   
  -/*
  - * Constants:
  - */
  -
  -#define FALSE 0
  -#define TRUE 1
  -
   /* Capacity */
  -#define PCRS_MAX_SUBMATCHES  33     /* Maximum number of capturing 
subpatterns allowed. MUST be <= 99! FIXME: Should be dynamic */
  -#define PCRS_MAX_MATCH_INIT  40     /* Initial amount of matches that can be 
stored in global searches */
  -#define PCRS_MAX_MATCH_GROW  1.6    /* Factor by which storage for matches 
is extended if exhausted */
  +/* Maximum number of capturing subpatterns allowed. MUST be <= 99! */
  +/* FIXME: Should be dynamic */
  +#define PCRS_MAX_SUBMATCHES  33
  +/* Initial amount of matches that can be stored in global searches */
  +#define PCRS_MAX_MATCH_INIT  40
  +/* Factor by which storage for matches is extended if exhausted */
  +#define PCRS_MAX_MATCH_GROW  1.6
   
   /* Error codes */
  -#define PCRS_ERR_NOMEM     -10      /* Failed to acquire memory. */
  -#define PCRS_ERR_CMDSYNTAX -11      /* Syntax of s///-command */
  -#define PCRS_ERR_STUDY     -12      /* pcre error while studying the pattern 
*/
  -#define PCRS_ERR_BADJOB    -13      /* NULL job pointer, pattern or 
substitute */
  -#define PCRS_WARN_BADREF   -14      /* Backreference out of range */
  +#define PCRS_ERR_NOMEM     -10       /* Failed to acquire memory. */
  +#define PCRS_ERR_CMDSYNTAX -11       /* Syntax of s///-command */
  +#define PCRS_ERR_STUDY     -12       /* pcre error while studying the 
pattern */
  +#define PCRS_ERR_BADJOB    -13       /* NULL job pointer, pattern or 
substitute */
  +#define PCRS_WARN_BADREF   -14       /* Backreference out of range */
   
   /* Flags */
  -#define PCRS_GLOBAL          1      /* Job should be applied globally, as 
with perl's g option */
  -#define PCRS_TRIVIAL         2      /* Backreferences in the substitute are 
ignored */
  -#define PCRS_SUCCESS         4      /* Job did previously match */
  -
  -
  -/*
  - * Data types:
  - */
  +#define PCRS_GLOBAL          1       /* Job should be applied globally, as 
with perl's g option */
  +#define PCRS_TRIVIAL         2       /* Backreferences in the substitute are 
ignored */
  +#define PCRS_SUCCESS         4       /* Job did previously match */
   
   /* A compiled substitute */
  -
   typedef struct {
  -  char  *text;                                   /* The plaintext part of 
the substitute, with all backreferences stripped */
  -  int    backrefs;                               /* The number of 
backreferences */
  -  int    block_offset[PCRS_MAX_SUBMATCHES];      /* Array with the offsets 
of all plaintext blocks in text */
  -  size_t block_length[PCRS_MAX_SUBMATCHES];      /* Array with the lengths 
of all plaintext blocks in text */
  -  int    backref[PCRS_MAX_SUBMATCHES];           /* Array with the backref 
number for all plaintext block borders */
  -  int    backref_count[PCRS_MAX_SUBMATCHES + 2]; /* Array with the number of 
references to each backref index */
  +    char *text;                      /* The plaintext part of the 
substitute, with all backreferences stripped */
  +    int backrefs;            /* The number of backreferences */
  +    int block_offset[PCRS_MAX_SUBMATCHES];   /* Array with the offsets of 
all plaintext blocks in text */
  +    size_t block_length[PCRS_MAX_SUBMATCHES];        /* Array with the 
lengths of all plaintext blocks in text */
  +    int backref[PCRS_MAX_SUBMATCHES];        /* Array with the backref 
number for all plaintext block borders */
  +    int backref_count[PCRS_MAX_SUBMATCHES + 2];      /* Array with the 
number of references to each backref index */
   } pcrs_substitute;
   
  -
   /*
    * A match, including all captured subpatterns (submatches)
    * Note: The zeroth is the whole match, the PCRS_MAX_SUBMATCHES + 0th
    * is the range before the match, the PCRS_MAX_SUBMATCHES + 1th is the
    * range after the match.
    */
  -
   typedef struct {
  -  int    submatches;                               /* Number of captured 
subpatterns */
  -  int    submatch_offset[PCRS_MAX_SUBMATCHES + 2]; /* Offset for each 
submatch in the subject */
  -  size_t submatch_length[PCRS_MAX_SUBMATCHES + 2]; /* Length of each 
submatch in the subject */
  +    int submatches;          /* Number of captured subpatterns */
  +    int submatch_offset[PCRS_MAX_SUBMATCHES + 2];    /* Offset for each 
submatch in the subject */
  +    size_t submatch_length[PCRS_MAX_SUBMATCHES + 2]; /* Length of each 
submatch in the subject */
   } pcrs_match;
   
  -
   /* A PCRS job */
  -
   typedef struct PCRS_JOB {
  -  pcre *pattern;                            /* The compiled pcre pattern */
  -  pcre_extra *hints;                        /* The pcre hints for the 
pattern */
  -  int options;                              /* The pcre options (numeric) */
  -  int flags;                                /* The pcrs and user flags (see 
"Flags" above) */
  -  pcrs_substitute *substitute;              /* The compiled pcrs substitute 
*/
  -  struct PCRS_JOB *next;                    /* Pointer for chaining jobs to 
joblists */
  +    pcre *pattern;           /* The compiled pcre pattern */
  +    pcre_extra *hints;       /* The pcre hints for the pattern */
  +    int options;             /* The pcre options (numeric) */
  +    int flags;               /* The pcrs and user flags (see "Flags" above) 
*/
  +    pcrs_substitute *substitute;     /* The compiled pcrs substitute */
  +    struct PCRS_JOB *next;   /* Pointer for chaining jobs to joblists */
   } pcrs_job;
   
  -
  -/*
  - * Prototypes:
  - */
  -
   /* Main usage */
  -extern pcrs_job        *pcrs_compile_command(const char *command, int 
*errptr);
  -extern pcrs_job        *pcrs_compile(const char *pattern, const char 
*substitute, const char *options, int *errptr);
  -extern int              pcrs_execute(pcrs_job *job, char *subject, size_t 
subject_length, char **result, size_t *result_length);
  -extern int              pcrs_execute_list(pcrs_job *joblist, char *subject, 
size_t subject_length, char **result, size_t *result_length);
  +extern pcrs_job *pcrs_compile_command(const char *command, int *errptr);
  +extern pcrs_job *pcrs_compile(const char *pattern, const char *substitute,
  +             const char *options, int *errptr);
  +extern int pcrs_execute(pcrs_job * job, char *s, size_t ns,
  +             char **result, size_t * result_length);
  +extern int pcrs_execute_list(pcrs_job * joblist, char *s, size_t ns,
  +             char **result, size_t * result_length);
   
   /* Freeing jobs */
  -extern pcrs_job        *pcrs_free_job(pcrs_job *job);
  -extern void             pcrs_free_joblist(pcrs_job *joblist);
  +extern pcrs_job *pcrs_free_job(pcrs_job * job);
  +extern void pcrs_free_joblist(pcrs_job * joblist);
   
   /* Info on errors: */
   extern const char *pcrs_strerror(const int error);
   
  -
   #ifdef __cplusplus
  -} /* extern "C" */
  +}                            /* extern "C" */
   #endif
  -
  -#endif /* ndef PCRS_H_INCLUDED */
  -
  -/*
  -  Local Variables:
  -  tab-width: 3
  -  end:
  -*/
  +#endif                               /* ndef PCRS_H_INCLUDED */
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/rpmio/pcrsed.c
  ============================================================================
  $ cvs diff -u -r1.1.2.1 -r1.1.2.2 pcrsed.c
  --- rpm/rpmio/pcrsed.c        20 Sep 2014 21:00:49 -0000      1.1.2.1
  +++ rpm/rpmio/pcrsed.c        21 Sep 2014 06:49:40 -0000      1.1.2.2
  @@ -1,86 +1,50 @@
  -/*********************************************************************
  - *
  - * File        :  $Source: /v/rpm/cvs/rpm/rpmio/Attic/pcrsed.c,v $
  - *
  - * Purpose     :  pcrsed is a small demo application for pcrs.
  - *                FWIW, it's licensed under the GPL
  - *   
  - *********************************************************************/
  -
  -#include <stdio.h>
  -#include <errno.h>
  -#include <string.h>
  -
  -#include "pcrs.h"
  -
  -#define BUFFER_SIZE 100000
  - 
  -int main(int Argc, char **Argv)
  +#include "system.h"
  +
  +#include <rpmio.h>   /* XXX rpmioClean */
  +
  +#define      _RPMSED_INTERNAL
  +#include <rpmsed.h>
  +
  +#include "debug.h"
  +
  +int main(int argc, char **argv)
   {
  -   pcrs_job *job;
  -   char *result;
  -   int err, linenum=0;
  -   size_t length;
  -
  -   char linebuf[BUFFER_SIZE];
  -   FILE *in;
  - 
  -   /*
  -    * Check usage
  -    */
  -   if (Argc < 2 || Argc > 3)
  -   {
  -      fprintf(stderr, "Usage: %s s/pattern/substitute/[options]  [file]\n", 
Argv[0]);
  -      return 1;
  -   }
  - 
  -   /* 
  -    * Open input file 
  -    */
  -   if (Argc == 3)
  -   {
  -      if (NULL == (in = fopen(Argv[2], "r")))
  -      {
  -         fprintf(stderr, "%s: Couldn't open %s\n", Argv[2], strerror(errno));
  -         return(1);
  -      }
  -   }
  -   else /* Argc == 2 */
  -   {
  -      in = stdin;
  -   }
  -
  -   /*
  -    * Compile the job
  -    */
  -   if (NULL == (job = pcrs_compile_command(Argv[1], &err)))
  -   {
  -      fprintf(stderr, "%s Compile error:  %s (%d).\n", Argv[0], 
pcrs_strerror(err), err);
  -      return(1);
  -   }
  -
  -
  -   /*
  -    * Execute on every input line
  -    */
  -   while (!feof(in) && !ferror(in) && fgets(linebuf, BUFFER_SIZE, in))
  -   {
  -      length = strlen(linebuf);
  -      linenum++;
  -
  -      if (0 > (err = pcrs_execute(job, linebuf, length, &result, &length)))
  -      {
  -         fprintf(stderr, "%s: Exec error:  %s (%d) in input line %d\n", 
Argv[0], pcrs_strerror(err), err, linenum);
  -         return(1);
  -      }
  -      else
  -      {
  -         fwrite(result, 1, length, stdout);
  -         free(result);
  -      }
  -   }
  -
  -   pcrs_free_job(job);
  -   return(0);
  - 
  +    /* Parse options and initialize job patterns. */
  +    rpmsed sed = rpmsedNew(argv, 0);
  +    int rc = EXIT_FAILURE;
  +    rpmRC xx;
  +    int k;
  +
  +    if (sed == NULL)
  +     goto exit;
  +
  +    sed->ofp = stdout;
  +    for (k = 0; k < sed->ac; k++) {
  +
  +     /* Open next input file */
  +     sed->fn = sed->av[k];
  +     xx = rpmsedOpen(sed, sed->fn);
  +     if (xx)
  +         goto exit;
  +
  +     /* Read & Execute jobs on every input line */
  +     xx = rpmsedProcess(sed);
  +     if (xx)
  +         goto exit;
  +
  +     /* Close input file */
  +     xx = rpmsedClose(sed);
  +     if (xx)
  +         goto exit;
  +    }
  +    sed->ofp = NULL;
  +
  +    rc = EXIT_SUCCESS;
  +
  +exit:
  +    sed = rpmsedFree(sed);
  +    rpmioClean();
  +
  +    return rc;
  +
   }
  @@ .
______________________________________________________________________
RPM Package Manager                                    http://rpm5.org
CVS Sources Repository                                rpm-cvs@rpm5.org

Reply via email to