home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / regexx.zip / regexx.c next >
C/C++ Source or Header  |  1999-09-04  |  7KB  |  306 lines

  1. /* regexx.c (emx+gcc) -- Copyright (c) 1994-1995 by Eberhard Mattes */
  2.  
  3. #include <os2emx.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <regexp.h>
  7.  
  8.  
  9. static void regfun (PCSZ name)
  10. {
  11.   RexxRegisterFunctionDll (name, "REGEXX", name);
  12. }
  13.  
  14.  
  15. ULONG regexx_loadfuncs (PCSZ name, LONG argc, const RXSTRING *argv,
  16.                         PCSZ queuename, PRXSTRING retstr)
  17. {
  18.   retstr->strlength = 0;
  19.   if (argc != 0)
  20.     return 1;
  21.   regfun("REGEXXSTART");
  22.   regfun("REGEXXEND");
  23.   regfun("REGEXXSUBSTR");
  24.   regfun("REGEXXREPLACEMATCH");
  25.   regfun("REGEXXREPLACEFIRST");
  26.   regfun("REGEXXREPLACEALL");
  27.   return 0;
  28. }
  29.  
  30.  
  31. void regerror (const char *s)
  32. {
  33. }
  34.  
  35.  
  36. static char *rxstr_alloc (void)
  37. {
  38.   PVOID p;
  39.  
  40.   DosAllocMem (&p, 0xf000, PAG_READ | PAG_WRITE | PAG_COMMIT);
  41.   return p;
  42. }
  43.  
  44.  
  45. /* RegexxStart(REGEXP, STRING)
  46.  
  47.    Find REGEXP in STRING and return the start position of the match.
  48.  
  49.    Return values:
  50.      0          No match
  51.      1, 2, ...  Position in STRING of the start of the first match */
  52.  
  53. ULONG regexx_start (PCSZ name, LONG argc, const RXSTRING *argv,
  54.                     PCSZ queuename, PRXSTRING retstr)
  55. {
  56.   regexp *r;
  57.   char *s;
  58.   int n;
  59.  
  60.   retstr->strlength = 0;
  61.   if (argc != 2 || RXNULLSTRING (argv[0]) || RXNULLSTRING (argv[1]))
  62.     return 1;
  63.  
  64.   r = regcomp (RXSTRPTR (argv[0]));
  65.   if (r == NULL)
  66.     n = -1;
  67.   else
  68.     {
  69.       s = RXSTRPTR (argv[1]);
  70.       if (regexec (r, s) == 0)
  71.         n = 0;
  72.       else
  73.         n = (r->startp[0] - s) + 1;
  74.       free (r);
  75.     }
  76.   _itoa (n, retstr->strptr, 10);
  77.   retstr->strlength = strlen (retstr->strptr);
  78.   return 0;
  79. }
  80.  
  81.  
  82. /* RegexxEnd(REGEXP, STRING)
  83.  
  84.    Find REGEXP in STRING and return the end position of the match.
  85.  
  86.    Return values:
  87.      0          No match
  88.      1, 2, ...  Position in STRING of the end of the first match */
  89.  
  90. ULONG regexx_end (PCSZ name, LONG argc, const RXSTRING *argv,
  91.                   PCSZ queuename, PRXSTRING retstr)
  92. {
  93.   regexp *r;
  94.   char *s;
  95.   int n;
  96.  
  97.   retstr->strlength = 0;
  98.   if (argc != 2 || RXNULLSTRING (argv[0]) || RXNULLSTRING (argv[1]))
  99.     return 1;
  100.  
  101.   r = regcomp (RXSTRPTR (argv[0]));
  102.   if (r == NULL)
  103.     n = -1;
  104.   else
  105.     {
  106.       s = RXSTRPTR (argv[1]);
  107.       if (regexec (r, s) == 0)
  108.         n = 0;
  109.       else
  110.         n = r->endp[0] - s;
  111.       free (r);
  112.     }
  113.   _itoa (n, retstr->strptr, 10);
  114.   retstr->strlength = strlen (retstr->strptr);
  115.   return 0;
  116. }
  117.  
  118.  
  119. /* RegexxSubstr(REGEXP, STRING)
  120.  
  121.    Find REGEXP in STRING and return the matching substring.  Return
  122.    the empty string if there is no match. */
  123.  
  124. ULONG regexx_substr (PCSZ name, LONG argc, const RXSTRING *argv,
  125.                      PCSZ queuename, PRXSTRING retstr)
  126. {
  127.   regexp *r;
  128.   char *s;
  129.   int n;
  130.   size_t len;
  131.  
  132.   retstr->strlength = 0;
  133.   if (argc != 2 || RXNULLSTRING (argv[0]) || RXNULLSTRING (argv[1]))
  134.     return 1;
  135.  
  136.   r = regcomp (RXSTRPTR (argv[0]));
  137.   if (r == NULL)
  138.     retstr->strlength = 0;
  139.   else
  140.     {
  141.       s = RXSTRPTR (argv[1]);
  142.       if (regexec (r, s) != 0)
  143.         {
  144.           len = r->endp[0] - r->startp[0];
  145.           if (len > RXAUTOBUFLEN)
  146.             retstr->strptr = rxstr_alloc ();
  147.           memcpy (retstr->strptr, r->startp[0], len);
  148.           retstr->strlength = len;
  149.         }
  150.       free (r);
  151.     }
  152.   return 0;
  153. }
  154.  
  155.  
  156. /* RegexxReplaceMatch(REGEXP, REPLACEMENT, STRING)
  157.  
  158.    Find REGEXP in STRING, replace the matching substring with
  159.    REPLACEMENT, and return that substring. */
  160.  
  161. ULONG regexx_replacematch (PCSZ name, LONG argc, const RXSTRING *argv,
  162.                            PCSZ queuename, PRXSTRING retstr)
  163. {
  164.   regexp *r;
  165.   char *result;
  166.   size_t len;
  167.  
  168.   retstr->strlength = 0;
  169.   if (argc != 3 || RXNULLSTRING (argv[0]) || RXNULLSTRING (argv[1])
  170.       || RXNULLSTRING (argv[2]))
  171.     return 1;
  172.  
  173.   r = regcomp (RXSTRPTR (argv[0]));
  174.   if (r == NULL)
  175.     {
  176.       retstr->strlength = 0;
  177.       return 0;
  178.     }
  179.  
  180.   if (regexec (r, RXSTRPTR (argv[2])) == 0)
  181.     retstr->strlength = 0;
  182.   else
  183.     {
  184.       result = rxstr_alloc ();
  185.       regsub (r, RXSTRPTR (argv[1]), result);
  186.       len = strlen (result);
  187.       if (len <= RXAUTOBUFLEN)
  188.         {
  189.           memcpy (retstr->strptr, result, len);
  190.           retstr->strlength = len;
  191.           DosFreeMem (result);
  192.         }
  193.       else
  194.         MAKERXSTRING (*retstr, result, len);
  195.     }
  196.   free (r);
  197.   return 0;
  198. }
  199.  
  200.  
  201. /* RegexxReplaceFirst(REGEXP, REPLACEMENT, STRING)
  202.  
  203.    Replace the first match of REGEXP in STRING with REPLACEMENT and
  204.    return the resulting string. */
  205.  
  206. ULONG regexx_replacefirst (PCSZ name, LONG argc, const RXSTRING *argv,
  207.                            PCSZ queuename, PRXSTRING retstr)
  208. {
  209.   regexp *r;
  210.  
  211.   retstr->strlength = 0;
  212.   if (argc != 3 || RXNULLSTRING (argv[0]) || RXNULLSTRING (argv[1])
  213.       || RXNULLSTRING (argv[2]))
  214.     return 1;
  215.  
  216.   r = regcomp (RXSTRPTR (argv[0]));
  217.   if (r == NULL)
  218.     {
  219.       retstr->strlength = 0;
  220.       return 0;
  221.     }
  222.  
  223.   if (regexec (r, RXSTRPTR (argv[2])) == 0)
  224.     {
  225.       if (RXSTRLEN (argv[2]) > RXAUTOBUFLEN)
  226.         retstr->strptr =  rxstr_alloc ();
  227.       memcpy (retstr->strptr, RXSTRPTR (argv[2]), RXSTRLEN (argv[2]));
  228.       retstr->strlength = RXSTRLEN (argv[2]);
  229.     }
  230.   else
  231.     {
  232.       char *result;
  233.       size_t pos, len;
  234.  
  235.       result = rxstr_alloc ();
  236.       pos = 0;
  237.       len = (PCH)r->startp[0] - RXSTRPTR (argv[2]);
  238.       memcpy (result + pos, RXSTRPTR (argv[2]), len); pos += len;
  239.       regsub (r, RXSTRPTR (argv[1]), result + pos);
  240.       pos += strlen (result + pos);
  241.       len = RXSTRLEN (argv[2]) - ((PCH)r->endp[0] - RXSTRPTR (argv[2]));
  242.       memcpy (result + pos, r->endp[0], len); pos += len;
  243.       if (pos <= RXAUTOBUFLEN)
  244.         {
  245.           memcpy (retstr->strptr, result, pos);
  246.           retstr->strlength = pos;
  247.           DosFreeMem (result);
  248.         }
  249.       else
  250.         MAKERXSTRING (*retstr, result, pos);
  251.     }
  252.   free (r);
  253.   return 0;
  254. }
  255.  
  256.  
  257. /* RegexxReplaceAll(REGEXP, REPLACEMENT, STRING)
  258.  
  259.    Replace the all matches of REGEXP in STRING with REPLACEMENT and
  260.    return the resulting string. */
  261.  
  262. ULONG regexx_replaceall (PCSZ name, LONG argc, const RXSTRING *argv,
  263.                          PCSZ queuename, PRXSTRING retstr)
  264. {
  265.   regexp *r;
  266.   char *result, *s;
  267.   size_t pos, len;
  268.  
  269.   retstr->strlength = 0;
  270.   if (argc != 3 || RXNULLSTRING (argv[0]) || RXNULLSTRING (argv[1])
  271.       || RXNULLSTRING (argv[2]))
  272.     return 1;
  273.  
  274.   r = regcomp (RXSTRPTR (argv[0]));
  275.   if (r == NULL)
  276.     {
  277.       retstr->strlength = 0;
  278.       return 0;
  279.     }
  280.  
  281.   result = rxstr_alloc ();
  282.   pos = 0;
  283.   s = RXSTRPTR (argv[2]);
  284.   while (regexec (r, s) != 0)
  285.     {
  286.       len = r->startp[0] - s;
  287.       memcpy (result + pos, s, len); pos += len;
  288.       regsub (r, RXSTRPTR (argv[1]), result + pos);
  289.       pos += strlen (result + pos);
  290.       s = r->endp[0];
  291.     }
  292.   len = strlen (s);
  293.   memcpy (result + pos, s, len); pos += len;
  294.   if (pos <= RXAUTOBUFLEN)
  295.     {
  296.       memcpy (retstr->strptr, result, pos);
  297.       retstr->strlength = pos;
  298.       DosFreeMem (result);
  299.     }
  300.   else
  301.     MAKERXSTRING (*retstr, result, pos);
  302.  
  303.   free (r);
  304.   return 0;
  305. }
  306.