openenvutils/commandshell/shell/src/modules/pcre.c
changeset 0 2e3d3ce01487
equal deleted inserted replaced
-1:000000000000 0:2e3d3ce01487
       
     1 /*
       
     2  * pcre.c - interface to the PCRE library
       
     3  *
       
     4  * This file is part of zsh, the Z shell.
       
     5  *
       
     6  * Copyright (c) 2001, 2002, 2003, 2004 Clint Adams
       
     7  * All rights reserved.
       
     8  *
       
     9  * Permission is hereby granted, without written agreement and without
       
    10  * license or royalty fees, to use, copy, modify, and distribute this
       
    11  * software and to distribute modified versions of this software for any
       
    12  * purpose, provided that the above copyright notice and the following
       
    13  * two paragraphs appear in all copies of this software.
       
    14  *
       
    15  * In no event shall Clint Adams or the Zsh Development Group be liable
       
    16  * to any party for direct, indirect, special, incidental, or consequential
       
    17  * damages arising out of the use of this software and its documentation,
       
    18  * even if Andrew Main and the Zsh Development Group have been advised of
       
    19  * the possibility of such damage.
       
    20  *
       
    21  * Clint Adams and the Zsh Development Group specifically disclaim any
       
    22  * warranties, including, but not limited to, the implied warranties of
       
    23  * merchantability and fitness for a particular purpose.  The software
       
    24  * provided hereunder is on an "as is" basis, and Andrew Main and the
       
    25  * Zsh Development Group have no obligation to provide maintenance,
       
    26  * support, updates, enhancements, or modifications.
       
    27  *
       
    28  */
       
    29 
       
    30 
       
    31 #include "pcre.mdh"
       
    32 #include "pcre.pro"
       
    33 
       
    34 #define CPCRE_PLAIN 0
       
    35 
       
    36 /**/
       
    37 #if defined(HAVE_PCRE_COMPILE) && defined(HAVE_PCRE_EXEC)
       
    38 #include <pcre.h>
       
    39 
       
    40 static pcre *pcre_pattern;
       
    41 static pcre_extra *pcre_hints;
       
    42 
       
    43 /**/
       
    44 static int
       
    45 bin_pcre_compile(char *nam, char **args, Options ops, UNUSED(int func))
       
    46 {
       
    47     int pcre_opts = 0, pcre_errptr;
       
    48     const char *pcre_error;
       
    49     
       
    50     if(OPT_ISSET(ops,'a')) pcre_opts |= PCRE_ANCHORED;
       
    51     if(OPT_ISSET(ops,'i')) pcre_opts |= PCRE_CASELESS;
       
    52     if(OPT_ISSET(ops,'m')) pcre_opts |= PCRE_MULTILINE;
       
    53     if(OPT_ISSET(ops,'x')) pcre_opts |= PCRE_EXTENDED;
       
    54     
       
    55     pcre_hints = NULL;  /* Is this necessary? */
       
    56     
       
    57     pcre_pattern = pcre_compile(*args, pcre_opts, &pcre_error, &pcre_errptr, NULL);
       
    58     
       
    59     if (pcre_pattern == NULL)
       
    60     {
       
    61 	zwarnnam(nam, "error in regex: %s", pcre_error, 0);
       
    62 	return 1;
       
    63     }
       
    64     
       
    65     return 0;
       
    66 }
       
    67 
       
    68 /**/
       
    69 #ifdef HAVE_PCRE_STUDY
       
    70 
       
    71 /**/
       
    72 static int
       
    73 bin_pcre_study(char *nam, UNUSED(char **args), UNUSED(Options ops), UNUSED(int func))
       
    74 {
       
    75     const char *pcre_error;
       
    76 
       
    77     if (pcre_pattern == NULL)
       
    78     {
       
    79 	zwarnnam(nam, "no pattern has been compiled for study",
       
    80 		 NULL, 0);
       
    81 	return 1;
       
    82     }
       
    83     
       
    84     pcre_hints = pcre_study(pcre_pattern, 0, &pcre_error);
       
    85     if (pcre_error != NULL)
       
    86     {
       
    87 	zwarnnam(nam, "error while studying regex: %s", pcre_error, 0);
       
    88 	return 1;
       
    89     }
       
    90     
       
    91     return 0;
       
    92 }
       
    93 
       
    94 /**/
       
    95 #else /* !HAVE_PCRE_STUDY */
       
    96 
       
    97 # define bin_pcre_study bin_notavail
       
    98 
       
    99 /**/
       
   100 #endif /* !HAVE_PCRE_STUDY */
       
   101 
       
   102 /**/
       
   103 static int
       
   104 zpcre_get_substrings(char *arg, int *ovec, int ret, char *receptacle)
       
   105 {
       
   106     char **captures, **matches;
       
   107 
       
   108 	if(!pcre_get_substring_list(arg, ovec, ret, (const char ***)&captures)) {
       
   109 	    
       
   110 	    matches = zarrdup(&captures[1]); /* first one would be entire string */
       
   111 	    if (receptacle == NULL)
       
   112 		setaparam("match", matches);
       
   113 	    else
       
   114 		setaparam(receptacle, matches);
       
   115 	    
       
   116 	    pcre_free_substring_list((const char **)captures);
       
   117 	}
       
   118 
       
   119 	return 0;
       
   120 }
       
   121 
       
   122 /**/
       
   123 static int
       
   124 bin_pcre_match(char *nam, char **args, Options ops, UNUSED(int func))
       
   125 {
       
   126     int ret, capcount, *ovec, ovecsize;
       
   127     char *receptacle = NULL;
       
   128     
       
   129     if(OPT_ISSET(ops,'a')) {
       
   130 	receptacle = *args++;
       
   131 	if(!*args) {
       
   132 	    zwarnnam(nam, "not enough arguments", NULL, 0);
       
   133 	    return 1;
       
   134 	}
       
   135     }
       
   136     
       
   137     if ((ret = pcre_fullinfo(pcre_pattern, pcre_hints, PCRE_INFO_CAPTURECOUNT, &capcount)))
       
   138     {
       
   139 	zwarnnam(nam, "error %d in fullinfo", NULL, ret);
       
   140 	return 1;
       
   141     }
       
   142     
       
   143     ovecsize = (capcount+1)*3;
       
   144     ovec = zalloc(ovecsize*sizeof(int));
       
   145     
       
   146     ret = pcre_exec(pcre_pattern, pcre_hints, *args, strlen(*args), 0, 0, ovec, ovecsize);
       
   147     
       
   148     if (ret==0) return 0;
       
   149     else if (ret==PCRE_ERROR_NOMATCH) return 1; /* no match */
       
   150     else if (ret>0) {
       
   151 	zpcre_get_substrings(*args, ovec, ret, receptacle);
       
   152 	return 0;
       
   153     }
       
   154     else {
       
   155 	zwarnnam(nam, "error in pcre_exec", NULL, 0);
       
   156 	return 1;
       
   157     }
       
   158     
       
   159     return 1;
       
   160 }
       
   161 
       
   162 /**/
       
   163 static int
       
   164 cond_pcre_match(char **a, int id)
       
   165 {
       
   166     pcre *pcre_pat;
       
   167     const char *pcre_err;
       
   168     char *lhstr, *rhre;
       
   169     int r = 0, pcre_opts = 0, pcre_errptr, capcnt, *ov, ovsize;
       
   170 
       
   171     lhstr = cond_str(a,0,0);
       
   172     rhre = cond_str(a,1,0);
       
   173 
       
   174     switch(id) {
       
   175 	 case CPCRE_PLAIN:
       
   176 		 pcre_pat = pcre_compile(rhre, pcre_opts, &pcre_err, &pcre_errptr, NULL);
       
   177                  pcre_fullinfo(pcre_pat, NULL, PCRE_INFO_CAPTURECOUNT, &capcnt);
       
   178     		 ovsize = (capcnt+1)*3;
       
   179 		 ov = zalloc(ovsize*sizeof(int));
       
   180     		 r = pcre_exec(pcre_pat, NULL, lhstr, strlen(lhstr), 0, 0, ov, ovsize);
       
   181     		if (r==0) return 1;
       
   182 	        else if (r==PCRE_ERROR_NOMATCH) return 0; /* no match */
       
   183                 else if (r>0) {
       
   184 		    zpcre_get_substrings(lhstr, ov, r, NULL);
       
   185 		    return 1;
       
   186 		}
       
   187 		break;
       
   188     }
       
   189 
       
   190     return 0;
       
   191 }
       
   192 
       
   193 /**/
       
   194 #else /* !(HAVE_PCRE_COMPILE && HAVE_PCRE_EXEC) */
       
   195 
       
   196 # define bin_pcre_compile bin_notavail
       
   197 # define bin_pcre_study bin_notavail
       
   198 # define bin_pcre_match bin_notavail
       
   199 # define cond_pcre_match cond_match
       
   200 
       
   201 /**/
       
   202 #endif /* !(HAVE_PCRE_COMPILE && HAVE_PCRE_EXEC) */
       
   203 
       
   204 static struct builtin bintab[] = {
       
   205     BUILTIN("pcre_compile", 0, bin_pcre_compile, 1, 1, 0, "aimx",  NULL),
       
   206     BUILTIN("pcre_study",   0, bin_pcre_study,   0, 0, 0, NULL,    NULL),
       
   207     BUILTIN("pcre_match",   0, bin_pcre_match,   1, 2, 0, "a",    NULL)
       
   208 };
       
   209 
       
   210 static struct conddef cotab[] = {
       
   211     CONDDEF("pcre-match", CONDF_INFIX, cond_pcre_match, 0, 0, CPCRE_PLAIN)
       
   212 };
       
   213 
       
   214 
       
   215 /**/
       
   216 int
       
   217 setup_(UNUSED(Module m))
       
   218 {
       
   219     return 0;
       
   220 }
       
   221 
       
   222 /**/
       
   223 int
       
   224 boot_(Module m)
       
   225 {
       
   226     return !addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab)) ||
       
   227 	   !addconddefs(m->nam, cotab, sizeof(cotab)/sizeof(*cotab));
       
   228 }
       
   229 
       
   230 /**/
       
   231 int
       
   232 cleanup_(Module m)
       
   233 {
       
   234     deletebuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
       
   235     deleteconddefs(m->nam, cotab, sizeof(cotab)/sizeof(*cotab));
       
   236     return 0;
       
   237 }
       
   238 
       
   239 /**/
       
   240 int
       
   241 finish_(UNUSED(Module m))
       
   242 {
       
   243     return 0;
       
   244 }