|
|
1.1 root 1: #include "update.h"
2:
3:
4: /*
5: ** Find the longest prefix of tar that match some substring of src
6: ** This uses an inverted index for speed.
7: */
8: #define ALPHA (256) /* alphabet size */
9:
10: static void freemem(n_index,index)
11: long *n_index;
12: char ***index;
13: {
14: register int i;
15: if(n_index && index)
16: {
17: for(i = 0; i < ALPHA; ++i)
18: if(n_index[i] > 0)
19: free(index[i]);
20: free(index);
21: free(n_index);
22: }
23: }
24:
25: /* initial assumptions: src[0] == tar[0] && src+n_match <= endsrc */
26: static long domatch(src,endsrc,tar,endtar,n_match)
27: char *src, *endsrc, *tar, *endtar;
28: long n_match;
29: {
30: register char *sp, *tp;
31:
32: /* see if this really improves on the current match */
33: for(sp = src+n_match, tp = tar+n_match; sp > src; --sp, --tp)
34: if(*sp != *tp)
35: break;
36:
37: /* got an improvement, match as many more as we can */
38: if(sp == src)
39: {
40: sp = src+n_match+1;
41: tp = tar+n_match+1;
42: for(; sp < endsrc && tp < endtar; ++sp, ++tp)
43: if(*sp != *tp)
44: break;
45: }
46: return tp-tar;
47: }
48:
49: /* the real thing */
50: long mtchstring(src,n_src,tar,n_tar,match)
51: char *src; /* the source string to match from */
52: long n_src; /* the length of src */
53: char *tar; /* the string a prefix of which is matched */
54: long n_tar; /* the length of tar */
55: char **match; /* to return the matched address in src */
56: {
57: char *endsrc, *endtar;
58: long n_match;
59: register int i;
60: register long n_ind;
61: register char **ind;
62: static long *N_index = NIL(long);
63: static char *Cursrc = NIL(char), ***Index = NIL(char**);
64: static int Alloced = 0;
65: char **malloc(), **realloc();
66:
67: /* free old inverted indices if necessary */
68: if(src != Cursrc)
69: {
70: if(Alloced)
71: freemem(N_index,Index);
72: Alloced = 0;
73: Cursrc = NIL(char);
74: }
75:
76: /* nothing to do */
77: if(!src || n_src <= 0 || !tar || n_tar <= 0)
78: return 0;
79:
80: endsrc = src + n_src;
81: endtar = tar + n_tar;
82:
83: /* build new index structure */
84: if(src != Cursrc)
85: {
86: Cursrc = src;
87: Alloced = 1;
88: if(N_index = (long*) malloc(ALPHA*sizeof(long)))
89: {
90: register char *sp;
91:
92: memzero((char*)N_index,ALPHA*sizeof(long));
93: if(!(Index = (char ***) malloc(ALPHA*sizeof(char**))))
94: {
95: free(N_index);
96: N_index = NIL(long);
97: Alloced = 0;
98: }
99: else for(sp = src; sp < endsrc; ++sp)
100: {
101: i = (int)(*((unsigned char *)(sp)));
102: ind = Index[i];
103: n_ind = N_index[i];
104:
105: /* make sure we have space */
106: if((n_ind%ALPHA) == 0)
107: {
108: ind = n_ind == 0 ?
109: malloc(ALPHA*sizeof(char *)) :
110: realloc(ind,(n_ind+ALPHA)*sizeof(char*));
111: Index[i] = ind;
112: }
113: if(ind)
114: {
115: ind[n_ind] = sp;
116: N_index[i] += 1;
117: }
118: else
119: {
120: freemem(N_index,Index);
121: N_index = NIL(long);
122: Index = NIL(char**);
123: Alloced = 0;
124: break;
125: }
126: }
127: }
128: }
129:
130: /* find longest matching prefix */
131: i = (int)(*((unsigned char *)(tar)));
132: ind = Alloced ? Index[i] : NULL;
133: n_ind = Alloced ? N_index[i] : -1;
134: n_match = 0;
135: while(1)
136: {
137: register long m;
138:
139: if(ind)
140: {
141: src = n_ind > 0 ? *ind++ : endsrc;
142: n_ind -= 1;
143: }
144: else for(; src+n_match < endsrc; ++src)
145: if(*src == *tar)
146: break;
147: if(src+n_match >= endsrc)
148: break;
149:
150: if((m = domatch(src,endsrc,tar,endtar,n_match)) > n_match)
151: {
152: n_match = m;
153: *match = src;
154: if(tar+n_match >= endtar)
155: break;
156: }
157: }
158:
159: return n_match;
160: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.