File: break_lp.c

package info (click to toggle)
lurkftp 1.00-1
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 324 kB
  • ctags: 375
  • sloc: ansic: 4,551; sh: 186; makefile: 162
file content (138 lines) | stat: -rw-r--r-- 3,006 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#include "lurkftp.h"

#define RE_BLKSIZE 8

#define NOMEM_ERR "No Memory"

static int try_split(const char *txt, regex_t *re, int *_pos)
{
    int len, i;
    char *s;
    static char *buf = NULL;
    static int buflen = 1;

    if(!*txt)
	return REG_ESPACE ? REG_ESPACE : -1; /* not accurate, but shouldn't ever happen */
    len = strlen(txt) + 1;
    if(len > buflen) {
	if(buf)
	    free(buf);
	while(buflen && buflen < len)
	    buflen <<= 1;
	if(buflen < len)
	    return REG_ESPACE ? REG_ESPACE : -1;
	if(!(buf = malloc(buflen)))
	    return REG_ESPACE ? REG_ESPACE : -1;
    }
    memcpy(buf, txt, len);
    /* search backwards for a spot */
    len /= 2;
    s = buf + len + 1;
    while(1) {
	while(--s > buf && *s != '|');
	if(s <= buf)
	    break;
	*s = 0;
	if(!(i = regcomp(re, buf, REG_EXTENDED|REG_NOSUB))) {
	    *_pos = (int)(s - buf + 1);
	    return 0;
	}
	*s = '|';
	if(i == REG_ESIZE || i == REG_ESPACE) {
	    len /= 2;
	    s = buf + len;
	    if(!len)
		return i;
	}
    }
    /* search forwards for a spot */
    s = buf + len;
    while(1) {
	while(*++s && *s != '|' && s < buf + len*2);
	if(*s != '|')
	    break;
	*s = 0;
	if(!(i = regcomp(re, buf, REG_EXTENDED|REG_NOSUB))) {
	    *_pos = (int)(s - buf + 1);
	    return 0;
	}
	*s = '|';
	if(i == REG_ESIZE || i == REG_ESPACE)
	    return i;
    }
    return REG_ESIZE ? REG_ESIZE : REG_ESPACE; /* one must be valid or we wouldn't be here */
}

const char *break_lp(const char *txt, regex_t *re0, regex_t **_re_array, int *_nre)
{
    int i, len;
    int nre = 0;
    regex_t *re_array;

    if(!(i = regcomp(re0, txt, REG_EXTENDED|REG_NOSUB))) {
	*_nre = 1;
	*_re_array = re0;
	return NULL;
    }
    if(i != REG_ESPACE && i != REG_ESIZE) {
	fprintf(stderr, "error %d != %d/%d\n", i, REG_ESPACE, REG_ESIZE);
	regerror(i, re0, scratch, 4096);
	return scratch;
    }
    re_array = malloc(sizeof(*re_array) * RE_BLKSIZE);
    if(!re_array)
	return NOMEM_ERR;
    while(*txt && !(i = try_split(txt, re0, &len))) {
	if(!nre) {
	    *re_array = *re0;
	    re0 = re_array;
	}
	nre++;
	re0++;
	txt += len;
	if(*txt && !(nre % RE_BLKSIZE)) {
	    re_array = realloc(re_array, sizeof(*re_array) * (RE_BLKSIZE + nre));
	    if(!re_array)
		return NOMEM_ERR;
	    re0 = re_array + nre;
	}
	if(!(i = regcomp(re0, txt, REG_EXTENDED|REG_NOSUB))) {
	    nre++;
	    break;
	}
    }
    if(i) {
	regerror(i, nre > 0 ? &re_array[nre] : re0, scratch, 4096);
	if(nre) {
	    while(--nre >= 0)
		regfree(&re_array[nre]);
	}
	free(re_array);
	return scratch;
    }
    *_re_array = re_array;
    *_nre = nre;
    return NULL;
}

int match_lp(const char *txt, const regex_t *re_array, int nre)
{
    for(;nre > 0; nre--, re_array++)
	if(!regexec(re_array, txt, 0, NULL, 0))
	    return 0;
    return 1;
}

void free_lp(regex_t **_re_array, int *_nre)
{
    int nre = *_nre;
    int i;
    regex_t *re_array = *_re_array;

    *_re_array = NULL;
    *_nre = 0;
    for(i = 0; i < nre; i++)
	regfree(&re_array[i]);
    if(nre > 1)
	free(re_array);
}