~vcs-imports/mammoth-replicator/trunk

« back to all changes in this revision

Viewing changes to contrib/tsearch2/ispell/regis.c

  • Committer: alvherre
  • Date: 2005-12-16 21:24:52 UTC
  • Revision ID: svn-v4:db760fc0-0f08-0410-9d63-cc6633f64896:trunk:1
Initial import of the REL8_0_3 sources from the Pgsql CVS repository.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <stdio.h>
 
2
#include <stdlib.h>
 
3
#include <string.h>
 
4
#include <ctype.h>
 
5
 
 
6
#include "regis.h"
 
7
#include "common.h"
 
8
 
 
9
int
 
10
RS_isRegis(const char *str)
 
11
{
 
12
        unsigned char *ptr = (unsigned char *) str;
 
13
 
 
14
        while (ptr && *ptr)
 
15
                if (isalpha(*ptr) || *ptr == '[' || *ptr == ']' || *ptr == '^')
 
16
                        ptr++;
 
17
                else
 
18
                        return 0;
 
19
        return 1;
 
20
}
 
21
 
 
22
#define RS_IN_ONEOF 1
 
23
#define RS_IN_ONEOF_IN  2
 
24
#define RS_IN_NONEOF    3
 
25
#define RS_IN_WAIT      4
 
26
 
 
27
static RegisNode *
 
28
newRegisNode(RegisNode * prev, int len)
 
29
{
 
30
        RegisNode  *ptr;
 
31
 
 
32
        ptr = (RegisNode *) malloc(RNHDRSZ + len + 1);
 
33
        if (!ptr)
 
34
                ts_error(ERROR, "No memory");
 
35
        memset(ptr, 0, RNHDRSZ + len + 1);
 
36
        if (prev)
 
37
                prev->next = ptr;
 
38
        return ptr;
 
39
}
 
40
 
 
41
int
 
42
RS_compile(Regis * r, int issuffix, const char *str)
 
43
{
 
44
        int                     i,
 
45
                                len = strlen(str);
 
46
        int                     state = RS_IN_WAIT;
 
47
        RegisNode  *ptr = NULL;
 
48
 
 
49
        memset(r, 0, sizeof(Regis));
 
50
        r->issuffix = (issuffix) ? 1 : 0;
 
51
 
 
52
        for (i = 0; i < len; i++)
 
53
        {
 
54
                unsigned char c = *(((unsigned char *) str) + i);
 
55
 
 
56
                if (state == RS_IN_WAIT)
 
57
                {
 
58
                        if (isalpha(c))
 
59
                        {
 
60
                                if (ptr)
 
61
                                        ptr = newRegisNode(ptr, len);
 
62
                                else
 
63
                                        ptr = r->node = newRegisNode(NULL, len);
 
64
                                ptr->data[0] = c;
 
65
                                ptr->type = RSF_ONEOF;
 
66
                                ptr->len = 1;
 
67
                        }
 
68
                        else if (c == '[')
 
69
                        {
 
70
                                if (ptr)
 
71
                                        ptr = newRegisNode(ptr, len);
 
72
                                else
 
73
                                        ptr = r->node = newRegisNode(NULL, len);
 
74
                                ptr->type = RSF_ONEOF;
 
75
                                state = RS_IN_ONEOF;
 
76
                        }
 
77
                        else
 
78
                                ts_error(ERROR, "Error in regis: %s at pos %d\n", str, i + 1);
 
79
                }
 
80
                else if (state == RS_IN_ONEOF)
 
81
                {
 
82
                        if (c == '^')
 
83
                        {
 
84
                                ptr->type = RSF_NONEOF;
 
85
                                state = RS_IN_NONEOF;
 
86
                        }
 
87
                        else if (isalpha(c))
 
88
                        {
 
89
                                ptr->data[0] = c;
 
90
                                ptr->len = 1;
 
91
                                state = RS_IN_ONEOF_IN;
 
92
                        }
 
93
                        else
 
94
                                ts_error(ERROR, "Error in regis: %s at pos %d\n", str, i + 1);
 
95
                }
 
96
                else if (state == RS_IN_ONEOF_IN || state == RS_IN_NONEOF)
 
97
                {
 
98
                        if (isalpha(c))
 
99
                        {
 
100
                                ptr->data[ptr->len] = c;
 
101
                                ptr->len++;
 
102
                        }
 
103
                        else if (c == ']')
 
104
                                state = RS_IN_WAIT;
 
105
                        else
 
106
                                ts_error(ERROR, "Error in regis: %s at pos %d\n", str, i + 1);
 
107
                }
 
108
                else
 
109
                        ts_error(ERROR, "Internal error in RS_compile: %d\n", state);
 
110
        }
 
111
 
 
112
        ptr = r->node;
 
113
        while (ptr)
 
114
        {
 
115
                r->nchar++;
 
116
                ptr = ptr->next;
 
117
        }
 
118
 
 
119
        return 0;
 
120
}
 
121
 
 
122
void
 
123
RS_free(Regis * r)
 
124
{
 
125
        RegisNode  *ptr = r->node,
 
126
                           *tmp;
 
127
 
 
128
        while (ptr)
 
129
        {
 
130
                tmp = ptr->next;
 
131
                free(ptr);
 
132
                ptr = tmp;
 
133
        }
 
134
 
 
135
        r->node = NULL;
 
136
}
 
137
 
 
138
int
 
139
RS_execute(Regis * r, const char *str, int len)
 
140
{
 
141
        RegisNode  *ptr = r->node;
 
142
        unsigned char *c;
 
143
 
 
144
        if (len < 0)
 
145
                len = strlen(str);
 
146
 
 
147
        if (len < r->nchar)
 
148
                return 0;
 
149
 
 
150
        if (r->issuffix)
 
151
                c = ((unsigned char *) str) + len - r->nchar;
 
152
        else
 
153
                c = (unsigned char *) str;
 
154
 
 
155
        while (ptr)
 
156
        {
 
157
                switch (ptr->type)
 
158
                {
 
159
                        case RSF_ONEOF:
 
160
                                if (ptr->len == 0)
 
161
                                {
 
162
                                        if (*c != *(ptr->data))
 
163
                                                return 0;
 
164
                                }
 
165
                                else if (strchr((char *) ptr->data, *c) == NULL)
 
166
                                        return 0;
 
167
                                break;
 
168
                        case RSF_NONEOF:
 
169
                                if (ptr->len == 0)
 
170
                                {
 
171
                                        if (*c == *(ptr->data))
 
172
                                                return 0;
 
173
                                }
 
174
                                else if (strchr((char *) ptr->data, *c) != NULL)
 
175
                                        return 0;
 
176
                                break;
 
177
                        default:
 
178
                                ts_error(ERROR, "RS_execute: Unknown type node: %d\n", ptr->type);
 
179
                }
 
180
                ptr = ptr->next;
 
181
                c++;
 
182
        }
 
183
 
 
184
        return 1;
 
185
}