Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/libodelta/mtchstring.c
1808 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1989-2011 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* Phong Vo <[email protected]> *
18
* *
19
***********************************************************************/
20
#pragma prototyped
21
#include "update.h"
22
23
24
/*
25
** Find the longest prefix of tar that match some substring of src
26
** This uses an inverted index for speed.
27
*/
28
#define ALPHA (256) /* alphabet size */
29
30
static void freemem(long* n_index, char*** index)
31
{
32
register int i;
33
if(n_index && index)
34
{
35
for(i = 0; i < ALPHA; ++i)
36
if(n_index[i] > 0)
37
free(index[i]);
38
free(index);
39
free(n_index);
40
}
41
}
42
43
/* initial assumptions: src[0] == tar[0] && src+n_match <= endsrc */
44
static long domatch(char* src, char* endsrc, char* tar, char* endtar, long n_match)
45
{
46
register char *sp, *tp;
47
48
/* see if this really improves on the current match */
49
for(sp = src+n_match, tp = tar+n_match; sp > src; --sp, --tp)
50
if(*sp != *tp)
51
break;
52
53
/* got an improvement, match as many more as we can */
54
if(sp == src)
55
{
56
sp = src+n_match+1;
57
tp = tar+n_match+1;
58
for(; sp < endsrc && tp < endtar; ++sp, ++tp)
59
if(*sp != *tp)
60
break;
61
}
62
return tp-tar;
63
}
64
65
/* the real thing */
66
long mtchstring(char* src, long n_src, char* tar, long n_tar, char** match)
67
{
68
char *endsrc, *endtar;
69
long n_match;
70
register int i;
71
register long n_ind;
72
register char **ind;
73
static long *N_index = 0;
74
static char *Cursrc = 0, ***Index = 0;
75
static int Alloced = 0;
76
77
/* free old inverted indices if necessary */
78
if(src != Cursrc)
79
{
80
if(Alloced)
81
freemem(N_index,Index);
82
Alloced = 0;
83
Cursrc = 0;
84
}
85
86
/* nothing to do */
87
if(!src || n_src <= 0 || !tar || n_tar <= 0)
88
return 0;
89
90
endsrc = src + n_src;
91
endtar = tar + n_tar;
92
93
/* build new index structure */
94
if(src != Cursrc)
95
{
96
Cursrc = src;
97
Alloced = 1;
98
if(N_index = (long*) malloc(ALPHA*sizeof(long)))
99
{
100
register char *sp;
101
102
memzero(N_index,ALPHA*sizeof(long));
103
if(!(Index = (char ***) malloc(ALPHA*sizeof(char**))))
104
{
105
free(N_index);
106
N_index = 0;
107
Alloced = 0;
108
}
109
else for(sp = src; sp < endsrc; ++sp)
110
{
111
i = (int)(*((unsigned char *)(sp)));
112
ind = Index[i];
113
n_ind = N_index[i];
114
115
/* make sure we have space */
116
if((n_ind%ALPHA) == 0)
117
{
118
ind = n_ind == 0 ?
119
(char**)malloc(ALPHA*sizeof(char *)) :
120
(char**)realloc(ind,(n_ind+ALPHA)*sizeof(char*));
121
Index[i] = ind;
122
}
123
if(ind)
124
{
125
ind[n_ind] = sp;
126
N_index[i] += 1;
127
}
128
else
129
{
130
freemem(N_index,Index);
131
N_index = 0;
132
Index = 0;
133
Alloced = 0;
134
break;
135
}
136
}
137
}
138
}
139
140
/* find longest matching prefix */
141
i = (int)(*((unsigned char *)(tar)));
142
ind = Alloced ? Index[i] : (char**)0;
143
n_ind = Alloced ? N_index[i] : -1;
144
n_match = 0;
145
while(1)
146
{
147
register long m;
148
149
if(ind)
150
{
151
src = n_ind > 0 ? *ind++ : endsrc;
152
n_ind -= 1;
153
}
154
else for(; src+n_match < endsrc; ++src)
155
if(*src == *tar)
156
break;
157
if(src+n_match >= endsrc)
158
break;
159
160
if((m = domatch(src,endsrc,tar,endtar,n_match)) > n_match)
161
{
162
n_match = m;
163
*match = src;
164
if(tar+n_match >= endtar)
165
break;
166
}
167
}
168
169
return n_match;
170
}
171
172