Home Libraries Author Links

matchtst.c

This example is an interactive console C program demonstrating the usage and testing the implementation of pattern matching in strings by means of regular expressions (see Match: Pattern Matching with Regular Expressions).

/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is the SysToMath C Libraries package (LibStmC).
 *
 * The Initial Developer of the Original Code is
 * Tom Michaelis, SysToMath.
 * Portions created by the Initial Developer are Copyright (C) 1989-2006
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

/******************************************************************************
 *                       First Release 1989-03-17
 ******************************************************************************/


const char *Copyright = "(C) 1989-2006 Tom Michaelis, SysToMath";
const char *Version   = "1.12-r341";

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stm/dvec.h>
#include <stm/match.h>


static void defsreact (StmReCtrl reCtrl);


static int incLineNumber (StmMtcFctCmd cmd, StmQreMtc qreMtc);


static int out (StmMtcFctCmd cmd, StmQreMtc qreMtc);


static int printIdent (StmMtcFctCmd cmd, StmReMtc reMtc);


static char *mkCtrl (char *str);


typedef struct MatchTstEnv MatchTstEnv;


struct MatchTstEnv
{
    int lnr;   
};


int main (int argc, char **argv);


int main (int argc, char **argv)
{
    char *prog = argv [0];
    char *str = NULL;                  /* String to match.           */
    char *reStr = NULL;                /* Regular expression string. */
    int ret;
    MatchTstEnv env;
    StmReCtrl reCtrl = NULL;
    StmRe re = NULL;
    jmp_buf envbuf;
    if (! (ret = setjmp (envbuf)))
    {
        reCtrl = stmReCtrlCreate (stderr, &envbuf, NULL, NULL);
        defsreact (reCtrl);

        /* Begin of the execution loop. */
        while (StmTrue)
        {
            /*
             * Input of the string to match.  It can contain newline, tab,
             * carriage return and form feed charcters as \\n, \\t, \\r and
             * \\f, respectively.  A single "q" causes the loop to be left.
             */
            printf ("String: ");
            str = stmFgetDstr (stdin, str, StmFgdStripNl, StmFgdNew);
            if (strcmp (str, "q") == 0) break;
            str = mkCtrl (str);

            /*
             * Input of the regular expression string to match.  It can contain
             * newline, tab, carriage return and form feed charcters as \\n,
             * \\t, \\r and \\f, respectively.
             */
            printf ("Re:     ");
            reStr = stmFgetDstr (stdin, reStr, StmFgdStripNl, StmFgdNew);
            reStr = mkCtrl (reStr);

            /* Generation of the named regular expression \b test. */
            re = stmReCreate (reCtrl, "test", reStr, NULL);

            /*
             * Matching operation by means of the function stmReMatch().
             * The matching result is printed. On error an according error
             * message is printed.
             */
            env.lnr = 1;
            printf ("success = %s\n",
                    stmReMatch (re, str, &env, NULL) ? "true" : "false");

            /*
             * Output of the line number counter implemented by the action
             * \b inclnr.
             */
            printf ("Last Line Number = %d\n\n", env.lnr);

            stmReDestroy (re);
            re = NULL;
        }
    }
    else
    {
        fprintf (stderr, "%s: %s\n", prog, stmReCtrlGetErrorMsg (reCtrl));
    }

    /* Program end. */
    stmReDestroy (re);
    stmReCtrlDestroy (reCtrl);
    stmDvecFree (str);
    stmDvecFree (reStr);
    return ret;
}


static void defsreact (StmReCtrl reCtrl)
{
    stmReCreate (reCtrl,
                 "ident",
                 "[_a-zA-Z][_0-9a-zA-Z]*",
                 printIdent);
    stmReCreate (reCtrl,
                 "nl",
                 "\n+:inclnr:",
                 NULL);
    stmReCreate (reCtrl,
                 "blank",
                 "[ \t]+",
                 NULL);
    stmReCreate (reCtrl,
                 "ws",
                 "(&blank&||&comm&||&nl&)*",
                 NULL);
    stmReCreate (reCtrl,
                 "comm",
                 "%/%*([^*\n]*(%**)([^/\n]|&nl&))*([^*\n]|&nl&)*%*+%/",
                 NULL);
    stmReCreate (reCtrl,
                 "subtext",
                 "&xy&:out:&ident&:out:",
                 NULL);
    stmReCreate (reCtrl,
                 "text",
                 "&subtext&:out:",
                 NULL);
    stmReCreate (reCtrl,
                 "xy",
                 "x|y",
                 NULL);
    stmReCreate (reCtrl,
                 "e",
                 "[^.]|&e&%.",
                 NULL);
    stmReCreate (reCtrl,
                 "a",
                 "[^.]&a&|%.",
                 NULL);
    stmQreActDef (reCtrl, "inclnr", incLineNumber);
    stmQreActDef (reCtrl, "out", out);
    return;
}


static int incLineNumber (StmMtcFctCmd cmd, StmQreMtc qreMtc)
{
    if (cmd.action)
    {
        MatchTstEnv *env = (MatchTstEnv *) stmQreMtcEnv (qreMtc);
        env -> lnr += stmQreMtcSimpleReMtcCount (qreMtc);
        printf ("incLineNumber: lnr = %d\n", env -> lnr);
    }
    return 0;
}


static int out (StmMtcFctCmd cmd, StmQreMtc qreMtc)
{
    if (cmd.action)
    {
        printf ("out: len = %d, q = %d, str = {%.*s}\n",
                stmQreMtcLen (qreMtc), stmQreMtcSimpleReMtcCount (qreMtc),
                stmQreMtcLen (qreMtc), stmQreMtcStr (qreMtc));
    }
    return 0;
}


static int printIdent (StmMtcFctCmd cmd, StmReMtc reMtc)
{
    if (cmd.action)
    {
        printf ("printIdent: %.*s\n",
                stmReMtcLen (reMtc), stmReMtcStr (reMtc));
    }
    return 0;
}


static char *mkCtrl (char *str)
{
    int i;
    for (i = 0; str [i]; i ++)
    {
        if (str [i] == '\\')
        {
            char ch;
            switch (str [i + 1])
            {
            case 'n' :
                ch = '\n';
                break;
            case 't' :
                ch = '\t';
                break;
            case 'r' :
                ch = '\r';
                break;
            case 'f' :
                ch = '\f';
                break;
            default :
                ch = str [i + 1];
                break;
            }
            str [i] = ch;
            str = stmDstrDel (str, i + 1, 1);
        }
    }
    return str;
}

© Copyright Tom Michaelis 2002-2007

Distributed under the SysToMath Software License (See the accompanying file license.txt or a copy at www.SysToMath.com).