Skip to content
Snippets Groups Projects
Select Git revision
  • a16aad66640b858aa47e11eb449828e95f7b0e89
  • master default protected
  • 9.0
  • 8.0
  • nt-tools
  • 7.8
  • 7.6
  • 7.4
  • 7.2
  • 7.0
  • 0.6
  • rosuav/latex-markdown-renderer
  • rxnpatch/rxnpatch
  • marcus/gobject-introspection
  • rxnpatch/8.0
  • rosuav/pre-listening-ports
  • rosuav/async-annotations
  • rosuav/pgsql-ssl
  • rxnpatch/rxnpatch-broken/2023-10-06T094250
  • grubba/fdlib
  • grubba/wip/sakura/8.0
  • v8.0.2020
  • v8.0.2018
  • v8.0.2016
  • v8.0.2014
  • v8.0.2012
  • v8.0.2008
  • v8.0.2006
  • v8.0.2004
  • v8.0.2002
  • v8.0.2000
  • v8.0.1998
  • v8.0.1996
  • v8.0.1994
  • v8.0.1992
  • v8.0.1990
  • v8.0.1988
  • v8.0.1986
  • rxnpatch/clusters/8.0/2025-04-29T124414
  • rxnpatch/2025-04-29T124414
  • v8.0.1984
41 results

glue.c

Blame
  • user avatar
    Fredrik Hübinette (Hubbe) authored
    Rev: src/modules/Regexp/glue.c:1.3
    Rev: src/modules/Regexp/pike_regexp.c:1.3
    Rev: src/modules/Regexp/pike_regexp.h:1.2
    21ba565f
    History
    glue.c 4.02 KiB
    /*\
    ||| This file a part of Pike, and is copyright by Fredrik Hubinette
    ||| Pike is distributed as GPL (General Public License)
    ||| See the files COPYING and DISCLAIMER for more information.
    \*/
    
    #ifdef HAVE_CONFIG_H
    #include "config.h"
    #endif /* HAVE_CONFIG_H */
    
    #include "global.h"
    #include "types.h"
    #include "interpret.h"
    #include "svalue.h"
    #include "stralloc.h"
    #include "array.h"
    #include "object.h"
    #include "macros.h"
    #include "threads.h"
    
    #ifdef USE_SYSTEM_REGEXP
    #include <regexp.h>
    
    struct regexp_glue
    {
      regex_t regexp;
      int num_paren;
    };
    #else
    #include <pike_regexp.h>
    
    struct regexp_glue
    {
      struct regexp *regexp;
    };
    
    #endif /* USE_SYSTEM_REGEXP */
    
    
    #define THIS ((struct regexp_glue *)(fp->current_storage))
    
    static void do_free()
    {
      if(THIS->regexp)
      {
    #ifdef USE_SYSTEM_REGEXP
        regfree(&(THIS->regexp));
    #else
        free((char *)THIS->regexp);
        THIS->regexp=0;
    #endif /* USE_SYSTEM_REGEXP */
      }
    }
    
    static void regexp_create(INT32 args)
    {
      const char *str;
    
      do_free();
      if(args)
      {
        get_all_args("Regexp.regexp->create", args, "%s", &str);
    
    #ifdef USE_SYSTEM_REGEXP
        {
          int err = regcomp(&(THIS->regexp), str, 0);
          int i;
          char *paren_ptr;
    
          if (err) {
    	char buf[1024];
    
    	regerror(err, &(THIS->regexp), buf, 1024);
    	error("Regexp.regexp->create(): Compilation failed:%s\n", buf);
          }
          for (i=0,paren_ptr=str; paren_ptr = strchr(paren_ptr, '('); i++) {
    	paren_ptr++;
          }
          THIS->num_paren = i;
        }
    #else
        THIS->regexp=pike_regcomp(sp[-args].u.string->str, 0);
    #endif
      }
    }
    
    static void regexp_match(INT32 args)
    {
      int i;
      char *str;
    #ifdef USE_SYSTEM_REGEXP
      regex_t *regexp = &(THIS->regexp);
    #else
      struct regexp *regexp = THIS->regexp;
    #endif /* USE_SYSTEM_REGEXP */
    
      get_all_args("Regexp.regexp->match", args, "%s", &str);
      
    #ifdef USE_SYSTEM_REGEXP
      ALLOW_THREADS();
      i = !regexec(regexp, str, 0, NULL, 0);
      DISALLOW_THREADS();
    #else
      i=pike_regexec(regexp, str);
    #endif /* USE_SYSTEM_REGEXP */
      pop_n_elems(args);
      push_int(i);
    }
    
    static void regexp_split(INT32 args)
    {
      struct pike_string *s;
    #ifdef USE_SYSTEM_REGEXP
      regex_t *r;
      regmatch_t *pmatch;
      size_t nmatch;
      int match;
    #else  
      struct regexp *r;
    #endif /* USE_SYSTEM_REGEXP */
    
      get_all_args("Regexp.regexp->split", args, "%S", &s);
    
    #ifdef USE_SYSTEM_REGEXP
      r = &(THIS->regexp);
      nmatch = THIS->num_paren+1;
      pmatch = xalloc(sizeof(regmatch_t)*nmatch);
    
      THREADS_ALLOW();
      match = !regexec(r, s->str, nmatch, pmatch, 0);
      THREADS_DISALLOW();
    
      if (match) {
        int i,j;
        
        s->refs++;
        pop_n_elems(args);
    
        for (i=1; i < nmatch; i++) {
          if (pmatch[i].rm_sp && pmatch[i].rm_so != -1) {
    	push_string(make_shared_binary_string(pmatch[i].rm_sp,
    					      pmatch[i].rm_eo-pmatch[i].rm_so));
          } else {
    	push_int(0);
          }
        }
        f_aggregate_array(nmatch-1);
        free_string(s);
      } else {
        pop_n_elems(args);
        push_int(0);
      }
    #else
      if(pike_regexec(r=THIS->regexp, s->str))
      {
        int i,j;
        s->refs++;
        pop_n_elems(args);
        for(j=i=1;i<NSUBEXP;i++)
        {
          if(!r->startp[i] || !r->endp[i])
          {
    	push_int(0);
          }else{
    	push_string(make_shared_binary_string(r->startp[i],
    					      r->endp[i]-r->startp[i]));
    	j=i;
          }
        }
        if(j<i-1) pop_n_elems(i-j-1);
        push_array(aggregate_array(j));
        free_string(s);
      }else{
        pop_n_elems(args);
        push_int(0);
      }
    #endif /* USE_SYSTEM_REGEXP */
    }
    
    static void init_regexp_glue(struct object *o)
    {
    #ifdef USE_SYSTEM_REGEXP
      MEMCLR(THIS, sizeof(struct regexp_glue));
    #else
      THIS->regexp=0;
    #endif /* USE_SYSTEM_REGEXP */
    }
    
    static void exit_regexp_glue(struct object *o)
    {
      do_free();
    }
    
    
    void pike_module_exit(void) {}
    
    void pike_module_init(void)
    {
      start_new_program();
      add_storage(sizeof(struct regexp_glue));
      
      add_function("create",regexp_create,"function(void|string:void)",0);
      add_function("match",regexp_match,"function(string:int)",0);
      add_function("split",regexp_split,"function(string:string*)",0);
    
      set_init_callback(init_regexp_glue);
      set_exit_callback(exit_regexp_glue);
      end_class("_module_value", 0);
    }