summaryrefslogtreecommitdiff
path: root/agen5/cgi-fsm.c
diff options
context:
space:
mode:
Diffstat (limited to 'agen5/cgi-fsm.c')
-rw-r--r--agen5/cgi-fsm.c323
1 files changed, 323 insertions, 0 deletions
diff --git a/agen5/cgi-fsm.c b/agen5/cgi-fsm.c
new file mode 100644
index 0000000..6965d79
--- /dev/null
+++ b/agen5/cgi-fsm.c
@@ -0,0 +1,323 @@
+/* -*- buffer-read-only: t -*- vi: set ro:
+ *
+ * DO NOT EDIT THIS FILE (cgi-fsm.c)
+ *
+ * It has been AutoGen-ed August 11, 2012 at 09:41:35 AM by AutoGen 5.16.2pre7
+ * From the definitions cgi.def
+ * and the template file fsm
+ *
+ * Automated Finite State Machine
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name ``Bruce Korb'' nor the name of any other
+ * contributor may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * AutoFSM IS PROVIDED BY Bruce Korb ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL Bruce Korb OR ANY OTHER CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#define DEFINE_FSM
+#include "cgi-fsm.h"
+#include <stdio.h>
+
+/*
+ * Do not make changes to this file, except between the START/END
+ * comments, or it will be removed the next time it is generated.
+ */
+/* START === USER HEADERS === DO NOT CHANGE THIS COMMENT */
+
+#include "autogen.h"
+
+/* END === USER HEADERS === DO NOT CHANGE THIS COMMENT */
+
+#ifndef NULL
+# define NULL 0
+#endif
+
+/*
+ * Enumeration of the valid transition types
+ * Some transition types may be common to several transitions.
+ */
+typedef enum {
+ CGI_TR_INVALID,
+ CGI_TR_NAME_EQUAL,
+ CGI_TR_SEPARATE,
+ CGI_TR_STASH,
+ CGI_TR_VALUE_ESCAPE
+} te_cgi_trans;
+#define CGI_TRANSITION_CT 5
+
+/**
+ * State transition handling map. Map the state enumeration and the event
+ * enumeration to the new state and the transition enumeration code (in that
+ * order). It is indexed by first the current state and then the event code.
+ */
+typedef struct cgi_transition t_cgi_transition;
+struct cgi_transition {
+ te_cgi_state next_state;
+ te_cgi_trans transition;
+};
+static const t_cgi_transition
+cgi_trans_table[ CGI_STATE_CT ][ CGI_EVENT_CT ] = {
+
+ /* STATE 0: CGI_ST_INIT */
+ { { CGI_ST_NAME, CGI_TR_STASH }, /* EVT: ALPHA */
+ { CGI_ST_INVALID, CGI_TR_INVALID }, /* EVT: NAME_CHAR */
+ { CGI_ST_INVALID, CGI_TR_INVALID }, /* EVT: = */
+ { CGI_ST_INVALID, CGI_TR_INVALID }, /* EVT: + */
+ { CGI_ST_INVALID, CGI_TR_INVALID }, /* EVT: % */
+ { CGI_ST_INVALID, CGI_TR_INVALID }, /* EVT: OTHER */
+ { CGI_ST_INVALID, CGI_TR_INVALID }, /* EVT: & */
+ { CGI_ST_INVALID, CGI_TR_INVALID } /* EVT: END */
+ },
+
+
+ /* STATE 1: CGI_ST_NAME */
+ { { CGI_ST_NAME, CGI_TR_STASH }, /* EVT: ALPHA */
+ { CGI_ST_NAME, CGI_TR_STASH }, /* EVT: NAME_CHAR */
+ { CGI_ST_VALUE, CGI_TR_NAME_EQUAL }, /* EVT: = */
+ { CGI_ST_INVALID, CGI_TR_INVALID }, /* EVT: + */
+ { CGI_ST_INVALID, CGI_TR_INVALID }, /* EVT: % */
+ { CGI_ST_INVALID, CGI_TR_INVALID }, /* EVT: OTHER */
+ { CGI_ST_INVALID, CGI_TR_INVALID }, /* EVT: & */
+ { CGI_ST_INVALID, CGI_TR_INVALID } /* EVT: END */
+ },
+
+
+ /* STATE 2: CGI_ST_VALUE */
+ { { CGI_ST_VALUE, CGI_TR_STASH }, /* EVT: ALPHA */
+ { CGI_ST_VALUE, CGI_TR_STASH }, /* EVT: NAME_CHAR */
+ { CGI_ST_VALUE, CGI_TR_STASH }, /* EVT: = */
+ { CGI_ST_VALUE, CGI_TR_STASH }, /* EVT: + */
+ { CGI_ST_VALUE, CGI_TR_VALUE_ESCAPE }, /* EVT: % */
+ { CGI_ST_VALUE, CGI_TR_STASH }, /* EVT: OTHER */
+ { CGI_ST_INIT, CGI_TR_SEPARATE }, /* EVT: & */
+ { CGI_ST_DONE, CGI_TR_SEPARATE } /* EVT: END */
+ }
+};
+
+
+#define CgiFsmErr_off 19
+#define CgiEvInvalid_off 75
+#define CgiStInit_off 83
+
+
+static char const zCgiStrings[133] =
+/* 0 */ "** OUT-OF-RANGE **\0"
+/* 19 */ "FSM Error: in state %d (%s), event %d (%s) is invalid\n\0"
+/* 75 */ "invalid\0"
+/* 83 */ "init\0"
+/* 88 */ "name\0"
+/* 93 */ "value\0"
+/* 99 */ "alpha\0"
+/* 105 */ "name_char\0"
+/* 115 */ "=\0"
+/* 117 */ "+\0"
+/* 119 */ "%\0"
+/* 121 */ "other\0"
+/* 127 */ "&\0"
+/* 129 */ "end";
+
+static const size_t aszCgiStates[3] = {
+ 83, 88, 93 };
+
+static const size_t aszCgiEvents[9] = {
+ 99, 105, 115, 117, 119, 121, 127, 129, 75 };
+
+
+#define CGI_EVT_NAME(t) ( (((unsigned)(t)) >= 9) \
+ ? zCgiStrings : zCgiStrings + aszCgiEvents[t])
+
+#define CGI_STATE_NAME(s) ( (((unsigned)(s)) >= 3) \
+ ? zCgiStrings : zCgiStrings + aszCgiStates[s])
+
+#ifndef EXIT_FAILURE
+# define EXIT_FAILURE 1
+#endif
+
+static int cgi_invalid_transition( te_cgi_state st, te_cgi_event evt );
+
+/* * * * * * * * * THE CODE STARTS HERE * * * * * * * *
+ *
+ * Print out an invalid transition message and return EXIT_FAILURE
+ */
+static int
+cgi_invalid_transition( te_cgi_state st, te_cgi_event evt )
+{
+ /* START == INVALID TRANS MSG == DO NOT CHANGE THIS COMMENT */
+ char* pz = aprf( zCgiStrings + CgiFsmErr_off, st, CGI_STATE_NAME( st ),
+ evt, CGI_EVT_NAME( evt ));
+
+ AG_ABEND( aprf(CGI_PARSE_ERR_FMT, pz ));
+ /* END == INVALID TRANS MSG == DO NOT CHANGE THIS COMMENT */
+
+ return EXIT_FAILURE;
+}
+
+/**
+ * Run the FSM. Will return CGI_ST_DONE or CGI_ST_INVALID
+ */
+te_cgi_state
+cgi_run_fsm(
+ char const* pzSrc,
+ int inlen,
+ char* pzOut,
+ int outlen )
+{
+ te_cgi_state cgi_state = CGI_ST_INIT;
+ te_cgi_event trans_evt;
+ te_cgi_state nxtSt;
+ te_cgi_trans trans;
+ char const* saved_pzSrc = pzSrc;
+ int saved_inlen = inlen;
+ char* saved_pzOut = pzOut;
+ int saved_outlen = outlen;
+ (void)saved_pzSrc;
+ (void)saved_inlen;
+ (void)saved_pzOut;
+ (void)saved_outlen;
+
+ while (cgi_state < CGI_ST_INVALID) {
+
+ /* START == FIND TRANSITION == DO NOT CHANGE THIS COMMENT */
+
+ char curCh;
+ if (--inlen < 0) {
+ trans_evt = CGI_EV_END;
+ curCh = NUL;
+
+ } else {
+ if (outlen < 4) {
+ static char const exhaustion[] = "output space exhausted\n";
+ if (saved_outlen > (int)sizeof(exhaustion))
+ memcpy(saved_pzOut, exhaustion, sizeof(exhaustion));
+
+ return CGI_ST_INVALID;
+ }
+ curCh = *(pzSrc++);
+ if (IS_ALPHABETIC_CHAR( curCh ))
+ trans_evt = CGI_EV_ALPHA;
+ else if (IS_DEC_DIGIT_CHAR( curCh ))
+ trans_evt = CGI_EV_NAME_CHAR;
+ else switch (curCh) {
+ case '_': trans_evt = CGI_EV_NAME_CHAR; break;
+ case '=': trans_evt = CGI_EV_EQUAL; break;
+ case '+': trans_evt = CGI_EV_SPACE; curCh = ' '; break;
+ case '%': trans_evt = CGI_EV_ESCAPE; break;
+ case '&': trans_evt = CGI_EV_SEPARATOR; break;
+ default: trans_evt = CGI_EV_OTHER; break;
+ }
+ }
+
+ /* END == FIND TRANSITION == DO NOT CHANGE THIS COMMENT */
+
+#ifndef __COVERITY__
+ if (trans_evt >= CGI_EV_INVALID) {
+ nxtSt = CGI_ST_INVALID;
+ trans = CGI_TR_INVALID;
+ } else
+#endif /* __COVERITY__ */
+ {
+ const t_cgi_transition* pTT =
+ cgi_trans_table[ cgi_state ] + trans_evt;
+ nxtSt = pTT->next_state;
+ trans = pTT->transition;
+ }
+
+
+ switch (trans) {
+ case CGI_TR_INVALID:
+ /* START == INVALID == DO NOT CHANGE THIS COMMENT */
+ exit( cgi_invalid_transition( cgi_state, trans_evt ));
+ /* END == INVALID == DO NOT CHANGE THIS COMMENT */
+ break;
+
+
+ case CGI_TR_NAME_EQUAL:
+ /* START == NAME_EQUAL == DO NOT CHANGE THIS COMMENT */
+ strcpy( pzOut, "='" );
+ outlen -= 2;
+ pzOut += 2;
+ /* END == NAME_EQUAL == DO NOT CHANGE THIS COMMENT */
+ break;
+
+
+ case CGI_TR_SEPARATE:
+ /* START == SEPARATE == DO NOT CHANGE THIS COMMENT */
+ strcpy( pzOut, "';\n" );
+ outlen -= 2;
+ pzOut += 3;
+ /* END == SEPARATE == DO NOT CHANGE THIS COMMENT */
+ break;
+
+
+ case CGI_TR_STASH:
+ /* START == STASH == DO NOT CHANGE THIS COMMENT */
+ *(pzOut++) = curCh;
+ outlen--;
+ /* END == STASH == DO NOT CHANGE THIS COMMENT */
+ break;
+
+
+ case CGI_TR_VALUE_ESCAPE:
+ /* START == VALUE_ESCAPE == DO NOT CHANGE THIS COMMENT */
+ {
+ char z[4];
+ if (inlen < 2)
+ exit( cgi_invalid_transition( cgi_state, trans_evt ));
+
+ z[0] = *(pzSrc++);
+ z[1] = *(pzSrc++);
+ z[2] = NUL;
+ inlen -= 2;
+
+ /*
+ * We must backslash quote certain characters that are %-quoted
+ * in the input string:
+ */
+ switch (*(pzOut++) = (int)strtol( z, NULL, 16 )) {
+ case '\'':
+ case '\\':
+ case '#':
+ pzOut[0] = pzOut[-1];
+ pzOut[-1] = '\\';
+ pzOut++;
+ }
+ }
+ /* END == VALUE_ESCAPE == DO NOT CHANGE THIS COMMENT */
+ break;
+
+
+ default:
+ /* START == BROKEN MACHINE == DO NOT CHANGE THIS COMMENT */
+ exit( cgi_invalid_transition( cgi_state, trans_evt ));
+ /* END == BROKEN MACHINE == DO NOT CHANGE THIS COMMENT */
+ }
+
+ cgi_state = nxtSt;
+ }
+ return cgi_state;
+}
+/*
+ * Local Variables:
+ * mode: C
+ * c-file-style: "stroustrup"
+ * indent-tabs-mode: nil
+ * End:
+ * end of cgi-fsm.c */