Back to home page

Enduro/X

 
 

    


0001 /**
0002  * @brief Regex common routines
0003  *
0004  * @file exregex.c
0005  */
0006 /* -----------------------------------------------------------------------------
0007  * Enduro/X Middleware Platform for Distributed Transaction Processing
0008  * Copyright (C) 2009-2016, ATR Baltic, Ltd. All Rights Reserved.
0009  * Copyright (C) 2017-2023, Mavimax, Ltd. All Rights Reserved.
0010  * This software is released under one of the following licenses:
0011  * AGPL (with Java and Go exceptions) or Mavimax's license for commercial use.
0012  * See LICENSE file for full text.
0013  * -----------------------------------------------------------------------------
0014  * AGPL license:
0015  *
0016  * This program is free software; you can redistribute it and/or modify it under
0017  * the terms of the GNU Affero General Public License, version 3 as published
0018  * by the Free Software Foundation;
0019  *
0020  * This program is distributed in the hope that it will be useful, but WITHOUT ANY
0021  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
0022  * PARTICULAR PURPOSE. See the GNU Affero General Public License, version 3
0023  * for more details.
0024  *
0025  * You should have received a copy of the GNU Affero General Public License along 
0026  * with this program; if not, write to the Free Software Foundation, Inc.,
0027  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
0028  *
0029  * -----------------------------------------------------------------------------
0030  * A commercial use license is available from Mavimax, Ltd
0031  * contact@mavimax.com
0032  * -----------------------------------------------------------------------------
0033  */
0034 
0035 /*---------------------------Includes-----------------------------------*/
0036 #include <ndrstandard.h>
0037 #include <time.h>
0038 #include <sys/time.h>
0039 #include <stdlib.h>
0040 #include <string.h>
0041 #include <stdio.h>
0042 #include <utlist.h>
0043 #include <nstdutil.h>
0044 #include <ndrx_ini.h>
0045 #include <inicfg.h>
0046 #include <nerror.h>
0047 #include <sys_unix.h>
0048 #include <errno.h>
0049 #include <nerror.h>
0050 #include <userlog.h>
0051 #include <regex.h>
0052 #include <ndebug.h>
0053 #include <exregex.h>
0054 /*---------------------------Externs------------------------------------*/
0055 /*---------------------------Macros-------------------------------------*/
0056 /*---------------------------Enums--------------------------------------*/
0057 /*---------------------------Typedefs-----------------------------------*/
0058 /*---------------------------Globals------------------------------------*/
0059 /*---------------------------Statics------------------------------------*/
0060 /*---------------------------Prototypes---------------------------------*/
0061 
0062 /**
0063  * Compile the regular expression rules
0064  * @param p_re struct of regex
0065  * @param expr  Expression to compile
0066  * @return SUCCEED/FAIL
0067  */
0068 expublic int ndrx_regcomp(regex_t *p_re, char *expr)
0069 {
0070     int ret=EXSUCCEED;
0071     
0072     if (EXSUCCEED!=(ret=regcomp(p_re, expr, REG_EXTENDED | REG_NOSUB)))
0073     {
0074         char *errmsg;
0075         int errlen;
0076         char errbuf[2048];
0077 
0078         errlen = (int) regerror(ret, p_re, NULL, 0);
0079         errmsg = (char *) NDRX_MALLOC(errlen*sizeof(char));
0080         regerror(ret, p_re, errmsg, errlen);
0081 
0082         NDRX_LOG_EARLY(log_error, "Failed to eventexpr [%s]: %s", expr, errbuf);
0083 
0084         NDRX_FREE(errmsg);
0085         ret=EXFAIL;
0086     }
0087     else
0088     {
0089         NDRX_LOG_EARLY(log_debug, "eventexpr [%s] compiled OK", expr);
0090     }
0091     
0092     return ret;
0093 }
0094 
0095 /**
0096  * Match the regular expressions on data
0097  * @param p_re compiled regexp
0098  * @param data data to evaluate
0099  * @return SUCCEED is matched, any other not matched
0100  */
0101 expublic int ndrx_regexec(regex_t *p_re, char *data)
0102 {
0103     return regexec(p_re, data, (size_t) 0, NULL, 0);
0104 }
0105 
0106 /**
0107  * Free up regexp
0108  * @param p_re
0109  */
0110 expublic void ndrx_regfree(regex_t *p_re)
0111 {
0112     regfree(p_re);
0113 }
0114 
0115 /**
0116  * Copy string to dest by doing escape of posix regex symbols
0117  * @param dest dest buffer assume enought space it has
0118  * @param src source buffer to copy from
0119  * @param opt_start optional start symbol to copy to str, opt if 0x0 not used
0120  * @param opt_end optional end symbol to copy to str, opt if 0x0 not used
0121  * @param subst_from substitute from char (opt), if 0x0 not used
0122  * @param subst_to substitute to string (opt)
0123  */
0124 expublic void ndrx_regasc_cpyesc(char *dest, char *src, 
0125         char opt_start, char opt_end, char subst_from, char *subst_to)
0126 {
0127     char *p = dest;
0128     int i;
0129     int len = strlen(src);
0130     
0131     if (opt_start)
0132     {
0133         *p=opt_start;
0134         p++;
0135     }
0136     
0137     for (i=0; i<len; i++)
0138     {
0139         if (strchr(".^$*+?()[{\\|", src[i]))
0140         {
0141             *p='\'';
0142             p++;
0143             *p = src[i];
0144         }
0145         else if (subst_from==src[i])
0146         {
0147             while (EXEOS!=*subst_to)
0148             {
0149                 *p = *subst_to;
0150                 
0151                 p++;
0152                 subst_to++;
0153             }
0154         }
0155         else
0156         {
0157             *p = src[i];
0158             p++;
0159         }
0160     }
0161     
0162     if (opt_end)
0163     {
0164         *p=opt_end;
0165         p++;
0166     }
0167     
0168     *p=EXEOS;
0169 }
0170 
0171 /**
0172  * Quick exec, compile & test & free
0173  * @param expr regular expression
0174  * @param data data to test
0175  * @return EXSUCCEED if matched
0176  */
0177 expublic int ndrx_regqexec(const char *expr, const char *data)
0178 {
0179     int ret = EXFAIL;
0180     regex_t re;
0181     
0182     if (EXSUCCEED==ndrx_regcomp(&re, (char *)expr))
0183     {
0184         ret = ndrx_regexec(&re, (char *)data);
0185         ndrx_regfree(&re);
0186     }
0187     
0188     return ret;
0189 }
0190 
0191 /*
0192  * If we want to do some extract in future, take a look on: regmatch_t
0193  * See:
0194  *  - https://stackoverflow.com/questions/15238468/c-regular-expressions-extracting-the-actual-matches
0195  *  - https://stackoverflow.com/questions/17764422/regmatch-t-how-can-i-get-match-only
0196  * 
0197  */
0198 
0199 /* vim: set ts=4 sw=4 et smartindent: */