#!/usr/bin/env perl ######### # fa.cgi - finite automata web engine # $Id: fa.cgi 20288 2008-02-06 23:42:42Z mahoney $ ######### use strict; use warnings; use CGI qw(param); use CGI::Carp qw(fatalsToBrowser); use IO::All qw(io); print "Content-type: text/html\n\n"; print page_html(); exit; # =========================================================== sub page_html { my $script = 'fa.cgi'; my $sample = '_sample'; my $page_template = 'template.html'; my $finite_automata = pwd() . '/finite_automata'; my $submit = param('submit') || ''; my $reset = $submit =~ m/reset/; (my $file = param('file') || param('filesubmit') || $sample) =~ s/\.fa$//; $file = $sample if $reset; if (param('newfile')){ ($file = param('newfile')) =~ s/\..*$//; # remove trailing .fa extension $file=lc($file); # lowercase $file =~ s/[^a-z0-9_]//g; # only a-z 0-9 _ chars } my $fa_input_file = $file . '.fa'; my $fa_output_file = $file . '.txt'; my $fa_input = param('fa_input') || get_file($fa_input_file) || sample_fa(); $fa_input = sample_fa() if $reset; for ($fa_input){ s/\x0D\x0A|\x0D/\n/g; # unix line endings s/\s*\n/\n/sg; # no trailing whitespace (makes YAML unhappy) } $fa_input .= "\n"; # make sure it ends in a newline. if (param('submit') =~ m/save as _sample/){ $file = '_sample'; $fa_input_file = '_sample.fa'; $fa_output_file = '_sample.txt'; } put_file($fa_input_file, $fa_input); `$finite_automata --diagram $fa_input_file > $fa_output_file 2>&1`; my $fa_output = get_file($fa_output_file); my $choices = join ' | ', map {qq($_)} sort glob "*.fa"; $choices =~ s/\.fa"/"/g; my %replace = ( file => $file, choices => $choices, fa_output => $fa_output, fa_input => $fa_input, ); (my $page_html=io($page_template)->all) =~ s[\$(\w+)] [ $replace{$1} || '$' . $1 ]ge; if ($reset){ $page_html =~ s{}{}; } return $page_html; } # Usage: $text = get_file('filename'); sub get_file { my ($filename) = @_; my $text = ''; eval { $text = io($filename)->all }; return $text; } # Usage: put_file('filename', $text); sub put_file { my ($filename, $text) = @_; eval { io($filename)->print($text) }; } sub sample_fa { return q( # # This is a *.fa (i.e. finite automata) definition file # which follows the yaml.org data format. # The ~ character is used to refer to the empty string. # The automata below is non-deterministic, since both # ~ and lists of symbols are used in the transition table. # start: s accept: [ q0, r0 ] transitions : # state x alpha -> state - [ s, ~, q0 ] - [ s, ~, r0 ] - [ q0, 1, q1 ] - [ q1, 1, q0 ] - [ r0, [0,1], r1 ] - [ r1, [0,1], r2 ] - [ r2, [0,1], r0 ] tests : - [ yes, ~ ] - [ no, 00000 ] - [ yes, 1111 ] - [ no, 1010 ] - [ yes, 111000 ] ); } # Usage: $pwd = pwd; sub pwd { chomp(my $pwd = `/bin/pwd`); return $pwd; }