fix possible crash on user deletion
[srvx.git] / rx / rxsimp.c
1 /*      Copyright (C) 1995, 1996 Tom Lord
2  * 
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU Library General Public License as published by
5  * the Free Software Foundation; either version 2, or (at your option)
6  * any later version.
7  * 
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU Library General Public License for more details.
12  * 
13  * You should have received a copy of the GNU Library General Public License
14  * along with this software; see the file COPYING.  If not, write to
15  * the Free Software Foundation, 59 Temple Place - Suite 330, 
16  * Boston, MA 02111-1307, USA. 
17  */
18
19 \f
20
21 #include "rxall.h"
22 #include "rxsimp.h"
23
24 \f
25
26
27 /* Could reasonably hashcons instead of in rxunfa.c */
28
29 #ifdef __STDC__
30 int
31 rx_simple_rexp (struct rexp_node ** answer,
32                 int cset_size,
33                 struct rexp_node *node,
34                 struct rexp_node ** subexps)
35 #else
36 int
37 rx_simple_rexp (answer, cset_size, node, subexps)
38      struct rexp_node ** answer;
39      int cset_size;
40      struct rexp_node *node;
41      struct rexp_node ** subexps;
42 #endif
43 {
44   int stat;
45
46   if (!node)
47     {
48       *answer = 0;
49       return 0;
50     }
51
52   if (!node->observed)
53     {
54       rx_save_rexp (node);
55       *answer = node;
56       return 0;
57     }
58
59   if (node->simplified)
60     {
61       rx_save_rexp (node->simplified);
62       *answer = node->simplified;
63       return 0;
64     }
65
66   switch (node->type)
67     {
68     default:
69     case r_cset:
70     case r_string:
71     case r_cut:
72       return -2;                /* an internal error, really */
73
74     case r_parens:
75       stat = rx_simple_rexp (answer, cset_size,
76                              node->params.pair.left,
77                              subexps);
78       break;
79
80     case r_context:
81       if (isdigit (node->params.intval))
82          stat = rx_simple_rexp (answer, cset_size,
83                                 subexps [node->params.intval - '0'],
84                                 subexps);
85       else
86         {
87           *answer = 0;
88           stat = 0;
89         }
90       break;
91
92     case r_concat:
93     case r_alternate:
94     case r_opt:
95     case r_star:
96     case r_plus:
97     case r_interval:
98       {
99         struct rexp_node *n;
100         n = rexp_node (node->type);
101         if (!n)
102           return -1;
103
104         if (node->params.cset)
105           {
106             n->params.cset = rx_copy_cset (cset_size,
107                                            node->params.cset);
108             if (!n->params.cset)
109               {
110                 rx_free_rexp (n);
111                 return -1;
112               }
113           }
114         n->params.intval = node->params.intval;
115         n->params.intval2 = node->params.intval2;
116         {
117           int s;
118     
119           s = rx_simple_rexp (&n->params.pair.left, cset_size,
120                               node->params.pair.left, subexps);
121           if (!s)
122             s = rx_simple_rexp (&n->params.pair.right, cset_size,
123                                 node->params.pair.right, subexps);
124           if (!s)
125             {
126               *answer = n;
127               stat = 0;
128             }
129           else
130             {
131               rx_free_rexp  (n);
132               stat = s;
133             }
134         }
135       }      
136       break;
137     }
138
139   if (!stat)
140     {
141       node->simplified = *answer;
142       rx_save_rexp (node->simplified);
143     }
144   return stat;
145 }  
146
147