[augeas-devel] augeas: master - * examples/fadot.c: tool to generate dot graphs of FA's

David Lutterkort lutter at fedoraproject.org
Fri Mar 20 18:43:01 UTC 2009


Gitweb:        http://git.fedorahosted.org/git/augeas.git?p=augeas.git;a=commitdiff;h=3e77df1886de7a8250a7d8cebb95fc883e9a9ced
Commit:        3e77df1886de7a8250a7d8cebb95fc883e9a9ced
Parent:        afee63affe8b6263644300003a91af5facb758a4
Author:        Francis Giraldeau <francis.giraldeau at revolutionlinux.com>
AuthorDate:    Fri Mar 20 11:41:17 2009 -0700
Committer:     David Lutterkort <lutter at redhat.com>
CommitterDate: Fri Mar 20 11:41:17 2009 -0700

* examples/fadot.c: tool to generate dot graphs of FA's

The fadot tool produces dot graphs of finite automata, and allows certain
operations on FA's from the command line, like intersection and complement
of FA's.
---
 AUTHORS              |    1 +
 Makefile.am          |    2 +-
 configure.ac         |    1 +
 examples/Makefile.am |   13 +++
 examples/examples.sh |   21 +++++
 examples/fadot       |  131 ++++++++++++++++++++++++++++++
 examples/fadot.c     |  214 ++++++++++++++++++++++++++++++++++++++++++++++++++
 7 files changed, 382 insertions(+), 1 deletions(-)

diff --git a/AUTHORS b/AUTHORS
index a530ab1..abd0d9a 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -9,6 +9,7 @@ Contributions by:
   Dominique Dumont <dominique.dumont at hp.com>
   Free Ekanayaka   <free at 64studio.com>
   Marc Fournier    <marc.fournier at camptocamp.com>
+  Francis Giraldeau <francis.giraldeau at revolutionlinux.com>
   Harald Hoyer     <harald at redhat.com>
   Bryan Kearney    <bkearney at redhat.com>
   Jim Meyering     <meyering at redhat.com>
diff --git a/Makefile.am b/Makefile.am
index 7affe4b..33e7d94 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS=gnulib/lib src gnulib/tests tests man doc
+SUBDIRS=gnulib/lib src gnulib/tests tests man doc examples
 
 ACLOCAL_AMFLAGS = -I gnulib/m4
 
diff --git a/configure.ac b/configure.ac
index 5568d52..2ac12ec 100644
--- a/configure.ac
+++ b/configure.ac
@@ -90,6 +90,7 @@ AC_OUTPUT(Makefile \
           src/Makefile \
           man/Makefile \
           tests/Makefile \
+          examples/Makefile \
 	  doc/Makefile \
 	  doc/naturaldocs/Makefile \
           augeas.pc augeas.spec)
