summaryrefslogtreecommitdiff
path: root/src/mt
diff options
context:
space:
mode:
authorHenrik Rydberg <rydberg@euromail.se>2011-10-08 20:30:28 +0200
committerHenrik Rydberg <rydberg@euromail.se>2011-10-08 20:30:28 +0200
commit5df79c53745fde5d6c3340a2979b1429cd5892c1 (patch)
tree1a81af141708b826e9c61e8a04019994fcca8298 /src/mt
Initial import of htcd system 1.0
Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
Diffstat (limited to 'src/mt')
-rw-r--r--src/mt/cfind.f80
-rw-r--r--src/mt/charset.h131
-rw-r--r--src/mt/config.cc33
-rw-r--r--src/mt/config.h27
-rw-r--r--src/mt/crfind.f80
-rw-r--r--src/mt/dates.cc207
-rw-r--r--src/mt/dates.h49
-rw-r--r--src/mt/find_not_of.f80
-rw-r--r--src/mt/find_of.f80
-rw-r--r--src/mt/issue.cc51
-rw-r--r--src/mt/issue.h55
-rw-r--r--src/mt/lock.cc114
-rw-r--r--src/mt/lock.h72
-rw-r--r--src/mt/lookup.cc88
-rw-r--r--src/mt/lookup.h32
-rw-r--r--src/mt/mlock.h48
-rw-r--r--src/mt/mread.cc135
-rw-r--r--src/mt/mread.h63
-rw-r--r--src/mt/mset.cc81
-rw-r--r--src/mt/mset.h62
-rw-r--r--src/mt/msmap.cc84
-rw-r--r--src/mt/msmap.h89
-rw-r--r--src/mt/mstream.cc72
-rw-r--r--src/mt/mstream.h103
-rw-r--r--src/mt/mstring.cc139
-rw-r--r--src/mt/mstring.h222
-rw-r--r--src/mt/mvec.h149
-rw-r--r--src/mt/qran.h34
-rw-r--r--src/mt/random.cc95
-rw-r--r--src/mt/random.h39
-rw-r--r--src/mt/rfind_not_of.f80
-rw-r--r--src/mt/rfind_of.f80
-rw-r--r--src/mt/scomptab.f44
-rw-r--r--src/mt/sconvert.f35
-rw-r--r--src/mt/sfind.f40
-rw-r--r--src/mt/sfindtab.f40
-rw-r--r--src/mt/skip_parentesis.f42
-rw-r--r--src/mt/split.h72
-rw-r--r--src/mt/srfind.f40
-rw-r--r--src/mt/srfindtab.f40
-rw-r--r--src/mt/stackque.h64
-rw-r--r--src/mt/stringref.cc126
-rw-r--r--src/mt/stringref.h239
-rw-r--r--src/mt/strip.f31
-rw-r--r--src/mt/test.cc337
-rw-r--r--src/mt/uniheap.h65
46 files changed, 3969 insertions, 0 deletions
diff --git a/src/mt/cfind.f b/src/mt/cfind.f
new file mode 100644
index 0000000..3d101ec
--- /dev/null
+++ b/src/mt/cfind.f
@@ -0,0 +1,80 @@
1ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
2c
3c HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4c
5c This program is free software; you can redistribute it and/or modify
6c it under the terms of the GNU General Public License as published by
7c the Free Software Foundation; either version 2 of the License, or
8c (at your option) any later version.
9c
10c This program is distributed in the hope that it will be useful,
11c but WITHOUT ANY WARRANTY; without even the implied warranty of
12c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13c GNU General Public License for more details.
14c
15c You should have received a copy of the GNU General Public License
16c along with this program; if not, write to the Free Software
17c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18c
19
20 integer function cfind(s,n,c)
21 character s(0:1),c
22 integer i,m,n
23 m=mod(n,16)
24 do 10 i=0,m-1
25 if(s(i).eq.c)go to 100
26 10 continue
27 do 20 i=m,n-1,16
28 if(s(i).eq.c)go to 100
29 if(s(i+1).eq.c)go to 101
30 if(s(i+2).eq.c)go to 102
31 if(s(i+3).eq.c)go to 103
32 if(s(i+4).eq.c)go to 104
33 if(s(i+5).eq.c)go to 105
34 if(s(i+6).eq.c)go to 106
35 if(s(i+7).eq.c)go to 107
36 if(s(i+8).eq.c)go to 108
37 if(s(i+9).eq.c)go to 109
38 if(s(i+10).eq.c)go to 110
39 if(s(i+11).eq.c)go to 111
40 if(s(i+12).eq.c)go to 112
41 if(s(i+13).eq.c)go to 113
42 if(s(i+14).eq.c)go to 114
43 if(s(i+15).eq.c)go to 115
44 20 continue
45 cfind=-1
46 return
47 100 cfind=i
48 return
49 101 cfind=i+1
50 return
51 102 cfind=i+2
52 return
53 103 cfind=i+3
54 return
55 104 cfind=i+4
56 return
57 105 cfind=i+5
58 return
59 106 cfind=i+6
60 return
61 107 cfind=i+7
62 return
63 108 cfind=i+8
64 return
65 109 cfind=i+9
66 return
67 110 cfind=i+10
68 return
69 111 cfind=i+11
70 return
71 112 cfind=i+12
72 return
73 113 cfind=i+13
74 return
75 114 cfind=i+14
76 return
77 115 cfind=i+15
78 return
79 end
80
diff --git a/src/mt/charset.h b/src/mt/charset.h
new file mode 100644
index 0000000..84742b9
--- /dev/null
+++ b/src/mt/charset.h
@@ -0,0 +1,131 @@
1/*************************************************************************
2 *
3 * HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#ifndef CHARSETH
21#define CHARSETH
22
23#include <string.h>
24
25struct charset {
26 explicit charset(const char s[]) {
27 memset(negmap,0,256); while(*s) map[*s++]=1;
28 }
29 charset(char beg,char end) {
30 memset(negmap,0,256); while(beg<=end) map[beg++]=1;
31 }
32 int test(char c) const { return map[c]; }
33 int operator[](char c) const { return map[c]; }
34 char negmap[128],map[128];
35};
36
37inline charset operator|(const charset& a,const charset& b) {
38 charset c(a); for(int i=-127;i<128;i++) c.map[i]|=b.map[i]; return c;
39}
40inline charset operator|(const charset& a,char b) {
41 charset c(a); c.map[b]=(b!=0); return c;
42}
43inline charset operator|(char a,const charset& b) {
44 charset c(b); c.map[a]=(a!=0); return c;
45}
46inline charset operator&(const charset& a,const charset& b) {
47 charset c(a); for(int i=-127;i<128;i++) c.map[i]&=b.map[i]; return c;
48}
49inline charset operator^(const charset& a,const charset& b) {
50 charset c(a); for(int i=-127;i<128;i++) c.map[i]^=b.map[i]; return c;
51}
52inline charset operator-(const charset& a,const charset& b) {
53 charset c(a); for(int i=-127;i<128;i++) c.map[i]&=~b.map[i]; return c;
54}
55inline charset operator-(const charset& a,char b) {
56 charset c(a); c.map[b]=0; return c;
57}
58inline charset operator~(const charset& a) {
59 charset c(a); for(int i=-127;i<128;i++) c.map[i]=!c.map[i]; c.map[0]=0;
60 return c;
61}
62
63//////////////////////////////////////////////////////////////////////////
64
65struct charmap {
66 charmap() { for(int i=-127;i<128;i++) map[i]=i; }
67 charmap(const charset& a,const charset& b) {
68 for(int i=-127,j=-127;i<128;i++) {
69 if(a[i]) { while(j<128&&!b[j]) j++; map[i]=j++; }
70 else map[i]=i;
71 }
72 }
73 charmap(const charset& a,const char* b) {
74 for(int i=-127;i<128;i++) if(a[i]&&*b) map[i]=*b++; else map[i]=i;
75 }
76 char operator[](char c) const { return map[c]; }
77 char negmap[128],map[128];
78};
79
80inline charmap operator<<(const charmap& a,const charmap& b) {
81 charmap c(a);
82 for(int i=-127;i<128;i++) if(b.map[i]!=i) c.map[i]=b.map[i];
83 for(int i=-127;i<128;i++) c.map[i]=c.map[c.map[i]];
84 return c;
85}
86
87//////////////////////////////////////////////////////////////////////////
88
89struct bracket {
90 explicit bracket(const char s[]) { strncpy(&left,s,sizeof(bracket)); }
91 int test(char c) const { return c==left||c==right; }
92 char left,right,esc,end;
93};
94
95//////////////////////////////////////////////////////////////////////////
96
97const charset cset_spaces(" \t");
98const charset cset_newl("\r\n");
99const charset cset_ws=cset_spaces|cset_newl;
100const charset cset_printable(' ','~');
101const charset cset_digit('0','9');
102const charset cset_real=cset_digit|'.';
103const charset cset_sign("+-");
104const charset cset_lalpha('a','z');
105const charset cset_ualpha('A','Z');
106const charset cset_alpha=cset_lalpha|cset_ualpha;
107const charset cset_alphanum=cset_alpha|cset_digit;
108const charset cset_alphareal=cset_alpha|cset_real;
109const charset cset_lext1(-32,-10),cset_lext2(-8,-2);
110const charset cset_uext1(-64,-42),cset_uext2(-40,-34);
111const charset cset_liso=cset_lalpha|cset_lext1|cset_lext2;
112const charset cset_uiso=cset_ualpha|cset_uext1|cset_uext2;
113
114const charmap cset_ident;
115const charmap cset_leqv1(cset_lext1,"aaaaaaaceeeeiiiidnooooo");
116const charmap cset_leqv2(cset_lext2,"ouuuuyp");
117const charmap cset_ueqv1(cset_uext1,"AAAAAAACEEEEIIIIDNOOOOO");
118const charmap cset_ueqv2(cset_uext2,"OUUUUYP");
119
120const charmap cset_lcase(cset_uiso,cset_liso);
121const charmap cset_ucase(cset_liso,cset_uiso);
122const charmap cset_sim=cset_lcase<<cset_leqv1<<cset_leqv2;
123
124const bracket cset_quotes("\"\"\\");
125const bracket cset_indices("[]\\");
126const bracket cset_braces("{}\\");
127const bracket cset_para("()\\");
128const bracket cset_dollars("$$\\");
129const bracket cset_hooks("<>\\");
130
131#endif
diff --git a/src/mt/config.cc b/src/mt/config.cc
new file mode 100644
index 0000000..1797780
--- /dev/null
+++ b/src/mt/config.cc
@@ -0,0 +1,33 @@
1/*************************************************************************
2 *
3 * HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#include <mt/config.h>
21
22mstring htchome()
23{
24 const char* p=getenv("HTCHOME");
25 if(!p) {
26 fprintf(stderr,"env: HTCHOME not set, exiting\n");
27 exit(-1);
28 }
29 mstring home=p;
30 if(home.back()=='/') home=home.popb();
31 return home;
32}
33
diff --git a/src/mt/config.h b/src/mt/config.h
new file mode 100644
index 0000000..5389755
--- /dev/null
+++ b/src/mt/config.h
@@ -0,0 +1,27 @@
1/*************************************************************************
2 *
3 * HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#ifndef CONFIGH
21#define CONFIGH
22
23#include <mt/mstring.h>
24
25mstring htchome();
26
27#endif
diff --git a/src/mt/crfind.f b/src/mt/crfind.f
new file mode 100644
index 0000000..f996ac4
--- /dev/null
+++ b/src/mt/crfind.f
@@ -0,0 +1,80 @@
1ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
2c
3c HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4c
5c This program is free software; you can redistribute it and/or modify
6c it under the terms of the GNU General Public License as published by
7c the Free Software Foundation; either version 2 of the License, or
8c (at your option) any later version.
9c
10c This program is distributed in the hope that it will be useful,
11c but WITHOUT ANY WARRANTY; without even the implied warranty of
12c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13c GNU General Public License for more details.
14c
15c You should have received a copy of the GNU General Public License
16c along with this program; if not, write to the Free Software
17c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18c
19
20 integer function crfind(s,n,c)
21 character s(0:1),c
22 integer i,m,n
23 m=mod(n,16)
24 do 10 i=n-16,m,-16
25 if(s(i+15).eq.c)go to 115
26 if(s(i+14).eq.c)go to 114
27 if(s(i+13).eq.c)go to 113
28 if(s(i+12).eq.c)go to 112
29 if(s(i+11).eq.c)go to 111
30 if(s(i+10).eq.c)go to 110
31 if(s(i+9).eq.c)go to 109
32 if(s(i+8).eq.c)go to 108
33 if(s(i+7).eq.c)go to 107
34 if(s(i+6).eq.c)go to 106
35 if(s(i+5).eq.c)go to 105
36 if(s(i+4).eq.c)go to 104
37 if(s(i+3).eq.c)go to 103
38 if(s(i+2).eq.c)go to 102
39 if(s(i+1).eq.c)go to 101
40 if(s(i).eq.c)go to 100
41 10 continue
42 do 20 i=m-1,0,-1
43 if(s(i).eq.c)go to 100
44 20 continue
45 crfind=-1
46 return
47 100 crfind=i
48 return
49 101 crfind=i+1
50 return
51 102 crfind=i+2
52 return
53 103 crfind=i+3
54 return
55 104 crfind=i+4
56 return
57 105 crfind=i+5
58 return
59 106 crfind=i+6
60 return
61 107 crfind=i+7
62 return
63 108 crfind=i+8
64 return
65 109 crfind=i+9
66 return
67 110 crfind=i+10
68 return
69 111 crfind=i+11
70 return
71 112 crfind=i+12
72 return
73 113 crfind=i+13
74 return
75 114 crfind=i+14
76 return
77 115 crfind=i+15
78 return
79 end
80
diff --git a/src/mt/dates.cc b/src/mt/dates.cc
new file mode 100644
index 0000000..8c244e5
--- /dev/null
+++ b/src/mt/dates.cc
@@ -0,0 +1,207 @@
1/*************************************************************************
2 *
3 * HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#include <mt/dates.h>
21#include <mt/split.h>
22#include <ctype.h>
23
24const mstring SWEEK[MAXLANG][7]={
25 "Sun","Mon","Tue","Wed","Thu","Fri","Sat",
26 "Sön","Mån","Tis","Ons","Tor","Fre","Lör"
27};
28const mstring SMONTH[MAXLANG][12]={
29 "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec",
30 "Jan","Feb","Mar","Apr","Maj","Jun","Jul","Aug","Sep","Okt","Nov","Dec"
31};
32const mstring WEEK[MAXLANG][7]={
33 "Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday",
34 "Söndag","Måndag","Tisdag","Onsdag","Torsdag","Fredag","Lördag"
35};
36const mstring MONTH[MAXLANG][12]={
37 "January","February","March","April","May","June",
38 "July","August","September","October","November","December",
39 "Januari","Februari","Mars","April","Maj","Juni",
40 "Juli","Augusti","September","Oktober","November","December"
41};
42
43time_t Today(time_t now)
44{
45 tm s; localtime_r(&now,&s);
46 s.tm_hour=0;
47 s.tm_min=0;
48 s.tm_sec=0;
49 return mktime(&s);
50}
51
52time_t Sunday(time_t now)
53{
54 tm s; localtime_r(&now,&s);
55 s.tm_mday-=s.tm_wday;
56 return mktime(&s);
57}
58
59const mstring& Week(int lang,time_t t)
60{
61 tm s; return WEEK[lang][localtime_r(&t,&s)->tm_wday];
62}
63
64const mstring& Month(int lang,time_t t)
65{
66 tm s; return MONTH[lang][localtime_r(&t,&s)->tm_mon];
67}
68
69const mstring& SWeek(int lang,time_t t)
70{
71 tm s; return SWEEK[lang][localtime_r(&t,&s)->tm_wday];
72}
73
74const mstring& SMonth(int lang,time_t t)
75{
76 tm s; return SMONTH[lang][localtime_r(&t,&s)->tm_mon];
77}
78
79mstring httpTime(time_t t)
80{
81 tm tt; gmtime_r(&t,&tt);
82 return mstring().convert("%s, %02d %s %4d %02d:%02d:%02d GMT",
83 SWEEK[0][tt.tm_wday].c_str(),
84 tt.tm_mday,
85 SMONTH[0][tt.tm_mon].c_str(),
86 tt.tm_year+1900,
87 tt.tm_hour,
88 tt.tm_min,
89 tt.tm_sec);
90}
91
92mstring htcTime(int lang,time_t t)
93{
94 tm tt; localtime_r(&t,&tt);
95 mstring s(32); asctime_r(&tt,s.data()); s.resize(24);
96 if(lang) {
97 for(int i=0;i<7;i++) if(s(0,3)==SWEEK[0][i]) {
98 s.replace(0,3,SWEEK[lang][i]);
99 break;
100 }
101 for(int i=0;i<12;i++) if(s(4,3)==SMONTH[0][i]) {
102 s.replace(4,3,SMONTH[lang][i]);
103 break;
104 }
105 }
106 return s;
107}
108
109static int Month(int& mon,const sref& st)
110{
111 mstring s=st; s.tolower(); s[0]=toupper(s[0]);
112 for(int lang=0;lang<MAXLANG;lang++) {
113 for(int m=0;m<12;m++) if(s==SMONTH[lang][m]) { mon=m; return 1; }
114 }
115 return 0;
116}
117
118static int Week(int& week,const sref& st)
119{
120 mstring s=st; s.tolower(); s[0]=toupper(s[0]);
121 for(int lang=0;lang<MAXLANG;lang++) {
122 for(int w=0;w<7;w++) if(s==SWEEK[lang][w]) { week=w; return 1; }
123 }
124 return 0;
125}
126
127static int Time(int& th,int& tmi,int& ts,const sref& st)
128{
129 static const charset sep_tag(":");
130 sref hour,min,sec,when=st;
131 int h,m,s;
132 if(when.find(':')<0) return 0;
133 Split(hour,when,sep_tag);
134 Split(min,when,sep_tag);
135 Split(sec,when,sep_tag);
136 h=atoi(hour);
137 m=atoi(min);
138 s=atoi(sec);
139 if(h>=0&&h<=24&&m>=0&&m<60&&s>=0&&s<60) { th=h; tmi=m; ts=s; return 1; }
140 return 0;
141}
142
143static int Day(int& day,const sref& s)
144{
145 if(s.find_not_of(cset_digit)>=0) return 0;
146 int d=atoi(s);
147 if(d>0&&d<32) { day=d; return 1; }
148 return 0;
149}
150
151static int Year(int& year,const sref& s)
152{
153 if(s.find_not_of(cset_digit)>=0) return 0;
154 int y=atoi(s);
155 if(y>=32&&y<9999) { year=y; return 1; }
156 return 0;
157}
158
159time_t htcTime(int lang,const sref& date)
160{
161 sref week,month,day,when,year,rest=date;
162 Split(week,rest);
163 Split(month,rest);
164 Split(day,rest);
165 Split(when,rest);
166 Split(year,rest);
167 struct tm t;
168 Time(t.tm_hour,t.tm_min,t.tm_sec,when);
169 t.tm_mday=atoi(day);
170 Month(t.tm_mon,month);
171 t.tm_year=atoi(year)-1900;
172 Week(t.tm_wday,week);
173 t.tm_isdst=-1;
174 return mktime(&t);
175}
176
177time_t cvtTime(const sref& code)
178{
179 time_t now=time(0);
180 tm t; localtime_r(&now,&t);
181 t.tm_hour=0;t.tm_min=0;t.tm_sec=0;
182 //Start with 00:00:00 today
183 sref first,rest=code;
184 int w=0,m=0,d=0,h=0,y=0;
185 while(Split(first,rest)) {
186 if(!w) w=Week(t.tm_wday,first);
187 if(!m) m=Month(t.tm_mon,first);
188 if(!h) h=Time(t.tm_hour,t.tm_min,t.tm_sec,first);
189 if(!d) d=Day(t.tm_mday,first);
190 if(!y) if(y=Year(t.tm_year,first)) t.tm_year-=1900;
191 }
192 t.tm_isdst=-1;
193 return mktime(&t);
194}
195
196//////////////////////////////
197
198int Language(const sref& st)
199{
200 static const charset seps=cset_ws|charset(",;");
201 mstring s=st; s.tolower();
202 sref first,rest=s;
203 while(Split(first,rest,seps)) {
204 for(int i=0;i<MAXLANG;i++) if(first==LANG[i]) return i;
205 }
206 return -1;
207}
diff --git a/src/mt/dates.h b/src/mt/dates.h
new file mode 100644
index 0000000..fe05245
--- /dev/null
+++ b/src/mt/dates.h
@@ -0,0 +1,49 @@
1/*************************************************************************
2 *
3 * HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#ifndef DATESH
21#define DATESH
22
23#include <mt/mstring.h>
24#include <time.h>
25
26const time_t SEC_PER_DAY=86400;
27const int MAXLANG=2;
28const mstring LANG[MAXLANG]={"en","sv"};
29
30inline time_t Now() { return time(0); }
31inline time_t Days(int days) { return days*SEC_PER_DAY; }
32
33time_t Today(time_t);
34time_t Sunday(time_t);
35
36const mstring& Week(int lang,time_t t);
37const mstring& Month(int lang,time_t t);
38
39const mstring& SWeek(int lang,time_t t);
40const mstring& SMonth(int lang,time_t t);
41
42mstring httpTime(time_t t);
43mstring htcTime(int lang,time_t t);
44time_t htcTime(int lang,const sref& date);
45time_t cvtTime(const sref& code);
46
47int Language(const sref& s);
48
49#endif
diff --git a/src/mt/find_not_of.f b/src/mt/find_not_of.f
new file mode 100644
index 0000000..11d9287
--- /dev/null
+++ b/src/mt/find_not_of.f
@@ -0,0 +1,80 @@
1ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
2c
3c HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4c
5c This program is free software; you can redistribute it and/or modify
6c it under the terms of the GNU General Public License as published by
7c the Free Software Foundation; either version 2 of the License, or
8c (at your option) any later version.
9c
10c This program is distributed in the hope that it will be useful,
11c but WITHOUT ANY WARRANTY; without even the implied warranty of
12c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13c GNU General Public License for more details.
14c
15c You should have received a copy of the GNU General Public License
16c along with this program; if not, write to the Free Software
17c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18c
19
20 integer function find_not_of(s,n,c)
21 byte s(0:1),c(0:1)
22 integer i,m,n
23 m=mod(n,16)
24 do 10 i=0,m-1
25 if(c(s(i)).eq.0)go to 100
26 10 continue
27 do 20 i=m,n-1,16
28 if(c(s(i)).eq.0)go to 100
29 if(c(s(i+1)).eq.0)go to 101
30 if(c(s(i+2)).eq.0)go to 102
31 if(c(s(i+3)).eq.0)go to 103
32 if(c(s(i+4)).eq.0)go to 104
33 if(c(s(i+5)).eq.0)go to 105
34 if(c(s(i+6)).eq.0)go to 106
35 if(c(s(i+7)).eq.0)go to 107
36 if(c(s(i+8)).eq.0)go to 108
37 if(c(s(i+9)).eq.0)go to 109
38 if(c(s(i+10)).eq.0)go to 110
39 if(c(s(i+11)).eq.0)go to 111
40 if(c(s(i+12)).eq.0)go to 112
41 if(c(s(i+13)).eq.0)go to 113
42 if(c(s(i+14)).eq.0)go to 114
43 if(c(s(i+15)).eq.0)go to 115
44 20 continue
45 find_not_of=-1
46 return
47 100 find_not_of=i
48 return
49 101 find_not_of=i+1
50 return
51 102 find_not_of=i+2
52 return
53 103 find_not_of=i+3
54 return
55 104 find_not_of=i+4
56 return
57 105 find_not_of=i+5
58 return
59 106 find_not_of=i+6
60 return
61 107 find_not_of=i+7
62 return
63 108 find_not_of=i+8
64 return
65 109 find_not_of=i+9
66 return
67 110 find_not_of=i+10
68 return
69 111 find_not_of=i+11
70 return
71 112 find_not_of=i+12
72 return
73 113 find_not_of=i+13
74 return
75 114 find_not_of=i+14
76 return
77 115 find_not_of=i+15
78 return
79 end
80
diff --git a/src/mt/find_of.f b/src/mt/find_of.f
new file mode 100644
index 0000000..81cd99d
--- /dev/null
+++ b/src/mt/find_of.f
@@ -0,0 +1,80 @@
1ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
2c
3c HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4c
5c This program is free software; you can redistribute it and/or modify
6c it under the terms of the GNU General Public License as published by
7c the Free Software Foundation; either version 2 of the License, or
8c (at your option) any later version.
9c
10c This program is distributed in the hope that it will be useful,
11c but WITHOUT ANY WARRANTY; without even the implied warranty of
12c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13c GNU General Public License for more details.
14c
15c You should have received a copy of the GNU General Public License
16c along with this program; if not, write to the Free Software
17c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18c
19
20 integer function find_of(s,n,c)
21 byte s(0:1),c(0:1)
22 integer i,m,n
23 m=mod(n,16)
24 do 10 i=0,m-1
25 if(c(s(i)).ne.0)go to 100
26 10 continue
27 do 20 i=m,n-1,16
28 if(c(s(i)).ne.0)go to 100
29 if(c(s(i+1)).ne.0)go to 101
30 if(c(s(i+2)).ne.0)go to 102
31 if(c(s(i+3)).ne.0)go to 103
32 if(c(s(i+4)).ne.0)go to 104
33 if(c(s(i+5)).ne.0)go to 105
34 if(c(s(i+6)).ne.0)go to 106
35 if(c(s(i+7)).ne.0)go to 107
36 if(c(s(i+8)).ne.0)go to 108
37 if(c(s(i+9)).ne.0)go to 109
38 if(c(s(i+10)).ne.0)go to 110
39 if(c(s(i+11)).ne.0)go to 111
40 if(c(s(i+12)).ne.0)go to 112
41 if(c(s(i+13)).ne.0)go to 113
42 if(c(s(i+14)).ne.0)go to 114
43 if(c(s(i+15)).ne.0)go to 115
44 20 continue
45 find_of=-1
46 return
47 100 find_of=i
48 return
49 101 find_of=i+1
50 return
51 102 find_of=i+2
52 return
53 103 find_of=i+3
54 return
55 104 find_of=i+4
56 return
57 105 find_of=i+5
58 return
59 106 find_of=i+6
60 return
61 107 find_of=i+7
62 return
63 108 find_of=i+8
64 return
65 109 find_of=i+9
66 return
67 110 find_of=i+10
68 return
69 111 find_of=i+11
70 return
71 112 find_of=i+12
72 return
73 113 find_of=i+13
74 return
75 114 find_of=i+14
76 return
77 115 find_of=i+15
78 return
79 end
80
diff --git a/src/mt/issue.cc b/src/mt/issue.cc
new file mode 100644
index 0000000..fa31f36
--- /dev/null
+++ b/src/mt/issue.cc
@@ -0,0 +1,51 @@
1/*************************************************************************
2 *
3 * HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#include <mt/issue.h>
21#include <signal.h>
22#include <sys/wait.h>
23
24void issue_t::run(mstream& out,const sref& in) throw(merror_t)
25{
26 int ip[2],op[2];
27 pipe(ip); pipe(op);
28 sigignore(SIGPIPE);
29 int pid=fork();
30 if(pid) {
31 close(ip[0]);
32 close(op[1]);
33 write(ip[1],in.data(),in.size());
34 close(ip[1]);
35 sref_t buf; int n;
36 while((n=read(op[0],buf,sizeof(sref_t)))>0) out.write(buf,n);
37 close(op[0]);
38 if(wait(0)<0) kill(pid,SIGKILL);
39 }
40 else {
41 close(ip[1]);
42 close(op[0]);
43 dup2(ip[0],0);
44 close(ip[0]);
45 dup2(op[1],1);
46 close(op[1]);
47 execv(*argv(),argv());
48 _exit(0);
49 }
50}
51
diff --git a/src/mt/issue.h b/src/mt/issue.h
new file mode 100644
index 0000000..27f6aa0
--- /dev/null
+++ b/src/mt/issue.h
@@ -0,0 +1,55 @@
1/*************************************************************************
2 *
3 * HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#ifndef ISSUEH
21#define ISSUEH
22
23#include <mt/mstring.h>
24#include <mt/mvec.h>
25#include <mt/split.h>
26
27// ISSUE A PIPED COMMAND
28//
29// This class is tuned to work in a mt environment.
30// The aim is to make this work locally as if it was
31// a single thread returning something to the stream out
32// depending on the input in.
33
34struct issue_t {
35 mrvec<char*> arg;
36
37 issue_t() {}
38 ~issue_t() { clear(); }
39
40 issue_t(const sref& s,const charset& ws=cset_ws) {
41 sref first,rest=s;
42 while(Split(first,rest,ws)) arg.push_back(first.news());
43 arg.push_back(0);
44 }
45
46 void clear() { for(int i=0;i<arg.size();i++) delete arg[i]; arg.clear(); }
47 void add(const sref& s) { arg.push_back(s.news()); }
48 void end() { arg.push_back(0); }
49 char* const* argv() const { return arg.begin(); }
50
51 void run(mstream& out,const sref& in) throw(merror_t);
52};
53
54#endif
55
diff --git a/src/mt/lock.cc b/src/mt/lock.cc
new file mode 100644
index 0000000..5b72967
--- /dev/null
+++ b/src/mt/lock.cc
@@ -0,0 +1,114 @@
1/*************************************************************************
2 *
3 * HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#include <mt/lock.h>
21#include <unistd.h>
22#include <fcntl.h>
23#include <errno.h>
24#include <sys/utsname.h>
25#include <signal.h>
26using namespace std;
27
28const mstring LOCK=".lock";
29
30void LockFile(const mstring& path,int prot) throw(merror_t)
31{
32 mstring name=path+LOCK; int fd;
33 while((fd=open(name.c_str(),O_CREAT|O_WRONLY|O_TRUNC|O_EXCL,prot))==-1&&
34 errno==EEXIST) sleep(1);
35 if(fd<0) THROW("lock: could not create lock file "<<name);
36 close(fd);
37}
38
39int remove(const char* path);
40void UnlockFile(const mstring& path)
41{
42 remove((path+LOCK).c_str());
43}
44
45///////////////////////////////////////////////////////////////////
46
47proclock_t::proclock_t(const mstring& p,int prot) : pid(0),path(p+LOCK)
48{
49 mstring buf,name=path;
50 int fd=open(path.c_str(),O_CREAT|O_WRONLY|O_TRUNC|O_EXCL,prot);
51 if(fd<0) {
52 if(errno==EEXIST) {
53 buf.load(path);
54 int oldpid=atoi(buf);
55 if(kill(oldpid,0)==0) THROW("proclock: already running as "<<buf)
56 else fd=open(path.c_str(),O_CREAT|O_WRONLY|O_TRUNC,prot);
57 }
58 else THROW("proclock: could not create lock file "<<path);
59 }
60 pid=getpid();
61 buf.convert("%d",pid);
62 write(fd,buf.data(),buf.size());
63 close(fd);
64}
65
66proclock_t::~proclock_t()
67{
68 if(getpid()==pid) remove(path.c_str());
69}
70
71///////////////////////////////////////////////////////////////////
72
73nodelock_t::nodelock_t(const mstring& p,int prot) : pid(0),path(p+LOCK)
74{
75 struct utsname uts; uname(&uts);
76 mstring buf;
77 int fd=open(path.c_str(),O_CREAT|O_WRONLY|O_TRUNC|O_EXCL,prot);
78 if(fd<0) {
79 if(errno==EEXIST) {
80 if(buf.load(path)>=0) {
81 if(buf.nempty()&&buf!=sref(uts.nodename))
82 THROW("nodelock: already locked on "<<buf);
83 }
84 else {
85 fd=open(path.c_str(),O_CREAT|O_WRONLY|O_TRUNC,prot);
86 pid=getpid();
87 buf=uts.nodename;
88 write(fd,buf.data(),buf.size());
89 close(fd);
90 }
91 }
92 else THROW("nodelock: could not create lock file "<<path);
93 }
94 else {
95 pid=getpid();
96 buf=uts.nodename;
97 write(fd,buf.data(),buf.size());
98 close(fd);
99 }
100}
101
102nodelock_t::~nodelock_t()
103{
104 if(getpid()==pid) remove(path.c_str());
105}
106
107///////////////////////////////////////////////////////////////////
108
109void ProcTerminate(const mstring& p,int stime)
110{
111 mstring buf,path=p+LOCK;
112 if(buf.load(path)>=0) while(!kill(atoi(buf),SIGTERM)) sleep(stime);
113}
114
diff --git a/src/mt/lock.h b/src/mt/lock.h
new file mode 100644
index 0000000..e019158
--- /dev/null
+++ b/src/mt/lock.h
@@ -0,0 +1,72 @@
1/*************************************************************************
2 *
3 * HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#ifndef LOCKH
21#define LOCKH
22
23#include <mt/mstring.h>
24
25// OFFERS TWO LOCKING MECHANISMS
26
27void LockFile(const mstring& path,int prot=0660) throw(merror_t);
28void UnlockFile(const mstring& path);
29
30// These functions create an exclusive lock on path by
31// creating a file path.lock.
32// Works well and is the same mechnism used by
33// mailing systems.
34
35////////////////////////////////////////////
36
37struct proclock_t {
38 pid_t pid;
39 mstring path;
40 proclock_t(const mstring& p,int prot=0660);
41 ~proclock_t();
42};
43
44#define PROCLOCK(p) proclock_t proclock(p)
45
46// The proclock class creates a file named path.lock
47// and stores the curent process id in it.
48// once the destructor is called in the same
49// process, the file is removed.
50
51////////////////////////////////////////////
52
53struct nodelock_t {
54 pid_t pid;
55 mstring path;
56 nodelock_t(const mstring& p,int prot=0660);
57 ~nodelock_t();
58};
59
60#define NODELOCK(p) nodelock_t nodelock(p)
61
62// The nodelock class creates a file named path.lock
63// and stores the curent network node name in it.
64// once the destructor is called in the same
65// process, the file is removed.
66
67////////////////////////////////////////////
68
69void ProcTerminate(const mstring& path,int stime=2);
70
71#endif
72
diff --git a/src/mt/lookup.cc b/src/mt/lookup.cc
new file mode 100644
index 0000000..c0e72c8
--- /dev/null
+++ b/src/mt/lookup.cc
@@ -0,0 +1,88 @@
1/*************************************************************************
2 *
3 * HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#include <mt/lookup.h>
21#include <mt/mvec.h>
22#include <mt/lock.h>
23#include <arpa/inet.h>
24#include <netinet/in.h>
25#include <sys/socket.h>
26
27const time_t VALIDSEC=120;
28static msvec<IPnode> cache;
29static mutex_t mutex;
30
31int Lookup(IPnode& node,const in_addr& ia)
32{
33 MLOCK(mutex);
34 IPnode* p=cache.begin();
35 time_t now=time(0);
36 while(p<cache.end()) {
37 if(now>p->valid) cache.erase(p);
38 else if(memcmp(&p->addr,&ia,sizeof(ia))==0) {p->valid=now+VALIDSEC;node=*p;return 1;}
39 else p++;
40 }
41 hostent hent;
42 sref_t buf;
43 int herr;
44 hostent* hp=0;
45 gethostbyaddr_r((const char*)&ia,sizeof(ia),AF_INET,
46 &hent,
47 buf,sizeof(sref_t),
48 &hp,
49 &herr);
50 if(!hp) return 0;
51 memcpy(&node.addr,hp->h_addr,sizeof(hp->h_length));
52 node.ip=inet_ntoa(node.addr);
53 node.name=hp->h_name;
54 node.valid=now+VALIDSEC;
55 cache.push_back(node);
56 return 1;
57}
58
59int Lookup(IPnode& node,const sref& s)
60{
61 MLOCK(mutex);
62 IPnode* p=cache.begin();
63 time_t now=time(0);
64 while(p<cache.end()) {
65 if(now>p->valid) cache.erase(p);
66 else if(p->ip==s||p->name==s) { p->valid=now+VALIDSEC; node=*p; return 1; }
67 else p++;
68 }
69 hostent hent;
70 sref_t sbuf,buf;
71 int herr;
72 hostent* hp=0;
73 for(int i=0;s[i];i++) if(s[i]!='.'&&(s[i]<'0'||s[i]>'9')) {
74 gethostbyname_r(s.copyto(sbuf),&hent,buf,sizeof(sref_t),&hp,&herr);
75 break;
76 }
77 if(!hp) {
78 unsigned long a=inet_addr(s.copyto(buf));
79 gethostbyaddr_r((char*)&a,sizeof(a),AF_INET,&hent,buf,sizeof(sref_t),&hp,&herr);
80 }
81 if(!hp) return 0;
82 memcpy(&node.addr,hp->h_addr,sizeof(hp->h_length));
83 node.ip=inet_ntoa(node.addr);
84 node.name=hp->h_name;
85 node.valid=now+VALIDSEC;
86 cache.push_back(node);
87 return 1;
88}
diff --git a/src/mt/lookup.h b/src/mt/lookup.h
new file mode 100644
index 0000000..d073766
--- /dev/null
+++ b/src/mt/lookup.h
@@ -0,0 +1,32 @@
1/*************************************************************************
2 *
3 * HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#ifndef LOOKUPH
21#define LOOKUPH
22
23#include <mt/mstring.h>
24#include <netdb.h>
25#include <netinet/in.h>
26
27struct IPnode { time_t valid; in_addr addr; mstring ip,name; };
28
29int Lookup(IPnode& node,const sref& s);
30int Lookup(IPnode& node,const in_addr& ia);
31
32#endif
diff --git a/src/mt/mlock.h b/src/mt/mlock.h
new file mode 100644
index 0000000..4639cf4
--- /dev/null
+++ b/src/mt/mlock.h
@@ -0,0 +1,48 @@
1/*************************************************************************
2 *
3 * HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#ifndef MLOCKH
21#define MLOCKH
22
23#if 1
24#include <pthread.h>
25typedef pthread_mutex_t mutex_t;
26typedef pthread_cond_t mtcond_t;
27const mutex_t MUTEX_INIT=PTHREAD_MUTEX_INITIALIZER;
28const mtcond_t MTCOND_INIT=PTHREAD_COND_INITIALIZER;
29struct mlock_t {
30 mutex_t* lock;
31
32 mlock_t(mutex_t& m) { pthread_mutex_lock(lock=&m); }
33 ~mlock_t() { if(lock) pthread_mutex_unlock(lock); }
34};
35#define MLOCK(m) mlock_t mlock(m)
36#define MSUSPEND(m,c) { MLOCK(m); pthread_cond_wait(&c,&m); }
37#define MCONTINUE(c) pthread_cond_signal(&c)
38#else
39typedef int mutex_t;
40typedef int mtcond_t;
41const mutex_t MUTEX_INIT=0;
42const mtcond_t MTCOND_INIT=0;
43#define MLOCK(m)
44#define MSUSPEND(m,c)
45#define MCONTINUE(c)
46#endif
47
48#endif
diff --git a/src/mt/mread.cc b/src/mt/mread.cc
new file mode 100644
index 0000000..da5a966
--- /dev/null
+++ b/src/mt/mread.cc
@@ -0,0 +1,135 @@
1/*************************************************************************
2 *
3 * HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#include <mt/mread.h>
21#include <mt/split.h>
22#include <poll.h>
23#include <signal.h>
24#include <errno.h>
25
26const int MSEC=4000;
27const int RETRY=3;
28const int TIMEOUT=2;
29
30//////////////////////////////////////////////////////////////////////////
31
32mread::mread() : fd(-1),buf()
33{
34}
35
36mread::mread(int f) : fd(f),buf()
37{
38}
39
40//////////////////////////////////////////////////////////////////////////
41
42void mread::clear()
43{
44 buf.clear();
45}
46
47int mread::poll()
48{
49 pollfd pfd={fd,POLLIN,0};
50 return ::poll(&pfd,1,MSEC);
51}
52
53int mread::read(char* s,int n)
54{
55 if(buf.empty()) {
56 int m=::read(fd,s,n);
57 for(int i=0;i<RETRY&&m<0&&errno==EAGAIN&&poll()>=0;i++) m=::read(fd,s,n);
58 if(m<0&&n) *s=0;
59 return m;
60 }
61 else {
62 if(n>buf.size()) n=buf.size();
63 memcpy(s,buf.data(),n);
64 buf.erase(0,n);
65 return n;
66 }
67}
68
69void mread::putback(const sref& s)
70{
71 if(s.nempty()) buf.insert(0,s);
72}
73
74//////////////////////////////////////////////////////////////////////////
75
76int mread::readx(char* s,int n)
77{
78 int tries=0,acc=0;
79 while(acc<n) {
80 int m=read(s+acc,n-acc);
81 if(m<0) return -1;
82 else if(m==0) {
83 if(poll()<0) return -1;
84 if(tries++>=TIMEOUT) return acc;
85 }
86 else {
87 acc+=m;
88 tries=0;
89 }
90 }
91 return acc;
92}
93
94//////////////////////////////////////////////////////////////////////////
95
96int mread::readln(char* s,int n)
97{
98 int tries=0,acc=0;
99 while(acc<n) {
100 int m=read(s+acc,n-acc);
101 if(m<0) return -1;
102 else if(m==0) {
103 if(poll()<0) return -1;
104 if(tries++>=TIMEOUT) return acc?-1:0;
105 }
106 else {
107 int p=sref(s+acc,m).find('\n')+1;
108 if(p>0) { acc+=p; putback(sref(s+acc,m-p)); return acc; }
109 else { acc+=m; tries=0; }
110 }
111 }
112 return acc;
113}
114
115int mread::readpara(char* s,int n)
116{
117 int tries=0,acc=0;
118 while(acc<n) {
119 int m=read(s+acc,n-acc);
120 if(m<0) return -1;
121 else if(m==0) {
122 if(poll()<0) return -1;
123 if(tries++>=TIMEOUT) return acc?-1:0;
124 }
125 else {
126 int found=0;
127 sref first,rest(s+acc,m);
128 while(Splitln(first,rest)) if(first.empty()) { found=1; break; }
129 if(found) { acc=rest.begin()-s; putback(rest); return acc; }
130 else { acc+=m; tries=0; }
131 }
132 }
133 return acc;
134}
135
diff --git a/src/mt/mread.h b/src/mt/mread.h
new file mode 100644
index 0000000..11516a2
--- /dev/null
+++ b/src/mt/mread.h
@@ -0,0 +1,63 @@
1/*************************************************************************
2 *
3 * HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#ifndef MREADH
21#define MREADH
22
23// These functions work with nonblocking pipes
24// as well as normal devices, and does not produce
25// any signals on pipe errors
26
27#include <mt/mstring.h>
28#include <unistd.h>
29#include <fcntl.h>
30
31class mread {
32public:
33 mread();
34 mread(int f);
35
36 void setfd(int f) { clear(); fd=f; }
37 int getfd() const { return fd; }
38
39 void setflag(int f) { fcntl(fd,F_SETFL,f); }
40 int getflag() const { return fcntl(fd,F_GETFL,0); }
41
42 // Basic, pipe-safe, normally non-blocking, reads
43 void clear();
44 int poll();
45 int read(char* s,int n);
46 void putback(const sref& s);
47
48 // Buffered reads
49 int readx(char* s,int n); // may timeout and return less than wanted
50 int readln(char* s,int n);
51 int readpara(char* s,int n);
52
53private:
54 int fd;
55 mstring buf;
56};
57
58// All functions return number of bytes written, or -1 on error.
59// Note that although ln and para continues to read until
60// it finds a newline or a paragraph, it may read more than that.
61// Use clear() to restore reading state
62
63#endif
diff --git a/src/mt/mset.cc b/src/mt/mset.cc
new file mode 100644
index 0000000..ec5b69e
--- /dev/null
+++ b/src/mt/mset.cc
@@ -0,0 +1,81 @@
1/*************************************************************************
2 *
3 * HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#include <mt/mset.h>
21#include <algorithm>
22using namespace std;
23
24mset::mset() : rpile() {}
25mset::mset(const sref& in) : rpile() {
26 sref first,rest=in;
27 while(Split(first,rest)) insert(first);
28}
29
30/////////////////////////////////////////////////////////////////////////////
31
32int mset::exist(const sref& t) const {
33 pair<const_iterator,const_iterator> p=equal_range(begin(),end(),t);
34 return p.first!=p.second;
35}
36int mset::insert(const sref& t) {
37 pair<iterator,iterator> p=equal_range(begin(),end(),t);
38 if(p.first==p.second) { rpile::insert(p.second,t); return 1; }
39 else return 0;
40}
41
42/////////////////////////////////////////////////////////////////////////////
43
44void mset::Union(const mset& a,const mset& b) {
45 clear();
46 for(int i=0;i<a.size();i++) insert(a[i]);
47 for(int i=0;i<b.size();i++) insert(b[i]);
48}
49void mset::Intersection(const mset& a,const mset& b) {
50 clear();
51 for(int i=0;i<a.size();i++) if(b.exist(a[i])) insert(a[i]);
52}
53void mset::Difference(const mset& a,const mset& b) {
54 clear();
55 for(int i=0;i<a.size();i++) if(!b.exist(a[i])) insert(a[i]);
56}
57
58/////////////////////////////////////////////////////////////////////////////
59
60mstream& operator<<(mstream& out,const mset& m) {
61 for(int i=0;i<m.size();i++) { if(i) out.put(' '); out<<m[i]; } return out;
62}
63
64/////////////////////////////////////////////////////////////////////////////
65
66int msset::exist(const mstring& t) const {
67 pair<const_iterator,const_iterator> p=equal_range(begin(),end(),t);
68 return p.first!=p.second;
69}
70int msset::insert(const mstring& t) {
71 pair<iterator,iterator> p=equal_range(begin(),end(),t);
72 if(p.first==p.second) { spile::insert(p.second,t); return 1; }
73 else return 0;
74}
75
76/////////////////////////////////////////////////////////////////////////////
77
78mstream& operator<<(mstream& out,const msset& m) {
79 for(int i=0;i<m.size();i++) { if(i) out.put(' '); out<<m[i]; } return out;
80}
81
diff --git a/src/mt/mset.h b/src/mt/mset.h
new file mode 100644
index 0000000..469166f
--- /dev/null
+++ b/src/mt/mset.h
@@ -0,0 +1,62 @@
1/*************************************************************************
2 *
3 * HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#ifndef MSETH
21#define MSETH
22
23#include <mt/split.h>
24#include <mt/mstring.h>
25#include <mt/mvec.h>
26
27typedef mrvec<sref> rpile;
28
29struct mset : public rpile
30{
31 typedef rpile::iterator iterator;
32 typedef rpile::const_iterator const_iterator;
33
34 mset();
35 mset(const sref& in);
36
37 int exist(const sref& t) const;
38 int insert(const sref& t);
39
40 void Union(const mset& a,const mset& b);
41 void Intersection(const mset& a,const mset& b);
42 void Difference(const mset& a,const mset& b);
43};
44
45mstream& operator<<(mstream& out,const mset& m);
46
47//////////////////////////////////////////////////////////
48
49typedef msvec<mstring> spile;
50
51struct msset : public spile
52{
53 typedef spile::iterator iterator;
54 typedef spile::const_iterator const_iterator;
55
56 int exist(const mstring& t) const;
57 int insert(const mstring& t);
58};
59
60mstream& operator<<(mstream& out,const mset& m);
61
62#endif
diff --git a/src/mt/msmap.cc b/src/mt/msmap.cc
new file mode 100644
index 0000000..c1284fb
--- /dev/null
+++ b/src/mt/msmap.cc
@@ -0,0 +1,84 @@
1/*************************************************************************
2 *
3 * HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#include <mt/msmap.h>
21#include <algorithm>
22using namespace std;
23
24const sref* rrmap::get(const sref& t) const
25{
26 pair<const_iterator,const_iterator> p=equal_range(begin(),end(),rrstring(t));
27 return p.first!=p.second?&p.first->second:0;
28}
29
30const sref* rrmap::add(const sref& t,const sref& s)
31{
32 rrstring tmp(t,s);
33 pair<iterator,iterator> p=equal_range(begin(),end(),tmp);
34 if(p.first!=p.second) return &(*p.first=tmp).second;
35 else return &insert(p.second,tmp)->second;
36}
37
38void rrmap::sort()
39{
40 ::sort(begin(),end());
41}
42
43////////////////////////////////////////////////////////////////
44
45int rimap::get(const sref& t) const
46{
47 pair<const_iterator,const_iterator> p=equal_range(begin(),end(),rimap_t(t));
48 return p.first!=p.second?p.first->at:-1;
49}
50
51int rimap::add(const sref& t,int at)
52{
53 rimap_t tmp(t,at);
54 pair<iterator,iterator> p=equal_range(begin(),end(),tmp);
55 if(p.first!=p.second) return (*p.first=tmp).at;
56 else return insert(p.second,tmp)->at;
57}
58
59void rimap::sort()
60{
61 ::sort(begin(),end());
62}
63
64////////////////////////////////////////////////////////////////
65
66const mstring* ssmap::get(const mstring& t) const
67{
68 pair<const_iterator,const_iterator> p=equal_range(begin(),end(),sstring(t));
69 return p.first!=p.second?&p.first->second:0;
70}
71
72const mstring* ssmap::add(const mstring& t,const mstring& s)
73{
74 sstring tmp(t,s);
75 pair<iterator,iterator> p=equal_range(begin(),end(),tmp);
76 if(p.first!=p.second) return &(*p.first=tmp).second;
77 else return &insert(p.second,tmp)->second;
78}
79
80void ssmap::sort()
81{
82 ::sort(begin(),end());
83}
84
diff --git a/src/mt/msmap.h b/src/mt/msmap.h
new file mode 100644
index 0000000..a719a7b
--- /dev/null
+++ b/src/mt/msmap.h
@@ -0,0 +1,89 @@
1/*************************************************************************
2 *
3 * HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#ifndef MSMAPH
21#define MSMAPH
22
23#include <mt/mstring.h>
24#include <mt/mvec.h>
25
26struct rrstring {
27 sref first,second;
28 rrstring() : first(),second() {}
29 explicit rrstring(const sref& a) : first(a),second() {}
30 rrstring(const sref& a,const sref& b) : first(a),second(b) {}
31};
32inline bool operator<(const rrstring& a,const rrstring& b) { return a.first<b.first; }
33
34typedef mrvec<rrstring> rrpile;
35
36struct rrmap : public rrpile
37{
38 typedef rrpile::iterator iterator;
39 typedef rrpile::const_iterator const_iterator;
40
41 const sref* get(const sref& t) const;
42 const sref* add(const sref& t,const sref& s);
43 void sort();
44};
45
46//////////////////////////////////////////////////////////////////
47
48struct rimap_t {
49 sref name;
50 int at;
51 rimap_t() : name(),at(0) {}
52 explicit rimap_t(const sref& a) : name(a),at(0) {}
53 rimap_t(const sref& a,int p) : name(a),at(p) {}
54};
55inline bool operator<(const rimap_t& a,const rimap_t& b) { return a.name<b.name; }
56
57struct rimap : public mrvec<rimap_t>
58{
59 typedef mrvec<rimap_t>::iterator iterator;
60 typedef mrvec<rimap_t>::const_iterator const_iterator;
61
62 int get(const sref& t) const;
63 int add(const sref& t,int at);
64 void sort();
65};
66
67//////////////////////////////////////////////////////////////////
68
69struct sstring {
70 mstring first,second;
71 sstring() : first(),second() {}
72 explicit sstring(const mstring& a) : first(a),second() {}
73 sstring(const mstring& a,const mstring& b) : first(a),second(b) {}
74};
75inline bool operator<(const sstring& a,const sstring& b) { return a.first<b.first; }
76
77typedef msvec<sstring> sspile;
78
79struct ssmap : public sspile
80{
81 typedef sspile::iterator iterator;
82 typedef sspile::const_iterator const_iterator;
83
84 const mstring* get(const mstring& t) const;
85 const mstring* add(const mstring& t,const mstring& s);
86 void sort();
87};
88
89#endif
diff --git a/src/mt/mstream.cc b/src/mt/mstream.cc
new file mode 100644
index 0000000..3d94936
--- /dev/null
+++ b/src/mt/mstream.cc
@@ -0,0 +1,72 @@
1/*************************************************************************
2 *
3 * HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#include <mt/mstream.h>
21#include <poll.h>
22#include <signal.h>
23
24const char cvt_form_f[]="%#.12f";
25const int MSEC=4000;
26
27sref ftoa(sref_t& buf,double f)
28{
29 char* e=buf+sprintf(buf,cvt_form_f,f)-1;
30 while(*e=='0') e--; if(*e=='.') e--;
31 return sref(buf,e-buf+1);
32}
33
34///////////////////////////////////////////////////////////
35
36int mstream::appc(char c) { return -1; }
37int mstream::appi(int i) { return -1; }
38int mstream::appf(double f) { return -1; }
39int mstream::apps(const sref& s) { return -1; }
40
41///////////////////////////////////////////////////////////
42
43int cvt_stream::appi(int i) { sref_t buf; return apps(itoa(buf,i)); }
44int cvt_stream::appf(double f) { sref_t buf; return apps(ftoa(buf,f)); }
45
46///////////////////////////////////////////////////////////
47
48int fp_stream::appc(char c) { return putc(c,fp)<0?-1:1; }
49int fp_stream::apps(const sref& s) { return fwrite(s.data(),s.size(),1,fp); }
50
51///////////////////////////////////////////////////////////
52
53int fd_stream::appc(char c) { return ::write(fd,&c,1); }
54int fd_stream::apps(const sref& s) { return ::write(fd,s.data(),s.size()); }
55
56///////////////////////////////////////////////////////////
57
58int pipe_stream::appc(char c) { return mwrite(&c,1); }
59int pipe_stream::apps(const sref& s) { return mwrite(s.data(),s.size()); }
60
61int pipe_stream::mwrite(const char* s,int n)
62{
63 int old=n;
64 while(n>0&&!hup) {
65 pollfd pfd={fd,POLLOUT,0};
66 if(::poll(&pfd,1,MSEC)<0) return hup=-1;
67 int m=::write(fd,s,n);
68 if(m<0) return hup=-1;
69 s+=m; n-=m;
70 }
71 return hup?-1:old;
72}
diff --git a/src/mt/mstream.h b/src/mt/mstream.h
new file mode 100644
index 0000000..4f5aeaf
--- /dev/null
+++ b/src/mt/mstream.h
@@ -0,0 +1,103 @@
1/*************************************************************************
2 *
3 * HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#ifndef MSTREAMH
21#define MSTREAMH
22
23#include <mt/stringref.h>
24#include <unistd.h>
25#include <stdio.h>
26
27///////////////////////////////////////////////////////////
28
29const char cvt_form_i[]="%d";
30
31///////////////////////////////////////////////////////////
32
33inline sref itoa(sref_t& buf,int i) { return sref(buf,sprintf(buf,cvt_form_i,i)); }
34sref ftoa(sref_t& buf,double f);
35
36///////////////////////////////////////////////////////////
37
38struct mstream {
39 virtual int appc(char c);
40 virtual int appi(int i);
41 virtual int appf(double f);
42 virtual int apps(const sref& s);
43
44 mstream& put(char c) { return appc(c),*this; }
45 int write(const char* s,int n) { return apps(sref(s,n)); }
46};
47
48inline mstream& operator<<(mstream& out,int i) { return out.appi(i),out; }
49inline mstream& operator<<(mstream& out,long l) { return out.appi(l),out; }
50inline mstream& operator<<(mstream& out,unsigned u) { return out.appi(u),out; }
51inline mstream& operator<<(mstream& out,unsigned long ul) { return out.appi(ul),out; }
52inline mstream& operator<<(mstream& out,double f) { return out.appf(f),out; }
53
54inline mstream& operator<<(mstream& out,const sref& s) { return out.apps(s),out; }
55inline mstream& operator<<(mstream& out,const char* s) { return out.apps(sref(s)),out; }
56
57///////////////////////////////////////////////////////////
58
59struct cvt_stream : public mstream {
60 int appi(int i);
61 int appf(double f);
62};
63
64///////////////////////////////////////////////////////////
65
66struct fp_stream : public cvt_stream {
67 FILE* fp;
68
69 int appc(char c);
70 int apps(const sref& s);
71
72 fp_stream(FILE* f) : fp(f) {}
73
74 int flush() { return fflush(fp); }
75};
76
77///////////////////////////////////////////////////////////
78
79struct fd_stream : public cvt_stream {
80 int fd;
81
82 int appc(char c);
83 int apps(const sref& s);
84
85 fd_stream(int f) : fd(f) {}
86};
87
88///////////////////////////////////////////////////////////
89
90struct pipe_stream : public cvt_stream {
91 int fd,hup;
92
93 int appc(char c);
94 int apps(const sref& s);
95
96 pipe_stream(int f) : fd(f),hup(0) {}
97
98 int mwrite(const char* s,int n);
99};
100
101///////////////////////////////////////////////////////////
102
103#endif
diff --git a/src/mt/mstring.cc b/src/mt/mstring.cc
new file mode 100644
index 0000000..7be82e3
--- /dev/null
+++ b/src/mt/mstring.cc
@@ -0,0 +1,139 @@
1/*************************************************************************
2 *
3 * HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#include <mt/mstring.h>
21#include <unistd.h>
22#include <fcntl.h>
23#include <sys/stat.h>
24#include <stdarg.h>
25
26uniheap<ms_mincaps> mstring::heap;
27
28///////////////////////////////////////////////////////////////////
29
30mstring::mstring() : sref(heap.push(),0),caps(ms_mincaps) {
31 map[dim]=0;
32}
33mstring::mstring(int n) : sref(heap.push(),0),caps(ms_mincaps) {
34 if(caps<n) { while(caps<n) caps<<=1; heap.pop(map); map=(char*)malloc(caps); }
35 map[dim=0]=0;
36}
37mstring::mstring(int n,char c) : sref(heap.push(),0),caps(ms_mincaps) {
38 resize(n);
39 memset(map,c,dim);
40}
41mstring::mstring(const char* s) : sref(heap.push(),0),caps(ms_mincaps) {
42 resize(strlen(s));
43 memcpy(map,s,dim);
44}
45mstring::mstring(const char* s,int n) : sref(heap.push(),0),caps(ms_mincaps) {
46 resize(n);
47 memcpy(map,s,dim);
48}
49mstring::mstring(const sref& s) : sref(heap.push(),0),caps(ms_mincaps) {
50 resize(s.size());
51 memcpy(map,s.data(),dim);
52}
53mstring::mstring(const mstring& s) : sref(heap.push(),0),caps(ms_mincaps) {
54 resize(s.dim);
55 memcpy(map,s.map,dim);
56}
57mstring::~mstring() {
58 if(caps==ms_mincaps) heap.pop(map);
59 else free(map);
60}
61
62///////////////////////////////////////////////////////////////////
63
64void mstring::erase(int pos,int n)
65{
66 if(pos<0) { pos+=dim; if(pos<0) pos=0; }
67 if(pos<dim) {
68 if(n<0) { n+=dim+1; if(n<0) n=0; }
69 if(n>=dim-pos) map[dim=pos]=0;
70 else { memmove(map+pos,map+pos+n,dim-pos-n); map[dim-=n]=0; }
71 }
72}
73
74void mstring::reserve(int n) {
75 if(caps<=n) {
76 if(caps==ms_mincaps) {
77 while(caps<=n) caps<<=1;
78 char* p=(char*)memcpy(malloc(caps),map,dim);
79 heap.pop(map);
80 map=p;
81 }
82 else {
83 while(caps<=n) caps<<=1;
84 map=(char*)realloc(map,caps);
85 }
86 }
87}
88
89///////////////////////////////////////////////////////////////////
90
91int mstring::load(const mstring& path)
92{
93 int fd=open(path.c_str(),O_RDONLY);
94 if(fd<0) return -1;
95 struct stat fs; fstat(fd,&fs);
96 resize(fs.st_size);
97 read(fd,map,dim);
98 close(fd);
99 return dim;
100}
101
102///////////////////////////////////////////////////////////////////
103
104mstring& mstring::convert(const char* format,...)
105{
106 sref_t buf;
107 va_list ap;
108 va_start(ap,format);
109 resize(vsprintf(buf,format,ap));
110 memcpy(map,buf,dim);
111 va_end(ap);
112 return *this;
113}
114
115///////////////////////////////////////////////////////////////////
116
117int swrite::appc(char c) { return mp->put(c),1; }
118int swrite::apps(const sref& s) { return mp->put(s),s.size(); }
119
120///////////////////////////////////////////////////////////////////
121
122int mswrite::appc(char c) { return m.put(c),1; }
123int mswrite::apps(const sref& s) { return m.put(s),s.size(); }
124
125///////////////////////////////////////////////////////////////////
126
127int merror_t::appc(char c) { return desc.put(c),1; }
128int merror_t::apps(const sref& s) { return desc.put(s),s.size(); }
129
130///////////////////////////////////////////////////////////////////
131
132void getline(mstring& m,FILE* fp,char end)
133{
134 m.clear();
135 int c=getc(fp);
136 while(c!=end&&c!=EOF) { m.append(1,c); c=getc(fp); }
137}
138
139
diff --git a/src/mt/mstring.h b/src/mt/mstring.h
new file mode 100644
index 0000000..be07c1a
--- /dev/null
+++ b/src/mt/mstring.h
@@ -0,0 +1,222 @@
1/*************************************************************************
2 *
3 * HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#ifndef MSTRINGH
21#define MSTRINGH
22
23#include <mt/mstream.h>
24#include <mt/uniheap.h>
25
26const int ms_mincaps=32;
27
28class mstring : public sref {
29public:
30 mstring();
31 explicit mstring(int n);
32 mstring(int n,char c);
33 mstring(const char* s);
34 mstring(const char* s,int n);
35 mstring(const sref& s);
36 mstring(const mstring& s);
37 ~mstring();
38
39 ////////////////////////////////////////////////////////////////
40
41 const char* c_str() const { return map; }
42 int capacity() const { return caps; }
43
44 void clear() { map[dim=0]=0; }
45
46 int own(const sref& s) const { int p=s.data()-map; return p>=0&&p<caps; }
47
48 ////////////////////////////////////////////////////////////////
49
50 void assign(int sdim,char c) {
51 resize(sdim);
52 memset(map,c,sdim);
53 }
54 void assign(const sref& s) {
55 reserve(s.size());
56 memmove(map,s.data(),s.size());
57 map[dim=s.size()]=0;
58 }
59
60 void put(char c) { if(dim+1>=caps) reserve(dim+1); map[dim++]=c; map[dim]=0; }
61 void put(const sref& s) {
62 reserve(dim+s.size());
63 memcpy(map+dim,s.data(),s.size());
64 map[dim+=s.size()]=0;
65 }
66
67 mstring& append(int sdim,char c) {
68 reserve(dim+sdim);
69 memset(map+dim,c,sdim);
70 map[dim+=sdim]=0;
71 return *this;
72 }
73
74 mstring& append(const sref& s) {
75 reserve(dim+s.size());
76 memmove(map+dim,s.data(),s.size());
77 map[dim+=s.size()]=0;
78 return *this;
79 }
80
81 int insert(int pos,int n) {
82 if(pos<0||pos>dim) return 0;
83 if(n) { reserve(dim+n); memmove(map+pos+n,map+pos,dim-pos); map[dim+=n]=0; }
84 return 1;
85 }
86
87 mstring& insert(int pos,int sdim,char c) {
88 if(insert(pos,sdim)) memset(map+pos,c,sdim);
89 return *this;
90 }
91 mstring& insert(int pos,const sref& s) {
92 if(insert(pos,s.size())) memcpy(map+pos,s.data(),s.size());
93 return *this;
94 }
95
96 mstring& replace(int pos,int n,int sdim,char c) {
97 if(insert(pos+n,sdim-n)) memset(map+pos,c,sdim);
98 return *this;
99 }
100 mstring& replace(int pos,int n,const sref& s) {
101 if(insert(pos+n,s.size()-n)) memcpy(map+pos,s.data(),s.size());
102 return *this;
103 }
104
105 ////////////////////////////////////////////////////////////////
106
107 void erase(int pos,int n=-1);
108 void reserve(int n);
109 void resize(int n) { reserve(n); map[dim=n]=0; }
110
111 ////////////////////////////////////////////////////////////////
112
113 mstring& operator=(const mstring& s) { assign(s); return *this; }
114 mstring& operator=(const sref& s) { assign(s); return *this; }
115 mstring& operator=(char c) { assign(1,c); return *this; }
116
117 mstring& operator+=(const sref& s) { return append(s); }
118 mstring& operator+=(char c) { return append(1,c); }
119
120 ////////////////////////////////////////////////////////////////
121
122 int load(const mstring& path);
123
124 ////////////////////////////////////////////////////////////////
125
126 // NOTE: if you apply convert to %s or any unbound data,
127 // you're in trouble. Internal buffer is sref_t.
128
129 mstring& convert(const char* format,...);
130
131protected:
132 static uniheap<ms_mincaps> heap;
133private:
134 int caps;
135};
136
137///////////////////////////////////////////////////////////////////
138
139inline void swap(mstring& a,mstring& b)
140{
141 char buf[sizeof(mstring)];
142 memcpy(buf,&a,sizeof(mstring));
143 memcpy(&a,&b,sizeof(mstring));
144 memcpy(&b,buf,sizeof(mstring));
145}
146
147///////////////////////////////////////////////////////////////////
148
149inline mstring operator+(const sref& a,const sref& b)
150{
151 return mstring(a).append(b);
152}
153inline mstring operator+(const sref& a,char b) {
154 return mstring(a).append(1,b);
155}
156inline mstring operator+(char a,const sref& b) {
157 return mstring(1,a).append(b);
158}
159
160///////////////////////////////////////////////////////////////////
161
162inline mstring btoa(int b) { return mstring(1,b?'1':'0'); }
163inline mstring itoa(int i) { sref_t buf; return mstring(itoa(buf,i)); }
164inline mstring ftoa(double f) { sref_t buf; return mstring(ftoa(buf,f)); }
165
166///////////////////////////////////////////////////////////////////
167
168const mstring ms_empty;
169
170///////////////////////////////////////////////////////////////////
171
172struct swrite : public cvt_stream {
173 mstring* mp;
174
175 int appc(char c);
176 int apps(const sref& s);
177
178 swrite() : mp(0) {}
179 swrite(mstring& m) : mp(&m) { mp->clear(); }
180
181 swrite& operator()(mstring& m) { (mp=&m)->clear(); return *this; }
182 swrite& hold(mstring& m) { mp=&m; return *this; }
183};
184
185///////////////////////////////////////////////////////////////////
186
187class mswrite : public cvt_stream {
188public:
189 mstring m;
190
191 int appc(char c);
192 int apps(const sref& s);
193
194 const mstring& str() const { return m; } // compatibility
195 void clear() { m.clear(); }
196
197 mswrite() : m() {}
198private:
199 mswrite(mstring&) {} // make no mistakes due to similarity with swrite
200};
201
202///////////////////////////////////////////////////////////////////
203
204struct merror_t : public cvt_stream {
205 int num;
206 mstring desc;
207
208 int appc(char c);
209 int apps(const sref& s);
210
211 merror_t(int n) : num(n),desc() {}
212};
213
214#define THROW(x) { merror_t merr(0); merr<<x; throw merr; }
215
216///////////////////////////////////////////////////////////////////
217
218void getline(mstring& m,FILE* fp,char end='\n');
219
220///////////////////////////////////////////////////////////////////
221
222#endif
diff --git a/src/mt/mvec.h b/src/mt/mvec.h
new file mode 100644
index 0000000..9f31c1e
--- /dev/null
+++ b/src/mt/mvec.h
@@ -0,0 +1,149 @@
1/*************************************************************************
2 *
3 * HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#ifndef MVECH
21#define MVECH
22
23#include <malloc.h>
24#include <string.h>
25#include <new>
26
27const int mv_mincaps=16;
28
29template <class T> class mrvec {
30public:
31 typedef T* iterator;
32 typedef const T* const_iterator;
33
34 mrvec():
35 map((T*)malloc(mv_mincaps*sizeof(T))),dim(0),caps(mv_mincaps) {}
36 mrvec(int n):
37 map((T*)malloc(mv_mincaps*sizeof(T))),dim(0),caps(mv_mincaps) { resize(n); }
38 ~mrvec() { free(map); }
39
40 int size() const { return dim; }
41 int capacity() const { return caps; }
42
43 bool empty() const { return dim==0; }
44 bool nempty() const { return dim!=0; }
45
46 T& at(int pos) { return map[pos]; }
47 const T& at(int pos) const { return map[pos]; }
48
49 T& operator[](int pos) { return map[pos]; }
50 const T& operator[](int pos) const { return map[pos]; }
51
52 iterator begin() { return map; }
53 const_iterator begin() const { return map; }
54
55 iterator end() { return map+dim; }
56 const_iterator end() const { return map+dim; }
57
58 T& front() { return map[0]; }
59 const T& front() const { return map[0]; }
60
61 T& back() { return map[dim?dim-1:0]; }
62 const T& back() const { return map[dim?dim-1:0]; }
63
64 ////////////////////////////////////////////////////////////////
65
66 void clear() { dim=0; }
67
68 iterator insert(iterator it,const T& s) {
69 int pos=it-map; ins(pos,1); return &(map[pos]=s);
70 }
71 void insert(iterator it,int n,const T& s) {
72 int pos=it-map; ins(pos,n); while(n--) map[pos++]=s;
73 }
74 void insert(iterator it,const_iterator p,const_iterator e) {
75 int pos=it-map; ins(pos,e-p); while(p<e) map[pos++]=*p++;
76 }
77 iterator erase(iterator it) {
78 int pos=it-map; ins(pos+1,-1); return map+pos;
79 }
80
81 void push_back(const T& s) { reserve(dim+1); map[dim++]=s; }
82 void pop_back(const T& s) { if(dim) --dim; }
83
84 ////////////////////////////////////////////////////////////////
85
86 void reserve(int n) {
87 if(caps<n) { while(caps<n) caps<<=1; map=(T*)realloc(map,caps*sizeof(T)); }
88 }
89 void resize(int n) { reserve(n); dim=n; }
90
91 ////////////////////////////////////////////////////////////////
92
93protected:
94 mrvec(const mrvec&) {}
95 void operator=(const mrvec&) {}
96
97 void ins(int pos,int n) {
98 if(n) { reserve(dim+n); memmove(map+pos+n,map+pos,(dim-pos)*sizeof(T)); dim+=n; }
99 }
100
101 T* map;
102 int dim,caps;
103};
104
105template <class T> class msvec : public mrvec<T> {
106public:
107 using mrvec<T>::map;
108 using mrvec<T>::dim;
109 typedef typename mrvec<T>::iterator iterator;
110 typedef typename mrvec<T>::const_iterator const_iterator;
111
112 msvec() : mrvec<T>() {}
113 msvec(int n) : mrvec<T>(n) { for(int i=0;i<dim;i++) new (map+i) T(); }
114 ~msvec() { while(dim) map[--dim].~T(); }
115
116 ////////////////////////////////////////////////////////////////
117
118 void clear() { while(dim) map[--dim].~T(); }
119
120 iterator insert(iterator it,const T& s) {
121 int pos=it-map; mrvec<T>::ins(pos,1); return new(map+pos) T(s);
122 }
123 void insert(iterator it,int n,const T& s) {
124 int pos=it-map; mrvec<T>::ins(pos,n); while(n--) new(map+pos++) T(s);
125 }
126 void insert(iterator it,const_iterator p,const_iterator e) {
127 int pos=it-map; mrvec<T>::ins(pos,e-p); while(p<e) new(map+pos++) T(*p++);
128 }
129 iterator erase(iterator it) {
130 it->~T(); int pos=it-map; mrvec<T>::ins(pos+1,-1); return map+pos;
131 }
132
133 void push_back(const T& s) { reserve(dim+1); new(map+dim++) T(s); }
134 void pop_back(const T& s) { if(dim) map[--dim].~T(); }
135
136 ////////////////////////////////////////////////////////////////
137
138 void resize(int n) {
139 while(dim>n) map[--dim].~T();
140 mrvec<T>::reserve(n);
141 while(dim<n) new (map+dim++) T();
142 }
143
144protected:
145 msvec(const msvec&) {}
146 void operator=(const msvec&) {}
147};
148
149#endif
diff --git a/src/mt/qran.h b/src/mt/qran.h
new file mode 100644
index 0000000..10f9a6f
--- /dev/null
+++ b/src/mt/qran.h
@@ -0,0 +1,34 @@
1/*************************************************************************
2 *
3 * HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#ifndef QRANH
21#define QRANH
22
23#include <math.h>
24
25inline double QUniform(unsigned long& q) {
26 q=1664525L*q+1013904223L;
27 unsigned long long s=q;s<<=20;s|=(1023ULL<<52);return *(double*)&s-1;
28}
29inline int QRanBit(unsigned long& q) {
30 if(q&131072U) { q=((q^19U)<<1)|1U; return 1; }
31 else { q<<=1; return 0; }
32}
33
34#endif
diff --git a/src/mt/random.cc b/src/mt/random.cc
new file mode 100644
index 0000000..87a4c8c
--- /dev/null
+++ b/src/mt/random.cc
@@ -0,0 +1,95 @@
1/*************************************************************************
2 *
3 * HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#include <mt/random.h>
21#include <mt/mlock.h>
22#include <time.h>
23
24//////////////////////////////////////////////////////
25//
26// This file implements some routines from NumRec
27//
28
29const int NTAB=32; // NOTE: change in header if changing this
30
31const int IA=16807;
32const int IM=2147483647;
33const float AM=1/float(IM);
34const int IQ=127773;
35const int IR=2836;
36const int NDIV=1+(IM-1)/NTAB;
37const float EPS=1.2e-7;
38const float RNMX=1-EPS;
39
40static int idum,iy,iv[32],flag;
41static float extra;
42static int inited;
43static mutex_t mutex;
44
45unsigned long RandomInit(unsigned long seed)
46{
47 inited=1;
48 idum=seed?seed:1;
49 for(int j=NTAB+7;j>=0;j--) {
50 int k=idum/IQ;
51 idum=IA*(idum-k*IQ)-IR*k;
52 if(idum<0) idum+=IM;
53 if(j<NTAB) iv[j]=idum;
54 }
55 iy=iv[0];
56 return seed;
57}
58
59float Uniform()
60{
61 MLOCK(mutex);
62 if(!inited) RandomInit(time(0));
63 int k=idum/IQ;
64 idum=IA*(idum-k*IQ)-IR*k;
65 if(idum<0) idum+=IM;
66 int j=iy/NDIV;
67 iy=iv[j];
68 iv[j]=idum;
69 float temp=AM*iy; if(temp>RNMX) temp=RNMX;
70 return temp;
71}
72
73float Exponential()
74{
75 return -log(Uniform());
76}
77
78float Gaussian()
79{
80 MLOCK(mutex);
81 float v1,v2,rsq;
82 if(flag) {
83 flag=0;
84 return extra;
85 } else {
86 do {
87 v1=2*Uniform()-1;
88 v2=2*Uniform()-1;
89 rsq=v1*v1+v2*v2;
90 } while(rsq>=1||rsq<=0);
91 float fac=sqrt(-2*log(rsq)/rsq);
92 flag=1; extra=v1*fac;
93 return v2*fac;
94 }
95}
diff --git a/src/mt/random.h b/src/mt/random.h
new file mode 100644
index 0000000..196beae
--- /dev/null
+++ b/src/mt/random.h
@@ -0,0 +1,39 @@
1/*************************************************************************
2 *
3 * HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#ifndef RANDOMH
21#define RANDOMH
22
23#include <mt/qran.h>
24
25///////////////////////////////////////////////////////////////////
26//
27// Uniform distribution ]x0..x1[
28//
29// Granularity approx 1.2e-7, ie more than 1e6 different values
30// Perodicity approx 1e8
31//
32
33unsigned long RandomInit(unsigned long seed);
34
35float Uniform();
36float Exponential();
37float Gaussian();
38
39#endif
diff --git a/src/mt/rfind_not_of.f b/src/mt/rfind_not_of.f
new file mode 100644
index 0000000..04a42d6
--- /dev/null
+++ b/src/mt/rfind_not_of.f
@@ -0,0 +1,80 @@
1ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
2c
3c HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4c
5c This program is free software; you can redistribute it and/or modify
6c it under the terms of the GNU General Public License as published by
7c the Free Software Foundation; either version 2 of the License, or
8c (at your option) any later version.
9c
10c This program is distributed in the hope that it will be useful,
11c but WITHOUT ANY WARRANTY; without even the implied warranty of
12c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13c GNU General Public License for more details.
14c
15c You should have received a copy of the GNU General Public License
16c along with this program; if not, write to the Free Software
17c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18c
19
20 integer function rfind_not_of(s,n,c)
21 byte s(0:1),c(0:1)
22 integer i,m,n
23 m=mod(n,16)
24 do 10 i=n-16,m,-16
25 if(c(s(i+15)).eq.0)go to 115
26 if(c(s(i+14)).eq.0)go to 114
27 if(c(s(i+13)).eq.0)go to 113
28 if(c(s(i+12)).eq.0)go to 112
29 if(c(s(i+11)).eq.0)go to 111
30 if(c(s(i+10)).eq.0)go to 110
31 if(c(s(i+9)).eq.0)go to 109
32 if(c(s(i+8)).eq.0)go to 108
33 if(c(s(i+7)).eq.0)go to 107
34 if(c(s(i+6)).eq.0)go to 106
35 if(c(s(i+5)).eq.0)go to 105
36 if(c(s(i+4)).eq.0)go to 104
37 if(c(s(i+3)).eq.0)go to 103
38 if(c(s(i+2)).eq.0)go to 102
39 if(c(s(i+1)).eq.0)go to 101
40 if(c(s(i)).eq.0)go to 100
41 10 continue
42 do 20 i=m-1,0,-1
43 if(c(s(i)).eq.0)go to 100
44 20 continue
45 rfind_not_of=-1
46 return
47 100 rfind_not_of=i
48 return
49 101 rfind_not_of=i+1
50 return
51 102 rfind_not_of=i+2
52 return
53 103 rfind_not_of=i+3
54 return
55 104 rfind_not_of=i+4
56 return
57 105 rfind_not_of=i+5
58 return
59 106 rfind_not_of=i+6
60 return
61 107 rfind_not_of=i+7
62 return
63 108 rfind_not_of=i+8
64 return
65 109 rfind_not_of=i+9
66 return
67 110 rfind_not_of=i+10
68 return
69 111 rfind_not_of=i+11
70 return
71 112 rfind_not_of=i+12
72 return
73 113 rfind_not_of=i+13
74 return
75 114 rfind_not_of=i+14
76 return
77 115 rfind_not_of=i+15
78 return
79 end
80
diff --git a/src/mt/rfind_of.f b/src/mt/rfind_of.f
new file mode 100644
index 0000000..5fa0931
--- /dev/null
+++ b/src/mt/rfind_of.f
@@ -0,0 +1,80 @@
1ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
2c
3c HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4c
5c This program is free software; you can redistribute it and/or modify
6c it under the terms of the GNU General Public License as published by
7c the Free Software Foundation; either version 2 of the License, or
8c (at your option) any later version.
9c
10c This program is distributed in the hope that it will be useful,
11c but WITHOUT ANY WARRANTY; without even the implied warranty of
12c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13c GNU General Public License for more details.
14c
15c You should have received a copy of the GNU General Public License
16c along with this program; if not, write to the Free Software
17c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18c
19
20 integer function rfind_of(s,n,c)
21 byte s(0:1),c(0:1)
22 integer i,m,n
23 m=mod(n,16)
24 do 10 i=n-16,m,-16
25 if(c(s(i+15)).ne.0)go to 115
26 if(c(s(i+14)).ne.0)go to 114
27 if(c(s(i+13)).ne.0)go to 113
28 if(c(s(i+12)).ne.0)go to 112
29 if(c(s(i+11)).ne.0)go to 111
30 if(c(s(i+10)).ne.0)go to 110
31 if(c(s(i+9)).ne.0)go to 109
32 if(c(s(i+8)).ne.0)go to 108
33 if(c(s(i+7)).ne.0)go to 107
34 if(c(s(i+6)).ne.0)go to 106
35 if(c(s(i+5)).ne.0)go to 105
36 if(c(s(i+4)).ne.0)go to 104
37 if(c(s(i+3)).ne.0)go to 103
38 if(c(s(i+2)).ne.0)go to 102
39 if(c(s(i+1)).ne.0)go to 101
40 if(c(s(i)).ne.0)go to 100
41 10 continue
42 do 20 i=m-1,0,-1
43 if(c(s(i)).ne.0)go to 100
44 20 continue
45 rfind_of=-1
46 return
47 100 rfind_of=i
48 return
49 101 rfind_of=i+1
50 return
51 102 rfind_of=i+2
52 return
53 103 rfind_of=i+3
54 return
55 104 rfind_of=i+4
56 return
57 105 rfind_of=i+5
58 return
59 106 rfind_of=i+6
60 return
61 107 rfind_of=i+7
62 return
63 108 rfind_of=i+8
64 return
65 109 rfind_of=i+9
66 return
67 110 rfind_of=i+10
68 return
69 111 rfind_of=i+11
70 return
71 112 rfind_of=i+12
72 return
73 113 rfind_of=i+13
74 return
75 114 rfind_of=i+14
76 return
77 115 rfind_of=i+15
78 return
79 end
80
diff --git a/src/mt/scomptab.f b/src/mt/scomptab.f
new file mode 100644
index 0000000..4a8a286
--- /dev/null
+++ b/src/mt/scomptab.f
@@ -0,0 +1,44 @@
1ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
2c
3c HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4c
5c This program is free software; you can redistribute it and/or modify
6c it under the terms of the GNU General Public License as published by
7c the Free Software Foundation; either version 2 of the License, or
8c (at your option) any later version.
9c
10c This program is distributed in the hope that it will be useful,
11c but WITHOUT ANY WARRANTY; without even the implied warranty of
12c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13c GNU General Public License for more details.
14c
15c You should have received a copy of the GNU General Public License
16c along with this program; if not, write to the Free Software
17c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18c
19
20 integer function scomptab(s,c,n,tab)
21 byte s(0:1),c(0:1),tab(0:1)
22 integer i,m,n
23 m=mod(n,4)
24 do 10 i=0,m-1
25 if(tab(s(i)).ne.tab(c(i)))go to 100
26 10 continue
27 do 20 i=m,n-1,4
28 if(tab(s(i)).ne.tab(c(i)))go to 100
29 if(tab(s(i+1)).ne.tab(c(i+1)))go to 101
30 if(tab(s(i+2)).ne.tab(c(i+2)))go to 102
31 if(tab(s(i+3)).ne.tab(c(i+3)))go to 103
32 20 continue
33 scomptab=0
34 return
35 100 scomptab=tab(s(i))-tab(c(i))
36 return
37 101 scomptab=tab(s(i+1))-tab(c(i+1))
38 return
39 102 scomptab=tab(s(i+2))-tab(c(i+2))
40 return
41 103 scomptab=tab(s(i+3))-tab(c(i+3))
42 return
43 end
44
diff --git a/src/mt/sconvert.f b/src/mt/sconvert.f
new file mode 100644
index 0000000..e887610
--- /dev/null
+++ b/src/mt/sconvert.f
@@ -0,0 +1,35 @@
1ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
2c
3c HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4c
5c This program is free software; you can redistribute it and/or modify
6c it under the terms of the GNU General Public License as published by
7c the Free Software Foundation; either version 2 of the License, or
8c (at your option) any later version.
9c
10c This program is distributed in the hope that it will be useful,
11c but WITHOUT ANY WARRANTY; without even the implied warranty of
12c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13c GNU General Public License for more details.
14c
15c You should have received a copy of the GNU General Public License
16c along with this program; if not, write to the Free Software
17c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18c
19
20 subroutine sconvert(s,sn,tab)
21 byte s(0:1),tab(0:1)
22 integer i,m,sn
23 m=mod(sn,4)
24 do 10 i=0,m-1
25 s(i)=tab(s(i))
26 10 continue
27 do 20 i=m,sn-1,4
28 s(i)=tab(s(i))
29 s(i+1)=tab(s(i+1))
30 s(i+2)=tab(s(i+2))
31 s(i+3)=tab(s(i+3))
32 20 continue
33 return
34 end
35
diff --git a/src/mt/sfind.f b/src/mt/sfind.f
new file mode 100644
index 0000000..2cc2954
--- /dev/null
+++ b/src/mt/sfind.f
@@ -0,0 +1,40 @@
1ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
2c
3c HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4c
5c This program is free software; you can redistribute it and/or modify
6c it under the terms of the GNU General Public License as published by
7c the Free Software Foundation; either version 2 of the License, or
8c (at your option) any later version.
9c
10c This program is distributed in the hope that it will be useful,
11c but WITHOUT ANY WARRANTY; without even the implied warranty of
12c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13c GNU General Public License for more details.
14c
15c You should have received a copy of the GNU General Public License
16c along with this program; if not, write to the Free Software
17c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18c
19
20 integer function sfind(s,sn,c,cn)
21 character s(0:1),c(0:1)
22 integer i,j,m,sn,cn
23 m=mod(cn,4)
24 do 10 i=0,sn-1
25 do 20 j=0,m-1
26 if(s(i+j).ne.c(j))go to 50
27 20 continue
28 do 30 j=m,cn-1,4
29 if(s(i+j).ne.c(j))go to 50
30 if(s(i+j+1).ne.c(j+1))go to 50
31 if(s(i+j+2).ne.c(j+2))go to 50
32 if(s(i+j+3).ne.c(j+3))go to 50
33 30 continue
34 50 if(j.eq.cn)go to 100
35 10 continue
36 sfind=-1
37 return
38 100 sfind=i
39 return
40 end
diff --git a/src/mt/sfindtab.f b/src/mt/sfindtab.f
new file mode 100644
index 0000000..b4e148e
--- /dev/null
+++ b/src/mt/sfindtab.f
@@ -0,0 +1,40 @@
1ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
2c
3c HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4c
5c This program is free software; you can redistribute it and/or modify
6c it under the terms of the GNU General Public License as published by
7c the Free Software Foundation; either version 2 of the License, or
8c (at your option) any later version.
9c
10c This program is distributed in the hope that it will be useful,
11c but WITHOUT ANY WARRANTY; without even the implied warranty of
12c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13c GNU General Public License for more details.
14c
15c You should have received a copy of the GNU General Public License
16c along with this program; if not, write to the Free Software
17c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18c
19
20 integer function sfindtab(s,sn,c,cn,tab)
21 byte s(0:1),c(0:1),tab(0:1)
22 integer i,j,m,sn,cn
23 m=mod(cn,4)
24 do 10 i=0,sn-1
25 do 20 j=0,m-1
26 if(tab(s(i+j)).ne.tab(c(j)))go to 50
27 20 continue
28 do 30 j=m,cn-1,4
29 if(tab(s(i+j)).ne.tab(c(j)))go to 50
30 if(tab(s(i+j+1)).ne.tab(c(j+1)))go to 50
31 if(tab(s(i+j+2)).ne.tab(c(j+2)))go to 50
32 if(tab(s(i+j+3)).ne.tab(c(j+3)))go to 50
33 30 continue
34 50 if(j.eq.cn)go to 100
35 10 continue
36 sfindtab=-1
37 return
38 100 sfindtab=i
39 return
40 end
diff --git a/src/mt/skip_parentesis.f b/src/mt/skip_parentesis.f
new file mode 100644
index 0000000..1104c8f
--- /dev/null
+++ b/src/mt/skip_parentesis.f
@@ -0,0 +1,42 @@
1ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
2c
3c HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4c
5c This program is free software; you can redistribute it and/or modify
6c it under the terms of the GNU General Public License as published by
7c the Free Software Foundation; either version 2 of the License, or
8c (at your option) any later version.
9c
10c This program is distributed in the hope that it will be useful,
11c but WITHOUT ANY WARRANTY; without even the implied warranty of
12c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13c GNU General Public License for more details.
14c
15c You should have received a copy of the GNU General Public License
16c along with this program; if not, write to the Free Software
17c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18c
19
20 integer function skip_parentesis(s,n,left,right,esc)
21 character s(0:1),left,right,esc
22 integer i,n,cnt
23 if(n.eq.0)go to 40
24 if(s(0).ne.left)go to 40
25 cnt=1
26 do 10 i=1,n-1
27 if(s(i-1).eq.esc)go to 10
28 if(s(i).eq.right)then
29 cnt=cnt-1
30 if(cnt.eq.0)go to 30
31 else if(s(i).eq.left)then
32 cnt=cnt+1
33 end if
34 10 continue
35 20 skip_parentesis=-1
36 return
37 30 skip_parentesis=i+1
38 return
39 40 skip_parentesis=0
40 return
41 end
42
diff --git a/src/mt/split.h b/src/mt/split.h
new file mode 100644
index 0000000..52e66e3
--- /dev/null
+++ b/src/mt/split.h
@@ -0,0 +1,72 @@
1/*************************************************************************
2 *
3 * HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#ifndef MSPLITH
21#define MSPLITH
22
23#include <mt/stringref.h>
24
25inline sref Skip(const sref& a,const charset& ws=cset_ws) {
26 return a.right_first_not_of(ws);
27}
28
29inline sref Trim(const sref& a,const charset& ws=cset_ws) {
30 return a.right_first_not_of(ws).leftand_last_not_of(ws);
31}
32
33inline sref Trim(const sref& a,const bracket& enc,const charset& ws=cset_ws) {
34 sref s=a.right_first_not_of(ws).leftand_last_not_of(ws);
35 while(s.nempty()&&s.skip(enc)==s.size())
36 s=s(1,-3).right_first_not_of(ws).leftand_last_not_of(ws);
37 return s;
38}
39
40inline sref First(const sref& a,const charset& ws=cset_ws) {
41 return a.right_first_not_of(ws).left_first_of(ws);
42}
43
44inline sref Rest(const sref& a,const charset& ws=cset_ws) {
45 return a.right_first_not_of(ws).right_first_of(ws).right_first_not_of(ws);
46}
47
48inline sref Last(const sref& a,const charset& ws=cset_ws) {
49 sref p=a.leftand_last_not_of(ws);
50 sref e=p.past_last_of(ws);
51 return e.nempty()?e:p;
52}
53
54inline int Split(sref& first,sref& rest,const charset& ws=cset_ws) {
55 rest=rest.right_first_not_of(ws);
56 int s=rest.find_of(ws);
57 first=rest.left(s);
58 rest=rest.right(s);
59 return first.nempty();
60}
61
62inline int Splitln(sref& first,sref& rest) {
63 int s=rest.find_of(cset_newl);
64 first=rest.left(s);
65 rest=rest.right(s).past_nl();
66 return first.begin()!=rest.begin();
67}
68
69typedef int (*split_t)(sref& first,sref& rest);
70
71#endif
72
diff --git a/src/mt/srfind.f b/src/mt/srfind.f
new file mode 100644
index 0000000..24f4fb4
--- /dev/null
+++ b/src/mt/srfind.f
@@ -0,0 +1,40 @@
1ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
2c
3c HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4c
5c This program is free software; you can redistribute it and/or modify
6c it under the terms of the GNU General Public License as published by
7c the Free Software Foundation; either version 2 of the License, or
8c (at your option) any later version.
9c
10c This program is distributed in the hope that it will be useful,
11c but WITHOUT ANY WARRANTY; without even the implied warranty of
12c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13c GNU General Public License for more details.
14c
15c You should have received a copy of the GNU General Public License
16c along with this program; if not, write to the Free Software
17c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18c
19
20 integer function srfind(s,sn,c,cn)
21 character s(0:1),c(0:1)
22 integer i,j,m,sn,cn
23 m=mod(cn,4)
24 do 10 i=sn-1,0,-1
25 do 20 j=0,m-1
26 if(s(i+j).ne.c(j))go to 50
27 20 continue
28 do 30 j=m,cn-1,4
29 if(s(i+j).ne.c(j))go to 50
30 if(s(i+j+1).ne.c(j+1))go to 50
31 if(s(i+j+2).ne.c(j+2))go to 50
32 if(s(i+j+3).ne.c(j+3))go to 50
33 30 continue
34 50 if(j.eq.cn)go to 100
35 10 continue
36 srfind=-1
37 return
38 100 srfind=i
39 return
40 end
diff --git a/src/mt/srfindtab.f b/src/mt/srfindtab.f
new file mode 100644
index 0000000..ad5fdd4
--- /dev/null
+++ b/src/mt/srfindtab.f
@@ -0,0 +1,40 @@
1ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
2c
3c HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4c
5c This program is free software; you can redistribute it and/or modify
6c it under the terms of the GNU General Public License as published by
7c the Free Software Foundation; either version 2 of the License, or
8c (at your option) any later version.
9c
10c This program is distributed in the hope that it will be useful,
11c but WITHOUT ANY WARRANTY; without even the implied warranty of
12c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13c GNU General Public License for more details.
14c
15c You should have received a copy of the GNU General Public License
16c along with this program; if not, write to the Free Software
17c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18c
19
20 integer function srfindtab(s,sn,c,cn,tab)
21 byte s(0:1),c(0:1),tab(0:1)
22 integer i,j,m,sn,cn
23 m=mod(cn,4)
24 do 10 i=sn-1,0,-1
25 do 20 j=0,m-1
26 if(tab(s(i+j)).ne.tab(c(j)))go to 50
27 20 continue
28 do 30 j=m,cn-1,4
29 if(tab(s(i+j)).ne.tab(c(j)))go to 50
30 if(tab(s(i+j+1)).ne.tab(c(j+1)))go to 50
31 if(tab(s(i+j+2)).ne.tab(c(j+2)))go to 50
32 if(tab(s(i+j+3)).ne.tab(c(j+3)))go to 50
33 30 continue
34 50 if(j.eq.cn)go to 100
35 10 continue
36 srfindtab=-1
37 return
38 100 srfindtab=i
39 return
40 end
diff --git a/src/mt/stackque.h b/src/mt/stackque.h
new file mode 100644
index 0000000..349cb4f
--- /dev/null
+++ b/src/mt/stackque.h
@@ -0,0 +1,64 @@
1/*************************************************************************
2 *
3 * HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#ifndef STACKQUEH
21#define STACKQUEH
22
23#include <mt/mstring.h>
24#include <mt/mlock.h>
25
26template <class T> class stackque {
27public:
28 stackque(int m) {
29 put=get=n=0;
30 base=new T[caps=m];
31 memset(&mutex,0,sizeof(mutex_t));
32 }
33 ~stackque() { delete base; }
34
35 int push(const T& a) throw(merror_t) {
36 MLOCK(mutex);
37 if(n>=caps) THROW("stackque: Full");
38 base[put++]=a;
39 if(put==caps) put=0;
40 return ++n;
41 }
42
43 int pop(T& a) {
44 MLOCK(mutex);
45 if(n) {
46 a=base[get++];
47 if(get==caps) get=0;
48 return n--;
49 }
50 else return 0;
51 }
52
53 int capacity() const { return caps; }
54 int size() const { return n; }
55 int empty() const { return n==0; }
56 int full() const { return n==caps; }
57 void clear() { put=get=n=0; }
58private:
59 int put,get,n,caps;
60 T* base;
61 mutex_t mutex;
62};
63
64#endif
diff --git a/src/mt/stringref.cc b/src/mt/stringref.cc
new file mode 100644
index 0000000..66b3d3e
--- /dev/null
+++ b/src/mt/stringref.cc
@@ -0,0 +1,126 @@
1/*************************************************************************
2 *
3 * HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#include <mt/stringref.h>
21#include <unistd.h>
22#include <fcntl.h>
23
24extern "C" {
25 int cfind_(const char* s,const int& sn,const char& c);
26 int crfind_(const char* s,const int& sn,const char& c);
27 int sfind_(const char* s,const int& sn,const char* c,const int& cn);
28 int srfind_(const char* s,const int& sn,const char* c,const int& cn);
29 int sfindtab_(const char* s,const int& sn,const char* c,const int& cn,const char* tab);
30 int srfindtab_(const char* s,const int& sn,const char* c,const int& cn,const char* tab);
31 int scomptab_(const char* s,const char* c,const int& n,const char* tab);
32 void sconvert_(char* s,const int& sn,const char* tab);
33 int find_of__(const char* s,const int& sn,const char* set);
34 int rfind_of__(const char* s,const int& sn,const char* set);
35 int find_not_of__(const char* s,const int& sn,const char* set);
36 int rfind_not_of__(const char* s,const int& sn,const char* set);
37 int skip_parentesis__(const char* s,const int& sn,
38 const char& left,const char& right,const char& esc);
39 int strip_(char* s,const char* c,const int& cn,const char& esc);
40}
41
42////////////////////////////////////////////////////
43
44char* sref::copyto(char* buf,int max) const {
45 if(!dim) buf[0]=0;
46 else if(dim<max) ((char*)memcpy(buf,map,dim))[dim]=0;
47 else ((char*)memcpy(buf,map,max-1))[max-1]=0;
48 return buf;
49}
50
51int sref::compare(const sref& s,const charmap& tab) const {
52 int c; if(map==s.map) return dim-s.dim;
53 else return (c=scomptab_(map,s.map,dim<s.dim?dim:s.dim,tab.map))?c:dim-s.dim;
54}
55
56////////////////////////////////////////////////////
57
58void sref::tolower() { sconvert_(map,dim,cset_lcase.map); }
59void sref::toupper() { sconvert_(map,dim,cset_ucase.map); }
60void sref::tosim(const charmap& s) { sconvert_(map,dim,s.map); }
61
62////////////////////////////////////////////////////
63
64sref sref::operator()(int pos,int n) const {
65 if(pos<0) { pos+=dim; if(pos<0) pos=0; }
66 if(pos>=dim) return sref(map+dim,0);
67 else {
68 if(n<0) { n+=dim+1; if(n<0) n=0; }
69 if(n>=dim-pos) return sref(map+pos,dim-pos);
70 else return sref(map+pos,n);
71 }
72}
73
74sref sref::left(int n) const {
75 if(n<0) { n+=dim+1; if(n<0) n=0; }
76 if(n>dim) return sref(map,dim);
77 else return sref(map,n);
78}
79sref sref::leftand(int n,int m) const {
80 if(n<0) { n+=dim+1; if(n<0) n=0; }
81 if((n+=m)>dim) return sref(map,dim);
82 else return sref(map,n);
83}
84sref sref::right(int n) const {
85 if(n<0) { n+=dim+1; if(n<0) n=0; }
86 if(n>dim) return sref(map+dim,0);
87 else return sref(map+n,dim-n);
88}
89sref sref::past(int n,int m) const {
90 if(n<0) { n+=dim+1; if(n<0) n=0; }
91 if((n+=m)>dim) return sref(map+dim,0);
92 else return sref(map+n,dim-n);
93}
94
95////////////////////////////////////////////////////////////////
96
97int sref::find(char c) const { return cfind_(map,dim,c); }
98int sref::rfind(char c) const { return crfind_(map,dim,c); }
99int sref::find(const sref& s) const { return sfind_(map,dim,s.map,s.dim); }
100int sref::rfind(const sref& s) const { return srfind_(map,dim,s.map,s.dim); }
101int sref::find(const sref& s,const charmap& tab) const {
102 return sfindtab_(map,dim,s.map,s.dim,tab.map);
103}
104int sref::rfind(const sref& s,const charmap& tab) const {
105 return srfindtab_(map,dim,s.map,s.dim,tab.map);
106}
107
108int sref::find_of(const charset& s) const { return find_of__(map,dim,s.map); }
109int sref::rfind_of(const charset& s) const { return rfind_of__(map,dim,s.map); }
110int sref::find_not_of(const charset& s) const { return find_not_of__(map,dim,s.map); }
111int sref::rfind_not_of(const charset& s) const { return rfind_not_of__(map,dim,s.map); }
112
113int sref::skip(const bracket& bra) const {
114 return skip_parentesis__(map,dim,bra.left,bra.right,bra.esc);
115}
116
117////////////////////////////////////////////////////////////////
118
119int sref::save(const sref& s,int prot) const {
120 sref_t path; s.copyto(path);
121 int fd=open(path,O_WRONLY|O_CREAT,prot);
122 if(fd<0) return -1;
123 write(fd,map,dim);
124 close(fd);
125 return dim;
126}
diff --git a/src/mt/stringref.h b/src/mt/stringref.h
new file mode 100644
index 0000000..a66ac21
--- /dev/null
+++ b/src/mt/stringref.h
@@ -0,0 +1,239 @@
1/*************************************************************************
2 *
3 * HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#ifndef SREFH
21#define SREFH
22
23#include <mt/charset.h>
24#include <stdlib.h>
25
26typedef char sref_t[1024];
27
28class sref {
29public:
30 sref() : map((char*)&dim),dim(0) {}
31 explicit sref(char* p) : map(p),dim(strlen(p)) {}
32 explicit sref(const char* p) : map((char*)p),dim(strlen(p)) {}
33 sref(char* p,int n) : map(p),dim(n) {}
34 sref(const char* p,int n) : map((char*)p),dim(n) {}
35
36 int size() const { return dim; }
37 bool empty() const { return dim==0; }
38 bool nempty() const { return dim!=0; }
39
40 char* data() { return map; }
41 const char* data() const { return map; }
42
43 char& operator[](int pos) { return map[pos]; }
44 const char& operator[](int pos) const { return map[pos]; }
45
46 char* begin() { return map; }
47 const char* begin() const { return map; }
48
49 char* end() { return map+dim; }
50 const char* end() const { return map+dim; }
51
52 int operator*() const { return dim?*map:0; }
53 int front() const { return dim?*map:0; }
54 int back() const { return dim?map[dim-1]:0; }
55
56 ////////////////////////////////////////////////////////////////
57
58 sref popf() const { return dim?sref(map+1,dim-1):*this; }
59 sref popb() const { return dim?sref(map,dim-1):*this; }
60
61 sref adv(int n) const { return n>0?(n<dim?sref(map+n,dim-n):sref(map+dim,0)):*this; }
62
63 // NOTE that these functions are LOW LEVEL - no checks!
64
65 sref adv(const sref& s) const { return sref(s.end(),end()-s.end()); }
66 sref operator()(char* p) { return sref(p,map+dim-p); }
67 const sref operator()(const char* p) const { return sref((char*)p,map+dim-p); }
68
69 ////////////////////////////////////////////////////////////////
70
71 char* news() const {char* s=new char[dim+1];s[dim]=0;return (char*)memcpy(s,map,dim); }
72
73 void clear() {dim=0;}
74
75 ////////////////////////////////////////////////////////////////
76
77 void mcopy(const sref& s) {
78 if(s.dim<dim) memmove(map,s.map,dim=s.dim); else memmove(map,s.map,dim);
79 }
80
81 void tolower();
82 void toupper();
83 void tosim(const charmap& s=cset_sim);
84
85 ////////////////////////////////////////////////////////////////
86
87 char* copyto(char* buf,int max) const;
88 char* copyto(sref_t& buf) const { return copyto(buf,sizeof(buf)); }
89
90 int compare(const sref& s) const {
91 int c; if(map==s.map) return dim-s.dim;
92 else return (c=memcmp(map,s.map,dim<s.dim?dim:s.dim))?c:dim-s.dim;
93 }
94 int compare(const sref& s,const charmap& tab) const;
95
96 ////////////////////////////////////////////////////////////////
97
98 sref operator()(int pos,int n=-1) const;
99 sref left(int n) const;
100 sref leftand(int n,int m) const;
101 sref right(int n) const;
102 sref past(int n,int m) const;
103
104 sref past_nl() const { return past(find('\n'),1); }
105
106 ////////////////////////////////////////////////////////////////
107
108 int find(char c) const;
109 sref left_first(char c) const { return left(find(c)); }
110 sref leftand_first(char c) const { return leftand(find(c),1); }
111 sref right_first(char c) const { return right(find(c)); }
112 sref past_first(char c) const { return past(find(c),1); }
113
114 int rfind(char c) const;
115 sref left_last(char c) const { return left(rfind(c)); }
116 sref leftand_last(char c) const { return leftand(rfind(c),1); }
117 sref right_last(char c) const { return right(rfind(c)); }
118 sref past_last(char c) const { return past(rfind(c),1); }
119
120 int find(const sref& s) const;
121 sref left_first(const sref& s) const { return left(find(s)); }
122 sref leftand_first(const sref& s) const { return leftand(find(s),s.size()); }
123 sref right_first(const sref& s) const { return right(find(s)); }
124 sref past_first(const sref& s) const { return past(find(s),s.size()); }
125
126 int rfind(const sref& s) const;
127 sref left_last(const sref& s) const { return left(rfind(s)); }
128 sref leftand_last(const sref& s) const { return leftand(rfind(s),s.size()); }
129 sref right_last(const sref& s) const { return right(rfind(s)); }
130 sref past_last(const sref& s) const { return past(rfind(s),s.size()); }
131
132 int find(const sref& s,const charmap& tab) const;
133 sref left_first(const sref& s,const charmap& tab) const { return left(find(s,tab)); }
134 sref leftand_first(const sref& s,const charmap& tab)const{
135 return leftand(find(s,tab),s.size());
136 }
137 sref right_first(const sref& s,const charmap& tab) const { return right(find(s,tab)); }
138 sref past_first(const sref& s,const charmap& tab) const {
139 return past(find(s,tab),s.size());
140 }
141
142 int rfind(const sref& s,const charmap& tab) const;
143 sref left_last(const sref& s,const charmap& tab) const { return left(rfind(s,tab)); }
144 sref leftand_last(const sref& s,const charmap& tab)const{
145 return leftand(rfind(s,tab),s.size());
146 }
147 sref right_last(const sref& s,const charmap& tab) const { return right(rfind(s,tab)); }
148 sref past_last(const sref& s,const charmap& tab) const {
149 return past(rfind(s,tab),s.size());
150 }
151
152 int find_of(const charset& s) const;
153 sref left_first_of(const charset& s) const { return left(find_of(s)); }
154 sref leftand_first_of(const charset& s) const { return leftand(find_of(s),1); }
155 sref right_first_of(const charset& s) const { return right(find_of(s)); }
156 sref past_first_of(const charset& s) const { return past(find_of(s),1); }
157
158 int rfind_of(const charset& s) const;
159 sref left_last_of(const charset& s) const { return left(rfind_of(s)); }
160 sref leftand_last_of(const charset& s) const { return leftand(rfind_of(s),1); }
161 sref right_last_of(const charset& s) const { return right(rfind_of(s)); }
162 sref past_last_of(const charset& s) const { return past(rfind_of(s),1); }
163
164 int find_not_of(const charset& s) const;
165 sref left_first_not_of(const charset& s) const { return left(find_not_of(s)); }
166 sref leftand_first_not_of(const charset& s) const { return leftand(find_not_of(s),1); }
167 sref right_first_not_of(const charset& s) const { return right(find_not_of(s)); }
168 sref past_first_not_of(const charset& s) const { return past(find_not_of(s),1); }
169
170 int rfind_not_of(const charset& s) const;
171 sref left_last_not_of(const charset& s) const { return left(rfind_not_of(s)); }
172 sref leftand_last_not_of(const charset& s) const { return leftand(rfind_not_of(s),1); }
173 sref right_last_not_of(const charset& s) const { return right(rfind_not_of(s)); }
174 sref past_last_not_of(const charset& s) const { return past(rfind_not_of(s),1); }
175
176 int skip(const bracket& bra) const;
177
178 ////////////////////////////////////////////////////////////////
179
180 int save(const sref& path,int prot=0600) const;
181
182protected:
183 char* map;
184 int dim;
185};
186
187////////////////////////////////////////////////////
188
189inline bool operator<(const sref& a,const sref& b) {
190 return a.compare(b)<0;
191}
192inline bool operator<=(const sref& a,const sref& b) {
193 return a.compare(b)<=0;
194}
195inline bool operator==(const sref& a,const sref& b) {
196 return a.compare(b)==0;
197}
198inline bool operator!=(const sref& a,const sref& b) {
199 return a.compare(b)!=0;
200}
201inline bool operator>=(const sref& a,const sref& b) {
202 return a.compare(b)>=0;
203}
204inline bool operator>(const sref& a,const sref& b) {
205 return a.compare(b)>0;
206}
207
208//////////////////////////////////////////////////////////////////////////
209
210inline int operator-(const sref& a,const sref& b) { return a.data()-b.data(); }
211
212//////////////////////////////////////////////////////////////////////////
213
214inline int ltn(const sref& a,const sref& b) {
215 return a.compare(b,cset_lcase)<0;
216}
217inline int len(const sref& a,const sref& b) {
218 return a.compare(b,cset_lcase)<=0;
219}
220inline int eqn(const sref& a,const sref& b) {
221 return a.compare(b,cset_lcase)==0;
222}
223inline int nen(const sref& a,const sref& b) {
224 return a.compare(b,cset_lcase)!=0;
225}
226inline int gen(const sref& a,const sref& b) {
227 return a.compare(b,cset_lcase)>=0;
228}
229inline int gtn(const sref& a,const sref& b) {
230 return a.compare(b,cset_lcase)>0;
231}
232
233//////////////////////////////////////////////////////////////////////////
234
235inline int atob(const sref& s) { sref_t buf; return atoi(s.copyto(buf))!=0; }
236inline int atoi(const sref& s) { sref_t buf; return atoi(s.copyto(buf)); }
237inline double atof(const sref& s) { sref_t buf; return atof(s.copyto(buf)); }
238
239#endif
diff --git a/src/mt/strip.f b/src/mt/strip.f
new file mode 100644
index 0000000..1cca9c4
--- /dev/null
+++ b/src/mt/strip.f
@@ -0,0 +1,31 @@
1ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
2c
3c HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4c
5c This program is free software; you can redistribute it and/or modify
6c it under the terms of the GNU General Public License as published by
7c the Free Software Foundation; either version 2 of the License, or
8c (at your option) any later version.
9c
10c This program is distributed in the hope that it will be useful,
11c but WITHOUT ANY WARRANTY; without even the implied warranty of
12c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13c GNU General Public License for more details.
14c
15c You should have received a copy of the GNU General Public License
16c along with this program; if not, write to the Free Software
17c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18c
19
20 integer function strip(s,c,cn,esc)
21 character s(0:1),c(0:1),esc
22 integer i,j,cn
23 j=0
24 do 10 i=0,cn-1
25 if(c(i).eq.esc)go to 10
26 s(j)=c(i)
27 j=j+1
28 10 continue
29 strip=j
30 return
31 end
diff --git a/src/mt/test.cc b/src/mt/test.cc
new file mode 100644
index 0000000..5671a33
--- /dev/null
+++ b/src/mt/test.cc
@@ -0,0 +1,337 @@
1/*************************************************************************
2 *
3 * HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#include <mt/uniheap.h>
21#include <mt/stackque.h>
22#include <mt/random.h>
23#include <mt/lookup.h>
24#include <mt/mset.h>
25#include <mt/issue.h>
26#include <mt/mvec.h>
27#include <mt/msmap.h>
28#include <time.h>
29
30#define GENERAL 0
31#define STREAM 1
32#define HEAPS 0
33#define CHARSET 0
34#define RANDOM 0
35#define LOOKUP 0
36#define ISSUE 1
37#define MSET 0
38#define CVTS 0
39#define VECTOR 0
40#define MSMAP 0
41
42static fp_stream mout(stdout),merr(stderr);
43
44main(int argc,char* argv[])
45{
46 mstring s;
47#if GENERAL
48 s="asdfwerfindfindis?? asdf wert nnvnbn\n";
49
50 mout<<"["<<Trim(s,cset_para)<<"]\n";
51
52 sref find=sref("find");
53 sref rfind=sref("rfind");
54
55 mout<<s.find(find)<<"\n";
56 mout<<s.rfind(rfind)<<"\n";
57 mout<<s.find(find,cset_lcase)<<"\n";
58 mout<<s.rfind(rfind,cset_lcase)<<"\n";
59 mout<<s.find(find,cset_ucase)<<"\n";
60 mout<<s.rfind(rfind,cset_ucase)<<"\n";
61
62 mout<<"****\n";
63
64 mout<<"["<<s.leftand_last_not_of(cset_ws)<<"]\n";
65
66 mout<<"****\n";
67
68 s.tolower();
69 mout<<"["<<s<<"]\n";
70 s.toupper();
71 mout<<"["<<s<<"]\n";
72
73 mout<<"*****\n";
74
75 mstring st="abcdefghi2jklmn";
76 charset stset("123");
77 mout<<"["<<st.left_first_of(stset)<<"]\n";
78 mout<<"["<<st.right_first_of(stset)<<"]\n";
79 mout<<"["<<st.past_first_of(stset)<<"]\n";
80
81 mout<<"******\n";
82
83 mstring a=First(s);
84 mstring b=Rest(s);
85 mstring c=Last(s);
86 mout<<"["<<a<<"]\n";
87 mout<<"["<<b<<"]\n";
88 mout<<"["<<c<<"]\n";
89
90 mout<<"******\n";
91
92 sref first,rest=s;
93 while(Split(first,rest)) {
94 mout<<"["<<first<<"]["<<atoi(first)<<"]\n";
95 }
96
97 mout<<"*******\n";
98
99 mout<<"["<<mstring().convert("%d %02X",56,100)<<"]\n";
100
101 mout<<s.skip(cset_para)<<"\n";
102
103 mout<<"********\n";
104
105 //mstring buf; buf.load("tt.cc");
106 //mout<<"***\n"<<buf<<"***\n";
107#endif
108#if STREAM
109 s="more strange asdf\n";
110
111 swrite to;
112 mout<<s<<"\n";
113 to.hold(s)<<" Hello! this is appending "<<4<<" to string\n";
114 mout<<s<<"\n";
115
116 mout<<"********\n";
117
118 mstream mm; mm<<"Hejsan!\n";
119
120 mout<<"********\n";
121
122 try {
123 THROW("hello "<<4<<" once more");
124 }
125 catch(const merror_t& e) {
126 mout<<"Error test: "<<e.num<<"\n";
127 mout<<e.desc<<"\n";
128 }
129
130 mout<<"********\n";
131
132 sref sa=s;
133 sref sb=s;
134 mout<<(sa==sb)<<"\n";
135
136 mout<<"********\n";
137
138 mstring tt="(asdf)sdfsdf";
139 mout<<tt.skip(cset_para)<<"\n";
140 mout<<"["<<tt(1,tt.skip(cset_para)-2)<<"]\n";
141
142 mout<<"********\n";
143#endif
144
145#if HEAPS
146
147 uniheap<4> stack; stack.init();
148 for(int i=0;i<48;i++) {
149 //stack.pop(stack.push());
150 stack.push();
151 }
152 mout<<"--\n";
153 mout<<stack.chunksize()<<"\n";
154
155 mout<<"********\n";
156
157 stackque<int> que(8);
158 for(int i=0;i<8;i++) que.push(i);
159
160 try {
161 que.push(5);
162 }
163 catch(const merror_t& e) {
164 merr<<e.num<<"\n";
165 merr<<e.desc<<"\n";
166 }
167
168 int pop;
169 while(que.pop(pop)) merr<<pop<<"\n";
170
171#endif
172
173#if CHARSET
174
175 charset set("12345öd");
176 charset set2("12");
177 charset set3=set-set2;
178
179 merr<<"* \n";
180
181 for(int i=-127;i<127;i++) {
182 if(set.map[i]) mout<<i<<"("<<char(i)<<")\n";
183 }
184
185 merr<<"* \n";
186
187 for(int i=-127;i<127;i++) {
188 if(set3.map[i]) mout<<i<<"("<<char(i)<<")\n";
189 }
190
191 merr<<"**\n";
192
193 mout<<find_of_("ö",1,set.map)<<"\n";
194 mout<<s.find_of(set)<<"\n";
195
196 mout<<"***\n";
197
198 mout<<"[";
199 for(int i=-127;i<128;i++) if(cset_lcase[i]!=i) mout.put(i);
200 mout<<"]\n";
201 mout<<"[";
202 for(int i=-127;i<128;i++) if(cset_lcase[i]!=i) mout.put(cset_lcase[i]);
203 mout<<"]\n";
204
205 mout<<"\n";
206
207 mout<<"[";
208 for(int i=-127;i<128;i++) if(cset_ueqv1[i]!=i) mout.put(i);
209 mout<<"]\n";
210 mout<<"[";
211 for(int i=-127;i<128;i++) if(cset_ueqv1[i]!=i) mout.put(cset_ueqv1[i]);
212 mout<<"]\n";
213
214 mout<<"\n";
215
216 mout<<"[";
217 for(int i=-127;i<128;i++) if(cset_ueqv2[i]!=i) mout.put(i);
218 mout<<"]\n";
219 mout<<"[";
220 for(int i=-127;i<128;i++) if(cset_ueqv2[i]!=i) mout.put(cset_ueqv2[i]);
221 mout<<"]\n";
222
223 mout<<"\n";
224
225 mout<<"[";
226 for(int i=-127;i<128;i++) if(cset_sim[i]!=i) mout.put(i);
227 mout<<"]\n";
228 mout<<"[";
229 for(int i=-127;i<128;i++) if(cset_sim[i]!=i) mout.put(cset_sim[i]);
230 mout<<"]\n";
231#endif
232
233#if RANDOM
234 RandomInit(13);
235 for(int i=0;i<100;i++) mout<<Uniform()<<"\n";
236#endif
237
238#if LOOKUP
239
240 while(1) {
241 mstring ip;
242 merr<<"addr>";
243 getline(ip,stdin);
244 IPnode node;
245 for(int i=0;i<4;i++) {
246 if(Lookup(node,ip)) {
247 merr<<node.valid<<"\n";
248 merr<<node.ip<<"\n";
249 merr<<node.name<<"\n";
250 }
251 else {
252 merr<<"Not found\n";
253 break;
254 }
255 }
256 }
257
258#endif
259
260#if ISSUE
261
262 issue_t cmd(sref("/bin/cat"));
263 mswrite out;
264 mstring in="hello world!";
265 cmd.run(out,in);
266 mout<<"Got ["<<out.str()<<"]\n";
267
268 cmd.clear();
269 cmd.add(sref("sadfasfd"));
270 cmd.end();
271 out.clear();
272 cmd.run(out,in);
273 mout<<"Got ["<<out.str()<<"]\n";
274
275#endif
276
277#if MSET
278
279 mstring mm="hello world!\n how many items?\n";
280 mset a=mm;
281 for(int i=0;i<a.size();i++) {
282 mout<<a[i]<<"\n";
283 }
284
285 mout<<"OR ["<<a<<"]\n";
286
287#endif
288
289#if CVTS
290
291 merr<<"n: "<<itoa(5)<<"\n";
292 merr<<"f: "<<ftoa(5)<<"\n";
293 merr<<"f: "<<ftoa(5.7)<<"\n";
294 merr<<"f: "<<ftoa(-3)<<"\n";
295 merr<<"f: "<<ftoa(3.78678)<<"\n";
296 merr<<"f: "<<ftoa(exp(2.1))<<"\n";
297 merr<<"f: "<<ftoa(time(0))<<"\n";
298 merr<<"direct: "<<3.40000<<"\n";
299
300 pipe_stream tout(1);
301 tout<<"How does this one "<<-78.4<<" behave??\n";
302
303 mstring inp;
304 getline(inp,stdin);
305 merr<<ftoa(atof(inp))<<"\n";
306
307#endif
308
309#if VECTOR
310
311 mrvec<int> v(4);
312 for(int i=0;i<v.size();i++) v[i]=i;
313
314 for(int i=0;i<v.size();i++) merr<<v[i]<<"\n";
315
316#endif
317
318#if MSMAP
319
320 ssmap map;
321 //map.add("hello","world");
322 //map.add("one","world!");
323 map.push_back(sstring("one","world!"));
324 map.push_back(sstring("hello","world"));
325 map.sort();
326
327 for(ssmap::iterator p=map.begin();p!=map.end();p++) {
328 merr<<p->first<<" "<<p->second<<"\n";
329 }
330
331 const mstring* p=map.get("one");
332 if(p) merr<<"got "<<*p<<"\n";
333
334#endif
335
336 return 0;
337}
diff --git a/src/mt/uniheap.h b/src/mt/uniheap.h
new file mode 100644
index 0000000..39c3d34
--- /dev/null
+++ b/src/mt/uniheap.h
@@ -0,0 +1,65 @@
1/*************************************************************************
2 *
3 * HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#ifndef UNIHEAPH
21#define UNIHEAPH
22
23#include <mt/mlock.h>
24#include <malloc.h>
25#include <string.h>
26
27// NOTE - must be in extern/static scope, or zeroed before use
28// by a call to init. constructors will fail badly.
29// A minimum of sizeof(T)==4 is required.
30// Furthermore, the upper limit of heap space is 1Gb.
31
32template <int N> class uniheap {
33public:
34 static const int maxchunks=24;
35
36 void init() {
37 head=0;
38 chunk=0;
39 nchunks=0;
40 memset(&mutex,0,sizeof(mutex_t));
41 }
42
43 char* push() { MLOCK(mutex); char* p=news(); head=*(char**)p; return p; }
44 void pop(void* p) { MLOCK(mutex); *((char**)p)=head; head=(char*)p; }
45 int chunksize() const { return chunk; }
46protected:
47 char* news() {
48 if(!head) {
49 if(!chunk) chunk=N<<4;
50 if(nchunks>=maxchunks) throw((int)0);
51 head=chunks[nchunks++]=(char*)malloc(chunk);
52 if(!head) throw((int)0);
53 for(int i=0;i<chunk-N;i+=N) *((char**)(head+i))=head+i+N;
54 *((char**)(head+chunk-N))=0;
55 chunk<<=1;
56 }
57 return head;
58 }
59private:
60 char *head,*chunks[maxchunks];
61 int chunk,nchunks;
62 mutex_t mutex;
63};
64
65#endif