kernel: new DEBUG_RACE option. try to provoke race conditions between processes.
[minix.git] / commands / yap / machine.c
blobc6984e1eb7cc7d41e6a9ddc422a6dd0ad5076005
1 /* Copyright (c) 1985 Ceriel J.H. Jacobs */
3 # ifndef lint
4 static char rcsid[] = "$Header$";
5 # endif
7 # define _MACHINE_
9 # include <ctype.h>
10 # include "in_all.h"
11 # include "machine.h"
12 # include "getline.h"
13 # include "assert.h"
16 * Add part of finite state machine to recognize the string s.
19 STATIC int
20 addtomach(s, cnt, list) char *s; struct state **list; {
22 register struct state *l;
23 register int i = FSM_OKE; /* Return value */
24 register int j;
26 for (;;) {
27 l = *list;
28 if (!l) {
30 * Create new list element
32 *list = l = (struct state *) alloc(sizeof(*l), 0);
33 l->s_char = *s;
34 l->s_endstate = 0;
35 l->s_match = 0;
36 l->s_next = 0;
38 if (l->s_char == *s) {
40 * Continue with next character
42 if (!*++s) {
44 * No next character
46 j = l->s_endstate;
47 l->s_endstate = 1;
48 if (l->s_match || j) {
50 * If the state already was an endstate,
51 * or has a successor, the currently
52 * added string is a prefix of an
53 * already recognized string
55 return FSM_ISPREFIX;
57 l->s_cnt = cnt;
58 return i;
60 if (l->s_endstate) {
62 * In this case, the currently added string has
63 * a prefix that is an already recognized
64 * string.
66 i = FSM_HASPREFIX;
68 list = &(l->s_match);
69 continue;
71 list = &(l->s_next);
73 /* NOTREACHED */
77 * Add a string to the FSM.
80 int
81 addstring(s,cnt,machine) register char *s; struct state **machine; {
83 if (!s || !*s) {
84 return FSM_ISPREFIX;
86 return addtomach(s,cnt,machine);
90 * Match string s with the finite state machine.
91 * If it matches, the number of characters actually matched is returned,
92 * and the count is put in the word pointed to by i.
93 * If the string is a prefix of a string that could be matched,
94 * FSM_ISPREFIX is returned. Otherwise, 0 is returned.
97 int
98 match(s,i,mach) char *s; int *i; register struct state *mach; {
100 register char *s1 = s; /* Walk through string */
101 register struct state *mach1 = 0;
102 /* Keep track of previous state */
104 while (mach && *s1) {
105 if (mach->s_char == *s1) {
107 * Current character matches. Carry on with next
108 * character and next state
110 mach1 = mach;
111 mach = mach->s_match;
112 s1++;
113 continue;
115 mach = mach->s_next;
117 if (!mach1) {
119 * No characters matched
121 return 0;
123 if (mach1->s_endstate) {
125 * The string matched
127 *i = mach1->s_cnt;
128 return s1 - s;
130 if (!*s1) {
132 * The string matched a prefix
134 return FSM_ISPREFIX;
136 return 0;