diff --git a/examples/Makefile.am b/examples/Makefile.am
new file mode 100644
index 0000000..c5fbd4f
--- /dev/null
+++ b/examples/Makefile.am
@@ -0,0 +1,13 @@
+
+GNULIB= ../gnulib/lib/libgnu.la
+GNULIB_CFLAGS= -I $(top_srcdir)/gnulib/lib
+
+AM_CFLAGS = @AUGEAS_CFLAGS@ @WARN_CFLAGS@ $(GNULIB_CFLAGS) \
+			-I $(top_builddir)/src
+
+bin_PROGRAMS = fadot
+
+fadot_SOURCES = fadot.c 
+fadot_LDADD = $(top_builddir)/src/libaugeas.la $(GNULIB)
+
+
diff --git a/examples/examples.sh b/examples/examples.sh
new file mode 100755
index 0000000..bc78ff4
--- /dev/null
+++ b/examples/examples.sh
@@ -0,0 +1,21 @@
+#!/bin/sh 
+# create some examples of operations on finite automaton
+
+export PATH=./:$PATH
+
+dest=/tmp/fadot-examples
+mkdir -p $dest
+
+fadot -f $dest/sample.dot     -o show         "[a-z]*"
+fadot -f $dest/concat.dot     -o concat       "[a-b]" "[b-c]"
+fadot -f $dest/union.dot      -o union        "[a-b]" "[b-c]"
+fadot -f $dest/intersect.dot  -o intersect    "[a-b]" "[b-c]"
+fadot -f $dest/complement.dot -o complement   "[a-z]"
+fadot -f $dest/minus.dot      -o minus        "[a-z]" "[a-c]" 
+
+
+for i in $(ls -1 $dest/*.dot|cut -d. -f1); do
+    dot -Tpng -o $i.png $i.dot
+done
+
+echo "Example compilation complete. Results are available in directory $dest"
diff --git a/examples/fadot b/examples/fadot
new file mode 100755
index 0000000..59a837a
--- /dev/null
+++ b/examples/fadot
@@ -0,0 +1,131 @@
+#! /bin/sh
+
+# fadot - temporary wrapper script for .libs/fadot
+# Generated by ltmain.sh - GNU libtool 1.5.26 (1.1220.2.493 2008/02/01 16:58:18)
+#
+# The fadot program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='/bin/sed -e 1s/^X//'
+sed_quote_subst='s/\([\\`\\"$\\\\]\)/\\\1/g'
+
+# Be Bourne compatible (taken from Autoconf:_AS_BOURNE_COMPATIBLE).
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+relink_command="(cd /homes/lutter/code/augeas/examples; { test -z \"\${LIBRARY_PATH+set}\" || unset LIBRARY_PATH || { LIBRARY_PATH=; export LIBRARY_PATH; }; }; { test -z \"\${COMPILER_PATH+set}\" || unset COMPILER_PATH || { COMPILER_PATH=; export COMPILER_PATH; }; }; { test -z \"\${GCC_EXEC_PREFIX+set}\" || unset GCC_EXEC_PREFIX || { GCC_EXEC_PREFIX=; export GCC_EXEC_PREFIX; }; }; { test -z \"\${LD_RUN_PATH+set}\" || unset LD_RUN_PATH || { LD_RUN_PATH=; export LD_RUN_PATH; }; }; { test -z \"\${LD_LIBRARY_PATH+set}\" || unset LD_LIBRARY_PATH || { LD_LIBRARY_PATH=; export LD_LIBRARY_PATH; }; }; PATH=\"/homes/lutter/bin:/usr/lib64/qt-3.3/bin:/usr/kerberos/bin:/usr/lib64/ccache:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin\"; export PATH; gcc -std=gnu99 -Wall -Wformat -Wformat-security -Wmissing-prototypes -Wnested-externs -Wpointer-arith -Wextra -Wshadow -Wcast-align -Wwrite-strings -Waggregate-return -Wstrict-prototypes -Winline -Wredundant-decls -Wno-sign-compa
 re -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fasynchronous-unwind-tables -Werror -I ../gnulib/lib -I ../src -g -o \$progdir/\$file fadot.o  ../src/.libs/libaugeas.so /homes/lutter/code/augeas/src/.libs/libfa.so -lselinux ../gnulib/lib/.libs/libgnu.a  -Wl,--rpath -Wl,/homes/lutter/code/augeas/src/.libs -Wl,--rpath -Wl,/data/share/lib ) "
+
+# This environment variable determines our operation mode.
+if test "$libtool_install_magic" = "%%%MAGIC variable%%%"; then
+  # install mode needs the following variable:
+  notinst_deplibs=' ../src/libaugeas.la /homes/lutter/code/augeas/src/libfa.la'
+else
+  # When we are sourced in execute mode, $file and $echo are already set.
+  if test "$libtool_execute_magic" != "%%%MAGIC variable%%%"; then
+    echo="echo"
+    file="$0"
+    # Make sure echo works.
+    if test "X$1" = X--no-reexec; then
+      # Discard the --no-reexec flag, and continue.
+      shift
+    elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
+      # Yippee, $echo works!
+      :
+    else
+      # Restart under the correct shell, and then maybe $echo will work.
+      exec /bin/sh "$0" --no-reexec ${1+"$@"}
+    fi
+  fi
+
+  # Find the directory that this script lives in.
+  thisdir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+  test "x$thisdir" = "x$file" && thisdir=.
+
+  # Follow symbolic links until we get to the real thisdir.
+  file=`ls -ld "$file" | /bin/sed -n 's/.*-> //p'`
+  while test -n "$file"; do
+    destdir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+
+    # If there was a directory component, then change thisdir.
+    if test "x$destdir" != "x$file"; then
+      case "$destdir" in
+      [\\/]* | [A-Za-z]:[\\/]*) thisdir="$destdir" ;;
+      *) thisdir="$thisdir/$destdir" ;;
+      esac
+    fi
+
+    file=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+    file=`ls -ld "$thisdir/$file" | /bin/sed -n 's/.*-> //p'`
+  done
+
+  # Try to get the absolute directory name.
+  absdir=`cd "$thisdir" && pwd`
+  test -n "$absdir" && thisdir="$absdir"
+
+  program=lt-'fadot'
+  progdir="$thisdir/.libs"
+
+  if test ! -f "$progdir/$program" || \
+     { file=`ls -1dt "$progdir/$program" "$progdir/../$program" 2>/dev/null | /bin/sed 1q`; \
+       test "X$file" != "X$progdir/$program"; }; then
+
+    file="$$-$program"
+
+    if test ! -d "$progdir"; then
+      mkdir "$progdir"
+    else
+      rm -f "$progdir/$file"
+    fi
+
+    # relink executable if necessary
+    if test -n "$relink_command"; then
+      if relink_command_output=`eval $relink_command 2>&1`; then :
+      else
+	echo "$relink_command_output" >&2
+	rm -f "$progdir/$file"
+	exit 1
+      fi
+    fi
+
+    mv -f "$progdir/$file" "$progdir/$program" 2>/dev/null ||
+    { rm -f "$progdir/$program";
+      mv -f "$progdir/$file" "$progdir/$program"; }
+    rm -f "$progdir/$file"
+  fi
+
+  if test -f "$progdir/$program"; then
+    if test "$libtool_execute_magic" != "%%%MAGIC variable%%%"; then
+      # Run the actual program with our arguments.
+
+      exec "$progdir/$program" ${1+"$@"}
+
+      $echo "$0: cannot exec $program $*"
+      exit 1
+    fi
+  else
+    # The program doesn't exist.
+    $echo "$0: error: \`$progdir/$program' does not exist" 1>&2
+    $echo "This script is just a wrapper for $program." 1>&2
+    echo "See the libtool documentation for more information." 1>&2
+    exit 1
+  fi
+fi
diff --git a/examples/fadot.c b/examples/fadot.c
new file mode 100644
index 0000000..b44958a
--- /dev/null
+++ b/examples/fadot.c
@@ -0,0 +1,214 @@
+/*
+ * fadot.c: example usage of finite automata library
+ *
+ * Copyright (C) 2009, Francis Giraldeau
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ *
+ * Author: Francis Giraldeau <francis.giraldeau at usherbrooke.ca>
+ */
+
+/*
+ * The purpose of this example is to show the usage of libfa
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <string.h>
+#include <getopt.h>
+
+#include "fa.h"
+
+const char *progname;
+
+__attribute__((noreturn))
+static void usage(void) {
+    fprintf(stderr, "\nUsage: %s [OPTIONS] REGEXP\n", progname);
+    fprintf(stderr, "Compile REGEXP and apply operation on them.\n");
+    fprintf(stderr, "\nOptions:\n\n");
+    fprintf(stderr, "  -o OPERATION		one of : show concat union intersect\n");
+    fprintf(stderr, "  	                         complement minus example\n");
+    fprintf(stderr, "  -f DOT_FILE 		Path of output .dot file\n");
+    fprintf(stderr, "  -n         		do not reduce resulting finite automaton\n");
+
+    exit(EXIT_FAILURE);
+}
+
+int main (int argc, char **argv)
+{
+
+	opterr = 0;
+
+	int reduce = 1;
+	char *file_output = NULL;
+	char *operation = NULL;
+	int i;
+	FILE *fd;
+	int c;
+	int nb_regexp = 0;
+
+	progname = argv[0];
+
+    while ((c = getopt (argc, argv, "nf:o:")) != -1)
+    	switch (c)
+    	{
+    	case 'n':
+    		reduce = 0;
+    		break;
+    	case 'f':
+    		file_output = optarg;
+    		break;
+    	case 'o':
+    		operation = optarg;
+    		break;
+    	case '?':
+    		if (optopt == 'o' || optopt == 'f')
+    			fprintf (stderr, "Option -%c requires an argument.\n", optopt);
+    		else if (isprint (optopt))
+    			fprintf (stderr, "Unknown option `-%c'.\n", optopt);
+    		else
+    			fprintf (stderr,
+    					"Unknown option character `\\x%x'.\n",
+    					optopt);
+    		usage();
+    		break;
+    	default:
+            usage();
+            break;
+    	}
+
+    //printf ("reduce = %d, file_output = %s, operation = %s\n",
+    //        reduce, file_output, operation);
+
+    if (!file_output){
+    	printf("\nPlease specify file output with option -f.\n");
+    	usage();
+    }
+
+    if (!operation){
+    	printf("\nPlease specify an operation with option -o.\n");
+    	usage();
+    }
+
+    for (i = optind; i < argc; i++){
+    	nb_regexp++;
+    }
+
+    if (nb_regexp == 0){
+    	printf("Please specify regexp to process.\n");
+    	usage();
+    }
+
+    struct fa* fa_result = NULL;
+
+    if (!strcmp(operation,"show")){
+    	fa_compile(argv[optind], strlen(argv[optind]), &fa_result);
+    } else if (!strcmp(operation,"concat")){
+
+    	if (nb_regexp < 2){
+    		fprintf(stderr,"Please specify 2 or more regexp to concat");
+    		return 1;
+    	}
+
+    	fa_result = fa_make_basic(FA_EPSILON);
+    	struct fa* fa_tmp;
+    	for (i = optind; i < argc; i++){
+    		fa_compile(argv[i], strlen(argv[i]), &fa_tmp);
+    		fa_result = fa_concat(fa_result, fa_tmp);
+    	}
+
+    } else if (!strcmp(operation, "union")){
+
+    	if (nb_regexp < 2){
+    		fprintf(stderr,"Please specify 2 or more regexp to union");
+    		return 1;
+    	}
+
+    	fa_result = fa_make_basic(FA_EMPTY);
+
+    	struct fa* fa_tmp;
+    	for (i = optind; i < argc; i++){
+    		fa_compile(argv[i], strlen(argv[i]), &fa_tmp);
+    		fa_result = fa_union(fa_result, fa_tmp);
+    	}
+
+    } else if (!strcmp(operation, "intersect")){
+
+        	if (nb_regexp < 2){
+        		fprintf(stderr,"Please specify 2 or more regexp to intersect");
+        		return 1;
+        	}
+
+        	fa_compile(argv[optind], strlen(argv[optind]), &fa_result);
+        	struct fa* fa_tmp;
+
+        	for (i = optind+1; i < argc; i++){
+        		fa_compile(argv[i], strlen(argv[i]), &fa_tmp);
+        		fa_result = fa_intersect(fa_result, fa_tmp);
+        	}
+
+    } else if (!strcmp(operation, "complement")){
+
+    	if (nb_regexp >= 2){
+    		fprintf(stderr,"Please specify one regexp to complement");
+    		return 1;
+    	}
+
+		fa_compile(argv[optind], strlen(argv[optind]), &fa_result);
+		fa_result = fa_complement(fa_result);
+
+    } else if (!strcmp(operation, "minus")){
+
+    	if (nb_regexp != 2){
+    		fprintf(stderr,"Please specify 2 regexp for operation minus");
+    		return 1;
+    	}
+
+    	struct fa* fa_tmp1;
+    	struct fa* fa_tmp2;
+    	fa_compile(argv[optind], strlen(argv[optind]), &fa_tmp1);
+    	fa_compile(argv[optind+1], strlen(argv[optind+1]), &fa_tmp2);
+		fa_result = fa_minus(fa_tmp1, fa_tmp2);
+
+    } else if (!strcmp(operation, "example")){
+
+    	if (nb_regexp != 1){
+    		fprintf(stderr,"Please specify one regexp for operation example");
+    		return 1;
+    	}
+
+    	char* word = NULL;
+    	size_t word_len = 0;
+    	fa_compile(argv[optind], strlen(argv[optind]), &fa_result);
+		fa_example(fa_result, &word, &word_len);
+		printf("Example word = %s\n", word);
+
+    }
+
+    if ((fd = fopen(file_output, "w")) == NULL) {
+        fprintf(stderr, "Error while opening file %s \n", file_output);
+        return 1;
+    }
+
+	if (reduce){
+		fa_minimize(fa_result);
+	}
+
+    fa_dot(fd, fa_result);
+
+    return 0;
+
+}




More information about the augeas-devel mailing list