1/* -*- c -*- 2 * File: pstring.h 3 * Author: Igor Vlasenko <vlasenko@imath.kiev.ua> 4 * Created: Fri Jul 1 20:11:51 2005 5 * 6 * $Id$ 7 */ 8 9#ifdef HAVE_CONFIG_H 10#include "config.h" 11#endif 12#include <stdio.h> 13#include <string.h> 14#include "pstring.h" 15#include "tmpllog.h" 16#include "exprval.h" 17#include "pmiscdef.h" /*for snprintf */ 18 19static 20PSTRING 21double_to_pstring (double number, char buffer[], size_t bufsize) { 22 size_t len=0; 23 size_t tmplen=0; 24 PSTRING retval; 25 snprintf(buffer,bufsize,"%f",number); 26 len=strlen(buffer); 27 tmplen=len; 28 /* removing trailing 0 as 2.00000... */ 29 while (buffer[tmplen-1]=='0' && tmplen-->0); 30 if (buffer[tmplen-1]=='.') { 31 tmplen--; 32 len=tmplen; 33 } 34 retval.begin=buffer; 35 retval.endnext=buffer+len; 36 return retval; 37} 38 39static 40PSTRING 41int_to_pstring (EXPR_int64 number, char buffer[], size_t bufsize) { 42 size_t len=0; 43 PSTRING retval; 44 snprintf(buffer, bufsize,"%" EXPR_PRId64 , number); 45 len=strlen(buffer); 46 retval.begin=buffer; 47 retval.endnext=buffer+len; 48 return retval; 49} 50 51static 52int 53pstring_ge(PSTRING a, PSTRING b) { 54 const char* in_a=a.begin; 55 const char* in_b=b.begin; 56 if (in_b==NULL) return 1; 57 if (in_a==NULL) return 0; 58 while (in_a<a.endnext && in_b < b.endnext && *in_a++==*in_b++); 59 if ((in_a==a.endnext && in_b==b.endnext) || *(--in_a) >= *(--in_b) ) return 1; else return 0; 60} 61 62static 63int 64pstring_le(PSTRING a, PSTRING b) { 65 const char* in_a=a.begin; 66 const char* in_b=b.begin; 67 if (in_a==NULL) return 1; 68 if (in_b==NULL) return 0; 69 while (in_a<a.endnext && in_b < b.endnext && *in_a++==*in_b++); 70 if ((in_a==a.endnext && in_b==b.endnext) || *(--in_a) <= *(--in_b) ) return 1; else return 0; 71} 72 73static 74int 75pstring_ne(PSTRING a, PSTRING b) { 76 const char* in_a=a.begin; 77 const char* in_b=b.begin; 78 if (in_a==NULL || in_b==NULL) return in_a != in_b; 79 while (in_a<a.endnext && in_b < b.endnext && *in_a++==*in_b++); 80 if (in_a==a.endnext && in_b==b.endnext && *(--in_a) == *(--in_b)) return 0; else return 1; 81} 82 83static 84int 85pstring_eq(PSTRING a, PSTRING b) { 86 const char* in_a=a.begin; 87 const char* in_b=b.begin; 88 if (in_a==NULL || in_b==NULL) return in_a == in_b; 89 if (in_a==a.endnext) return in_b==b.endnext; 90 while (in_a<a.endnext && in_b < b.endnext && *in_a++==*in_b++); 91 if (in_a==a.endnext && in_b==b.endnext && *(--in_a) == *(--in_b)) return 1; else return 0; 92} 93 94static 95int 96pstring_gt(PSTRING a, PSTRING b) { 97 const char* in_a=a.begin; 98 const char* in_b=b.begin; 99 if (in_a==NULL) return 0; 100 if (in_b==NULL) return 1; 101 while (in_a<a.endnext && in_b < b.endnext && *in_a++==*in_b++); 102 if ((in_b==b.endnext && in_a!=a.endnext) 103 || (*(--in_a) > *(--in_b)) ) return 1; else return 0; 104} 105 106static 107int 108pstring_lt(PSTRING a, PSTRING b) { 109 const char* in_a=a.begin; 110 const char* in_b=b.begin; 111 if (in_b==NULL) return 0; 112 if (in_a==NULL) return 1; 113 while (in_a<a.endnext && in_b < b.endnext && *in_a++==*in_b++); 114 if ((in_b!=b.endnext && in_a==a.endnext) 115 || *(--in_a) < *(--in_b) ) return 1; else return 0; 116} 117 118static 119int 120re_notlike(struct expr_parser* exprobj, PSTRING a, PSTRING b) { 121 return ! re_like(exprobj, a,b); 122} 123 124#ifndef HAVE_PCRE 125static 126int 127re_like(struct expr_parser* exprobj, PSTRING a, PSTRING b) { 128 log_expr(exprobj,TMPL_LOG_ERROR,"can't parse the regular expression (sorry, Stanislav Yadykin regexp extension is disabled at compile time) \n"); 129 return 0; 130} 131#else 132#include <pcre.h> 133static 134int 135re_like(struct expr_parser* exprobj, PSTRING a, PSTRING b) { 136 pcre* re; 137 int ovector[30]; 138 int rc, erroffset; 139 const char* error; 140 const char* subject=a.begin; 141 int subject_length=(int)(a.endnext-a.begin); 142 char* pattern; 143 if (subject==NULL) { 144 log_expr(exprobj,TMPL_LOG_INFO, "regular expression: applied to undefined value.\n"); 145 return 0; 146 } 147 if (b.begin==NULL || (b.endnext-b.begin)==0) { 148 log_expr(exprobj,TMPL_LOG_INFO, "regular expression: the pattern is empty or undefined.\n"); 149 return 1; 150 } 151 pattern=(char*)malloc(b.endnext-b.begin); 152 if (pattern==NULL) { 153 log_expr(exprobj,TMPL_LOG_ERROR, "regular expression: memory allocation failed.\n"); 154 return 0; 155 } 156 strncpy(pattern, b.begin, (b.endnext-b.begin)); 157 *(pattern+(b.endnext-b.begin))=0; 158 re = pcre_compile(pattern, 0, &error, &erroffset, NULL); /* default character set */ 159 free(pattern); 160 if (re==NULL) { 161 log_expr(exprobj,TMPL_LOG_ERROR, "regular expression: PCRE compilation failed at offset %d: %s\n", 162 erroffset, error); 163 return 0; 164 } 165 rc=pcre_exec(re, NULL, subject, subject_length, 0, 0, ovector, 30); 166 return (rc<0)?0:1; 167} 168#endif 169