home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 2002 April / pcpro0402.iso / essentials / graphics / Gimp / gimp-src-20001226.exe / src / gimp / plug-ins / script-fu / interp_regex.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-01-26  |  4.8 KB  |  183 lines

  1. #include <sys/types.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include "regex.h"
  6. #include "siod.h"
  7.  
  8. /* OSF/1 doc says that POSIX and XPG4 include regcomp in libc.
  9.    So we might as well set ourselves up to take advantage of it.
  10.    This functionality is also available in hpux, and is also provided
  11.    by the FSF's librx package, so if you can use that if your
  12.    operating system vendor doesn't supply it.
  13.  */
  14.  
  15. static void
  16. init_regex_version (void)
  17. {
  18.   setvar (cintern ("*regex-version*"),
  19.       cintern ("$Id: interp_regex.c,v 1.7 2000/01/24 22:16:34 yosh Exp $"),
  20.       NIL);
  21. }
  22.  
  23. long tc_regex = 0;
  24.  
  25. struct tc_regex
  26.   {
  27.     int compflag;
  28.     size_t nmatch;
  29.     regex_t *r;
  30.     regmatch_t *m;
  31.   };
  32.  
  33. struct tc_regex *
  34. get_tc_regex (LISP ptr)
  35. {
  36.   if NTYPEP
  37.     (ptr, tc_regex) my_err ("not a regular expression", ptr);
  38.   return ((struct tc_regex *) ptr->storage_as.string.data);
  39. }
  40.  
  41. LISP
  42. regcomp_l (LISP pattern, LISP flags)
  43. {
  44.   long iflag, iflags;
  45.   char *str, errbuff[1024];
  46.   int error;
  47.   LISP result;
  48.   struct tc_regex *h;
  49.   iflags = NNULLP (flags) ? get_c_long (flags) : 0;
  50.   str = get_c_string (pattern);
  51.   iflag = no_interrupt (1);
  52.   result = cons (NIL, NIL);
  53.   h = (struct tc_regex *) must_malloc (sizeof (struct tc_regex));
  54.   h->compflag = 0;
  55.   h->nmatch = 0;
  56.   h->r = NULL;
  57.   h->m = NULL;
  58.   result->type = tc_regex;
  59.   result->storage_as.string.data = (char *) h;
  60.   h->r = (regex_t *) must_malloc (sizeof (regex_t));
  61.   if ((error = regcomp (h->r, str, iflags)))
  62.     {
  63.       regerror (error, h->r, errbuff, sizeof (errbuff));
  64.       return (my_err (errbuff, pattern));
  65.     }
  66.   h->compflag = 1;
  67.   if (iflags & REG_NOSUB)
  68.     {
  69.       no_interrupt (iflag);
  70.       return (result);
  71.     }
  72.   h->nmatch = h->r->re_nsub + 1;
  73.   h->m = (regmatch_t *) must_malloc (sizeof (regmatch_t) * h->nmatch);
  74.   no_interrupt (iflag);
  75.   return (result);
  76. }
  77.  
  78. LISP
  79. regerror_l (LISP code, LISP ptr)
  80. {
  81.   char errbuff[1024];
  82.   regerror (get_c_long (code), get_tc_regex (ptr)->r, errbuff, sizeof (errbuff));
  83.   return (strcons (strlen (errbuff), errbuff));
  84. }
  85.  
  86. LISP
  87. regexec_l (LISP ptr, LISP str, LISP eflags)
  88. {
  89.   size_t j;
  90.   int error;
  91.   LISP result;
  92.   struct tc_regex *h;
  93.   h = get_tc_regex (ptr);
  94.   if ((error = regexec (h->r,
  95.                get_c_string (str),
  96.                h->nmatch,
  97.                h->m,
  98.                NNULLP (eflags) ? get_c_long (eflags) : 0)))
  99.     return (flocons (error));
  100.   for (j = 0, result = NIL; j < h->nmatch; ++j)
  101.     result = cons (cons (flocons (h->m[j].rm_so),
  102.              flocons (h->m[j].rm_eo)),
  103.            result);
  104.   return (nreverse (result));
  105. }
  106.  
  107. void
  108. regex_gc_free (LISP ptr)
  109. {
  110.   struct tc_regex *h;
  111.   if ((h = (struct tc_regex *) ptr->storage_as.string.data))
  112.     {
  113.       if ((h->compflag) && h->r)
  114.     regfree (h->r);
  115.       if (h->r)
  116.     {
  117.       free (h->r);
  118.       h->r = NULL;
  119.     }
  120.       if (h->m)
  121.     {
  122.       free (h->m);
  123.       h->m = NULL;
  124.     }
  125.       free (h);
  126.       ptr->storage_as.string.data = NULL;
  127.     }
  128. }
  129.  
  130. void
  131. regex_prin1 (LISP ptr, struct gen_printio *f)
  132. {
  133.   char buffer[256];
  134.   regex_t *p;
  135.   p = get_tc_regex (ptr)->r;
  136.   sprintf (buffer, "#<REGEX %p nsub=%d",
  137.        p, p->re_nsub);
  138.   gput_st (f, buffer);
  139.   gput_st (f, ">");
  140. }
  141.  
  142. void
  143. init_regex (void)
  144. {
  145.   long j;
  146.   tc_regex = allocate_user_tc ();
  147.   set_gc_hooks (tc_regex,
  148.         NULL,
  149.         NULL,
  150.         NULL,
  151.         regex_gc_free,
  152.         &j);
  153.   set_print_hooks (tc_regex, regex_prin1);
  154.   init_subr_2 ("regcomp", regcomp_l);
  155.   init_subr_2 ("regerror", regerror_l);
  156.   init_subr_3 ("regexec", regexec_l);
  157.   setvar (cintern ("REG_EXTENDED"), flocons (REG_EXTENDED), NIL);
  158.   setvar (cintern ("REG_ICASE"), flocons (REG_ICASE), NIL);
  159.   setvar (cintern ("REG_NOSUB"), flocons (REG_NOSUB), NIL);
  160.   setvar (cintern ("REG_NEWLINE"), flocons (REG_NEWLINE), NIL);
  161.  
  162.   setvar (cintern ("REG_NOTBOL"), flocons (REG_NOTBOL), NIL);
  163.   setvar (cintern ("REG_NOTEOL"), flocons (REG_NOTEOL), NIL);
  164.  
  165.   setvar (cintern ("REG_NOMATCH"), flocons (REG_NOMATCH), NIL);
  166.   setvar (cintern ("REG_BADPAT"), flocons (REG_BADPAT), NIL);
  167.   setvar (cintern ("REG_ECOLLATE"), flocons (REG_ECOLLATE), NIL);
  168.   setvar (cintern ("REG_ECTYPE"), flocons (REG_ECTYPE), NIL);
  169.   setvar (cintern ("REG_EESCAPE"), flocons (REG_EESCAPE), NIL);
  170.   setvar (cintern ("REG_ESUBREG"), flocons (REG_ESUBREG), NIL);
  171.   setvar (cintern ("REG_EBRACK"), flocons (REG_EBRACK), NIL);
  172.   setvar (cintern ("REG_EPAREN"), flocons (REG_EPAREN), NIL);
  173.   setvar (cintern ("REG_EBRACE"), flocons (REG_EBRACE), NIL);
  174.   setvar (cintern ("REG_BADBR"), flocons (REG_BADBR), NIL);
  175.   setvar (cintern ("REG_ERANGE"), flocons (REG_ERANGE), NIL);
  176.   setvar (cintern ("REG_ESPACE"), flocons (REG_ESPACE), NIL);
  177.   setvar (cintern ("REG_BADRPT"), flocons (REG_BADRPT), NIL);
  178. #ifdef REG_ECHAR
  179.   setvar (cintern ("REG_ECHAR"), flocons (REG_ECHAR), NIL);
  180. #endif
  181.   init_regex_version ();
  182. }
  183.