diff options
Diffstat (limited to 'src/mt')
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 @@ | |||
| 1 | ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc | ||
| 2 | c | ||
| 3 | c HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | c | ||
| 5 | c This program is free software; you can redistribute it and/or modify | ||
| 6 | c it under the terms of the GNU General Public License as published by | ||
| 7 | c the Free Software Foundation; either version 2 of the License, or | ||
| 8 | c (at your option) any later version. | ||
| 9 | c | ||
| 10 | c This program is distributed in the hope that it will be useful, | ||
| 11 | c but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | c GNU General Public License for more details. | ||
| 14 | c | ||
| 15 | c You should have received a copy of the GNU General Public License | ||
| 16 | c along with this program; if not, write to the Free Software | ||
| 17 | c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | c | ||
| 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 | |||
| 25 | struct 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 | |||
| 37 | inline 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 | } | ||
| 40 | inline charset operator|(const charset& a,char b) { | ||
| 41 | charset c(a); c.map[b]=(b!=0); return c; | ||
| 42 | } | ||
| 43 | inline charset operator|(char a,const charset& b) { | ||
| 44 | charset c(b); c.map[a]=(a!=0); return c; | ||
| 45 | } | ||
| 46 | inline 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 | } | ||
| 49 | inline 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 | } | ||
| 52 | inline 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 | } | ||
| 55 | inline charset operator-(const charset& a,char b) { | ||
| 56 | charset c(a); c.map[b]=0; return c; | ||
| 57 | } | ||
| 58 | inline 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 | |||
| 65 | struct 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 | |||
| 80 | inline 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 | |||
| 89 | struct 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 | |||
| 97 | const charset cset_spaces(" \t"); | ||
| 98 | const charset cset_newl("\r\n"); | ||
| 99 | const charset cset_ws=cset_spaces|cset_newl; | ||
| 100 | const charset cset_printable(' ','~'); | ||
| 101 | const charset cset_digit('0','9'); | ||
| 102 | const charset cset_real=cset_digit|'.'; | ||
| 103 | const charset cset_sign("+-"); | ||
| 104 | const charset cset_lalpha('a','z'); | ||
| 105 | const charset cset_ualpha('A','Z'); | ||
| 106 | const charset cset_alpha=cset_lalpha|cset_ualpha; | ||
| 107 | const charset cset_alphanum=cset_alpha|cset_digit; | ||
| 108 | const charset cset_alphareal=cset_alpha|cset_real; | ||
| 109 | const charset cset_lext1(-32,-10),cset_lext2(-8,-2); | ||
| 110 | const charset cset_uext1(-64,-42),cset_uext2(-40,-34); | ||
| 111 | const charset cset_liso=cset_lalpha|cset_lext1|cset_lext2; | ||
| 112 | const charset cset_uiso=cset_ualpha|cset_uext1|cset_uext2; | ||
| 113 | |||
| 114 | const charmap cset_ident; | ||
| 115 | const charmap cset_leqv1(cset_lext1,"aaaaaaaceeeeiiiidnooooo"); | ||
| 116 | const charmap cset_leqv2(cset_lext2,"ouuuuyp"); | ||
| 117 | const charmap cset_ueqv1(cset_uext1,"AAAAAAACEEEEIIIIDNOOOOO"); | ||
| 118 | const charmap cset_ueqv2(cset_uext2,"OUUUUYP"); | ||
| 119 | |||
| 120 | const charmap cset_lcase(cset_uiso,cset_liso); | ||
| 121 | const charmap cset_ucase(cset_liso,cset_uiso); | ||
| 122 | const charmap cset_sim=cset_lcase<<cset_leqv1<<cset_leqv2; | ||
| 123 | |||
| 124 | const bracket cset_quotes("\"\"\\"); | ||
| 125 | const bracket cset_indices("[]\\"); | ||
| 126 | const bracket cset_braces("{}\\"); | ||
| 127 | const bracket cset_para("()\\"); | ||
| 128 | const bracket cset_dollars("$$\\"); | ||
| 129 | const 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 | |||
| 22 | mstring 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 | |||
| 25 | mstring 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 @@ | |||
| 1 | ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc | ||
| 2 | c | ||
| 3 | c HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | c | ||
| 5 | c This program is free software; you can redistribute it and/or modify | ||
| 6 | c it under the terms of the GNU General Public License as published by | ||
| 7 | c the Free Software Foundation; either version 2 of the License, or | ||
| 8 | c (at your option) any later version. | ||
| 9 | c | ||
| 10 | c This program is distributed in the hope that it will be useful, | ||
| 11 | c but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | c GNU General Public License for more details. | ||
| 14 | c | ||
| 15 | c You should have received a copy of the GNU General Public License | ||
| 16 | c along with this program; if not, write to the Free Software | ||
| 17 | c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | c | ||
| 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 | |||
| 24 | const mstring SWEEK[MAXLANG][7]={ | ||
| 25 | "Sun","Mon","Tue","Wed","Thu","Fri","Sat", | ||
| 26 | "Sön","Mån","Tis","Ons","Tor","Fre","Lör" | ||
| 27 | }; | ||
| 28 | const 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 | }; | ||
| 32 | const mstring WEEK[MAXLANG][7]={ | ||
| 33 | "Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday", | ||
| 34 | "Söndag","Måndag","Tisdag","Onsdag","Torsdag","Fredag","Lördag" | ||
| 35 | }; | ||
| 36 | const 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 | |||
| 43 | time_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 | |||
| 52 | time_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 | |||
| 59 | const mstring& Week(int lang,time_t t) | ||
| 60 | { | ||
| 61 | tm s; return WEEK[lang][localtime_r(&t,&s)->tm_wday]; | ||
| 62 | } | ||
| 63 | |||
| 64 | const mstring& Month(int lang,time_t t) | ||
| 65 | { | ||
| 66 | tm s; return MONTH[lang][localtime_r(&t,&s)->tm_mon]; | ||
| 67 | } | ||
| 68 | |||
| 69 | const mstring& SWeek(int lang,time_t t) | ||
| 70 | { | ||
| 71 | tm s; return SWEEK[lang][localtime_r(&t,&s)->tm_wday]; | ||
| 72 | } | ||
| 73 | |||
| 74 | const mstring& SMonth(int lang,time_t t) | ||
| 75 | { | ||
| 76 | tm s; return SMONTH[lang][localtime_r(&t,&s)->tm_mon]; | ||
| 77 | } | ||
| 78 | |||
| 79 | mstring 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 | |||
| 92 | mstring 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 | |||
| 109 | static 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 | |||
| 118 | static 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 | |||
| 127 | static 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 | |||
| 143 | static 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 | |||
| 151 | static 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 | |||
| 159 | time_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 | |||
| 177 | time_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 | |||
| 198 | int 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 | |||
| 26 | const time_t SEC_PER_DAY=86400; | ||
| 27 | const int MAXLANG=2; | ||
| 28 | const mstring LANG[MAXLANG]={"en","sv"}; | ||
| 29 | |||
| 30 | inline time_t Now() { return time(0); } | ||
| 31 | inline time_t Days(int days) { return days*SEC_PER_DAY; } | ||
| 32 | |||
| 33 | time_t Today(time_t); | ||
| 34 | time_t Sunday(time_t); | ||
| 35 | |||
| 36 | const mstring& Week(int lang,time_t t); | ||
| 37 | const mstring& Month(int lang,time_t t); | ||
| 38 | |||
| 39 | const mstring& SWeek(int lang,time_t t); | ||
| 40 | const mstring& SMonth(int lang,time_t t); | ||
| 41 | |||
| 42 | mstring httpTime(time_t t); | ||
| 43 | mstring htcTime(int lang,time_t t); | ||
| 44 | time_t htcTime(int lang,const sref& date); | ||
| 45 | time_t cvtTime(const sref& code); | ||
| 46 | |||
| 47 | int 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 @@ | |||
| 1 | ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc | ||
| 2 | c | ||
| 3 | c HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | c | ||
| 5 | c This program is free software; you can redistribute it and/or modify | ||
| 6 | c it under the terms of the GNU General Public License as published by | ||
| 7 | c the Free Software Foundation; either version 2 of the License, or | ||
| 8 | c (at your option) any later version. | ||
| 9 | c | ||
| 10 | c This program is distributed in the hope that it will be useful, | ||
| 11 | c but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | c GNU General Public License for more details. | ||
| 14 | c | ||
| 15 | c You should have received a copy of the GNU General Public License | ||
| 16 | c along with this program; if not, write to the Free Software | ||
| 17 | c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | c | ||
| 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 @@ | |||
| 1 | ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc | ||
| 2 | c | ||
| 3 | c HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | c | ||
| 5 | c This program is free software; you can redistribute it and/or modify | ||
| 6 | c it under the terms of the GNU General Public License as published by | ||
| 7 | c the Free Software Foundation; either version 2 of the License, or | ||
| 8 | c (at your option) any later version. | ||
| 9 | c | ||
| 10 | c This program is distributed in the hope that it will be useful, | ||
| 11 | c but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | c GNU General Public License for more details. | ||
| 14 | c | ||
| 15 | c You should have received a copy of the GNU General Public License | ||
| 16 | c along with this program; if not, write to the Free Software | ||
| 17 | c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | c | ||
| 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 | |||
| 24 | void 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 | |||
| 34 | struct 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> | ||
| 26 | using namespace std; | ||
| 27 | |||
| 28 | const mstring LOCK=".lock"; | ||
| 29 | |||
| 30 | void 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 | |||
| 39 | int remove(const char* path); | ||
| 40 | void UnlockFile(const mstring& path) | ||
| 41 | { | ||
| 42 | remove((path+LOCK).c_str()); | ||
| 43 | } | ||
| 44 | |||
| 45 | /////////////////////////////////////////////////////////////////// | ||
| 46 | |||
| 47 | proclock_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 | |||
| 66 | proclock_t::~proclock_t() | ||
| 67 | { | ||
| 68 | if(getpid()==pid) remove(path.c_str()); | ||
| 69 | } | ||
| 70 | |||
| 71 | /////////////////////////////////////////////////////////////////// | ||
| 72 | |||
| 73 | nodelock_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 | |||
| 102 | nodelock_t::~nodelock_t() | ||
| 103 | { | ||
| 104 | if(getpid()==pid) remove(path.c_str()); | ||
| 105 | } | ||
| 106 | |||
| 107 | /////////////////////////////////////////////////////////////////// | ||
| 108 | |||
| 109 | void 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 | |||
| 27 | void LockFile(const mstring& path,int prot=0660) throw(merror_t); | ||
| 28 | void 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 | |||
| 37 | struct 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 | |||
| 53 | struct 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 | |||
| 69 | void 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 | |||
| 27 | const time_t VALIDSEC=120; | ||
| 28 | static msvec<IPnode> cache; | ||
| 29 | static mutex_t mutex; | ||
| 30 | |||
| 31 | int 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 | |||
| 59 | int 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 | |||
| 27 | struct IPnode { time_t valid; in_addr addr; mstring ip,name; }; | ||
| 28 | |||
| 29 | int Lookup(IPnode& node,const sref& s); | ||
| 30 | int 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> | ||
| 25 | typedef pthread_mutex_t mutex_t; | ||
| 26 | typedef pthread_cond_t mtcond_t; | ||
| 27 | const mutex_t MUTEX_INIT=PTHREAD_MUTEX_INITIALIZER; | ||
| 28 | const mtcond_t MTCOND_INIT=PTHREAD_COND_INITIALIZER; | ||
| 29 | struct 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 | ||
| 39 | typedef int mutex_t; | ||
| 40 | typedef int mtcond_t; | ||
| 41 | const mutex_t MUTEX_INIT=0; | ||
| 42 | const 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 | |||
| 26 | const int MSEC=4000; | ||
| 27 | const int RETRY=3; | ||
| 28 | const int TIMEOUT=2; | ||
| 29 | |||
| 30 | ////////////////////////////////////////////////////////////////////////// | ||
| 31 | |||
| 32 | mread::mread() : fd(-1),buf() | ||
| 33 | { | ||
| 34 | } | ||
| 35 | |||
| 36 | mread::mread(int f) : fd(f),buf() | ||
| 37 | { | ||
| 38 | } | ||
| 39 | |||
| 40 | ////////////////////////////////////////////////////////////////////////// | ||
| 41 | |||
| 42 | void mread::clear() | ||
| 43 | { | ||
| 44 | buf.clear(); | ||
| 45 | } | ||
| 46 | |||
| 47 | int mread::poll() | ||
| 48 | { | ||
| 49 | pollfd pfd={fd,POLLIN,0}; | ||
| 50 | return ::poll(&pfd,1,MSEC); | ||
| 51 | } | ||
| 52 | |||
| 53 | int 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 | |||
| 69 | void mread::putback(const sref& s) | ||
| 70 | { | ||
| 71 | if(s.nempty()) buf.insert(0,s); | ||
| 72 | } | ||
| 73 | |||
| 74 | ////////////////////////////////////////////////////////////////////////// | ||
| 75 | |||
| 76 | int 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 | |||
| 96 | int 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 | |||
| 115 | int 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 | |||
| 31 | class mread { | ||
| 32 | public: | ||
| 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 | |||
| 53 | private: | ||
| 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> | ||
| 22 | using namespace std; | ||
| 23 | |||
| 24 | mset::mset() : rpile() {} | ||
| 25 | mset::mset(const sref& in) : rpile() { | ||
| 26 | sref first,rest=in; | ||
| 27 | while(Split(first,rest)) insert(first); | ||
| 28 | } | ||
| 29 | |||
| 30 | ///////////////////////////////////////////////////////////////////////////// | ||
| 31 | |||
| 32 | int 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 | } | ||
| 36 | int 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 | |||
| 44 | void 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 | } | ||
| 49 | void 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 | } | ||
| 53 | void 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 | |||
| 60 | mstream& 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 | |||
| 66 | int 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 | } | ||
| 70 | int 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 | |||
| 78 | mstream& 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 | |||
| 27 | typedef mrvec<sref> rpile; | ||
| 28 | |||
| 29 | struct 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 | |||
| 45 | mstream& operator<<(mstream& out,const mset& m); | ||
| 46 | |||
| 47 | ////////////////////////////////////////////////////////// | ||
| 48 | |||
| 49 | typedef msvec<mstring> spile; | ||
| 50 | |||
| 51 | struct 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 | |||
| 60 | mstream& 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> | ||
| 22 | using namespace std; | ||
| 23 | |||
| 24 | const 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 | |||
| 30 | const 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 | |||
| 38 | void rrmap::sort() | ||
| 39 | { | ||
| 40 | ::sort(begin(),end()); | ||
| 41 | } | ||
| 42 | |||
| 43 | //////////////////////////////////////////////////////////////// | ||
| 44 | |||
| 45 | int 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 | |||
| 51 | int 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 | |||
| 59 | void rimap::sort() | ||
| 60 | { | ||
| 61 | ::sort(begin(),end()); | ||
| 62 | } | ||
| 63 | |||
| 64 | //////////////////////////////////////////////////////////////// | ||
| 65 | |||
| 66 | const 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 | |||
| 72 | const 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 | |||
| 80 | void 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 | |||
| 26 | struct 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 | }; | ||
| 32 | inline bool operator<(const rrstring& a,const rrstring& b) { return a.first<b.first; } | ||
| 33 | |||
| 34 | typedef mrvec<rrstring> rrpile; | ||
| 35 | |||
| 36 | struct 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 | |||
| 48 | struct 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 | }; | ||
| 55 | inline bool operator<(const rimap_t& a,const rimap_t& b) { return a.name<b.name; } | ||
| 56 | |||
| 57 | struct 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 | |||
| 69 | struct 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 | }; | ||
| 75 | inline bool operator<(const sstring& a,const sstring& b) { return a.first<b.first; } | ||
| 76 | |||
| 77 | typedef msvec<sstring> sspile; | ||
| 78 | |||
| 79 | struct 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 | |||
| 24 | const char cvt_form_f[]="%#.12f"; | ||
| 25 | const int MSEC=4000; | ||
| 26 | |||
| 27 | sref 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 | |||
| 36 | int mstream::appc(char c) { return -1; } | ||
| 37 | int mstream::appi(int i) { return -1; } | ||
| 38 | int mstream::appf(double f) { return -1; } | ||
| 39 | int mstream::apps(const sref& s) { return -1; } | ||
| 40 | |||
| 41 | /////////////////////////////////////////////////////////// | ||
| 42 | |||
| 43 | int cvt_stream::appi(int i) { sref_t buf; return apps(itoa(buf,i)); } | ||
| 44 | int cvt_stream::appf(double f) { sref_t buf; return apps(ftoa(buf,f)); } | ||
| 45 | |||
| 46 | /////////////////////////////////////////////////////////// | ||
| 47 | |||
| 48 | int fp_stream::appc(char c) { return putc(c,fp)<0?-1:1; } | ||
| 49 | int fp_stream::apps(const sref& s) { return fwrite(s.data(),s.size(),1,fp); } | ||
| 50 | |||
| 51 | /////////////////////////////////////////////////////////// | ||
| 52 | |||
| 53 | int fd_stream::appc(char c) { return ::write(fd,&c,1); } | ||
| 54 | int fd_stream::apps(const sref& s) { return ::write(fd,s.data(),s.size()); } | ||
| 55 | |||
| 56 | /////////////////////////////////////////////////////////// | ||
| 57 | |||
| 58 | int pipe_stream::appc(char c) { return mwrite(&c,1); } | ||
| 59 | int pipe_stream::apps(const sref& s) { return mwrite(s.data(),s.size()); } | ||
| 60 | |||
| 61 | int 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 | |||
| 29 | const char cvt_form_i[]="%d"; | ||
| 30 | |||
| 31 | /////////////////////////////////////////////////////////// | ||
| 32 | |||
| 33 | inline sref itoa(sref_t& buf,int i) { return sref(buf,sprintf(buf,cvt_form_i,i)); } | ||
| 34 | sref ftoa(sref_t& buf,double f); | ||
| 35 | |||
| 36 | /////////////////////////////////////////////////////////// | ||
| 37 | |||
| 38 | struct 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 | |||
| 48 | inline mstream& operator<<(mstream& out,int i) { return out.appi(i),out; } | ||
| 49 | inline mstream& operator<<(mstream& out,long l) { return out.appi(l),out; } | ||
| 50 | inline mstream& operator<<(mstream& out,unsigned u) { return out.appi(u),out; } | ||
| 51 | inline mstream& operator<<(mstream& out,unsigned long ul) { return out.appi(ul),out; } | ||
| 52 | inline mstream& operator<<(mstream& out,double f) { return out.appf(f),out; } | ||
| 53 | |||
| 54 | inline mstream& operator<<(mstream& out,const sref& s) { return out.apps(s),out; } | ||
| 55 | inline mstream& operator<<(mstream& out,const char* s) { return out.apps(sref(s)),out; } | ||
| 56 | |||
| 57 | /////////////////////////////////////////////////////////// | ||
| 58 | |||
| 59 | struct cvt_stream : public mstream { | ||
| 60 | int appi(int i); | ||
| 61 | int appf(double f); | ||
| 62 | }; | ||
| 63 | |||
| 64 | /////////////////////////////////////////////////////////// | ||
| 65 | |||
| 66 | struct 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 | |||
| 79 | struct 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 | |||
| 90 | struct 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 | |||
| 26 | uniheap<ms_mincaps> mstring::heap; | ||
| 27 | |||
| 28 | /////////////////////////////////////////////////////////////////// | ||
| 29 | |||
| 30 | mstring::mstring() : sref(heap.push(),0),caps(ms_mincaps) { | ||
| 31 | map[dim]=0; | ||
| 32 | } | ||
| 33 | mstring::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 | } | ||
| 37 | mstring::mstring(int n,char c) : sref(heap.push(),0),caps(ms_mincaps) { | ||
| 38 | resize(n); | ||
| 39 | memset(map,c,dim); | ||
| 40 | } | ||
| 41 | mstring::mstring(const char* s) : sref(heap.push(),0),caps(ms_mincaps) { | ||
| 42 | resize(strlen(s)); | ||
| 43 | memcpy(map,s,dim); | ||
| 44 | } | ||
| 45 | mstring::mstring(const char* s,int n) : sref(heap.push(),0),caps(ms_mincaps) { | ||
| 46 | resize(n); | ||
| 47 | memcpy(map,s,dim); | ||
| 48 | } | ||
| 49 | mstring::mstring(const sref& s) : sref(heap.push(),0),caps(ms_mincaps) { | ||
| 50 | resize(s.size()); | ||
| 51 | memcpy(map,s.data(),dim); | ||
| 52 | } | ||
| 53 | mstring::mstring(const mstring& s) : sref(heap.push(),0),caps(ms_mincaps) { | ||
| 54 | resize(s.dim); | ||
| 55 | memcpy(map,s.map,dim); | ||
| 56 | } | ||
| 57 | mstring::~mstring() { | ||
| 58 | if(caps==ms_mincaps) heap.pop(map); | ||
| 59 | else free(map); | ||
| 60 | } | ||
| 61 | |||
| 62 | /////////////////////////////////////////////////////////////////// | ||
| 63 | |||
| 64 | void 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 | |||
| 74 | void 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 | |||
| 91 | int 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 | |||
| 104 | mstring& 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 | |||
| 117 | int swrite::appc(char c) { return mp->put(c),1; } | ||
| 118 | int swrite::apps(const sref& s) { return mp->put(s),s.size(); } | ||
| 119 | |||
| 120 | /////////////////////////////////////////////////////////////////// | ||
| 121 | |||
| 122 | int mswrite::appc(char c) { return m.put(c),1; } | ||
| 123 | int mswrite::apps(const sref& s) { return m.put(s),s.size(); } | ||
| 124 | |||
| 125 | /////////////////////////////////////////////////////////////////// | ||
| 126 | |||
| 127 | int merror_t::appc(char c) { return desc.put(c),1; } | ||
| 128 | int merror_t::apps(const sref& s) { return desc.put(s),s.size(); } | ||
| 129 | |||
| 130 | /////////////////////////////////////////////////////////////////// | ||
| 131 | |||
| 132 | void 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 | |||
| 26 | const int ms_mincaps=32; | ||
| 27 | |||
| 28 | class mstring : public sref { | ||
| 29 | public: | ||
| 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 | |||
| 131 | protected: | ||
| 132 | static uniheap<ms_mincaps> heap; | ||
| 133 | private: | ||
| 134 | int caps; | ||
| 135 | }; | ||
| 136 | |||
| 137 | /////////////////////////////////////////////////////////////////// | ||
| 138 | |||
| 139 | inline 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 | |||
| 149 | inline mstring operator+(const sref& a,const sref& b) | ||
| 150 | { | ||
| 151 | return mstring(a).append(b); | ||
| 152 | } | ||
| 153 | inline mstring operator+(const sref& a,char b) { | ||
| 154 | return mstring(a).append(1,b); | ||
| 155 | } | ||
| 156 | inline mstring operator+(char a,const sref& b) { | ||
| 157 | return mstring(1,a).append(b); | ||
| 158 | } | ||
| 159 | |||
| 160 | /////////////////////////////////////////////////////////////////// | ||
| 161 | |||
| 162 | inline mstring btoa(int b) { return mstring(1,b?'1':'0'); } | ||
| 163 | inline mstring itoa(int i) { sref_t buf; return mstring(itoa(buf,i)); } | ||
| 164 | inline mstring ftoa(double f) { sref_t buf; return mstring(ftoa(buf,f)); } | ||
| 165 | |||
| 166 | /////////////////////////////////////////////////////////////////// | ||
| 167 | |||
| 168 | const mstring ms_empty; | ||
| 169 | |||
| 170 | /////////////////////////////////////////////////////////////////// | ||
| 171 | |||
| 172 | struct 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 | |||
| 187 | class mswrite : public cvt_stream { | ||
| 188 | public: | ||
| 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() {} | ||
| 198 | private: | ||
| 199 | mswrite(mstring&) {} // make no mistakes due to similarity with swrite | ||
| 200 | }; | ||
| 201 | |||
| 202 | /////////////////////////////////////////////////////////////////// | ||
| 203 | |||
| 204 | struct 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 | |||
| 218 | void 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 | |||
| 27 | const int mv_mincaps=16; | ||
| 28 | |||
| 29 | template <class T> class mrvec { | ||
| 30 | public: | ||
| 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 | |||
| 93 | protected: | ||
| 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 | |||
| 105 | template <class T> class msvec : public mrvec<T> { | ||
| 106 | public: | ||
| 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 | |||
| 144 | protected: | ||
| 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 | |||
| 25 | inline 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 | } | ||
| 29 | inline 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 | |||
| 29 | const int NTAB=32; // NOTE: change in header if changing this | ||
| 30 | |||
| 31 | const int IA=16807; | ||
| 32 | const int IM=2147483647; | ||
| 33 | const float AM=1/float(IM); | ||
| 34 | const int IQ=127773; | ||
| 35 | const int IR=2836; | ||
| 36 | const int NDIV=1+(IM-1)/NTAB; | ||
| 37 | const float EPS=1.2e-7; | ||
| 38 | const float RNMX=1-EPS; | ||
| 39 | |||
| 40 | static int idum,iy,iv[32],flag; | ||
| 41 | static float extra; | ||
| 42 | static int inited; | ||
| 43 | static mutex_t mutex; | ||
| 44 | |||
| 45 | unsigned 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 | |||
| 59 | float 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 | |||
| 73 | float Exponential() | ||
| 74 | { | ||
| 75 | return -log(Uniform()); | ||
| 76 | } | ||
| 77 | |||
| 78 | float 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 | |||
| 33 | unsigned long RandomInit(unsigned long seed); | ||
| 34 | |||
| 35 | float Uniform(); | ||
| 36 | float Exponential(); | ||
| 37 | float 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 @@ | |||
| 1 | ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc | ||
| 2 | c | ||
| 3 | c HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | c | ||
| 5 | c This program is free software; you can redistribute it and/or modify | ||
| 6 | c it under the terms of the GNU General Public License as published by | ||
| 7 | c the Free Software Foundation; either version 2 of the License, or | ||
| 8 | c (at your option) any later version. | ||
| 9 | c | ||
| 10 | c This program is distributed in the hope that it will be useful, | ||
| 11 | c but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | c GNU General Public License for more details. | ||
| 14 | c | ||
| 15 | c You should have received a copy of the GNU General Public License | ||
| 16 | c along with this program; if not, write to the Free Software | ||
| 17 | c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | c | ||
| 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 @@ | |||
| 1 | ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc | ||
| 2 | c | ||
| 3 | c HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | c | ||
| 5 | c This program is free software; you can redistribute it and/or modify | ||
| 6 | c it under the terms of the GNU General Public License as published by | ||
| 7 | c the Free Software Foundation; either version 2 of the License, or | ||
| 8 | c (at your option) any later version. | ||
| 9 | c | ||
| 10 | c This program is distributed in the hope that it will be useful, | ||
| 11 | c but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | c GNU General Public License for more details. | ||
| 14 | c | ||
| 15 | c You should have received a copy of the GNU General Public License | ||
| 16 | c along with this program; if not, write to the Free Software | ||
| 17 | c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | c | ||
| 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 @@ | |||
| 1 | ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc | ||
| 2 | c | ||
| 3 | c HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | c | ||
| 5 | c This program is free software; you can redistribute it and/or modify | ||
| 6 | c it under the terms of the GNU General Public License as published by | ||
| 7 | c the Free Software Foundation; either version 2 of the License, or | ||
| 8 | c (at your option) any later version. | ||
| 9 | c | ||
| 10 | c This program is distributed in the hope that it will be useful, | ||
| 11 | c but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | c GNU General Public License for more details. | ||
| 14 | c | ||
| 15 | c You should have received a copy of the GNU General Public License | ||
| 16 | c along with this program; if not, write to the Free Software | ||
| 17 | c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | c | ||
| 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 @@ | |||
| 1 | ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc | ||
| 2 | c | ||
| 3 | c HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | c | ||
| 5 | c This program is free software; you can redistribute it and/or modify | ||
| 6 | c it under the terms of the GNU General Public License as published by | ||
| 7 | c the Free Software Foundation; either version 2 of the License, or | ||
| 8 | c (at your option) any later version. | ||
| 9 | c | ||
| 10 | c This program is distributed in the hope that it will be useful, | ||
| 11 | c but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | c GNU General Public License for more details. | ||
| 14 | c | ||
| 15 | c You should have received a copy of the GNU General Public License | ||
| 16 | c along with this program; if not, write to the Free Software | ||
| 17 | c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | c | ||
| 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 @@ | |||
| 1 | ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc | ||
| 2 | c | ||
| 3 | c HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | c | ||
| 5 | c This program is free software; you can redistribute it and/or modify | ||
| 6 | c it under the terms of the GNU General Public License as published by | ||
| 7 | c the Free Software Foundation; either version 2 of the License, or | ||
| 8 | c (at your option) any later version. | ||
| 9 | c | ||
| 10 | c This program is distributed in the hope that it will be useful, | ||
| 11 | c but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | c GNU General Public License for more details. | ||
| 14 | c | ||
| 15 | c You should have received a copy of the GNU General Public License | ||
| 16 | c along with this program; if not, write to the Free Software | ||
| 17 | c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | c | ||
| 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 @@ | |||
| 1 | ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc | ||
| 2 | c | ||
| 3 | c HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | c | ||
| 5 | c This program is free software; you can redistribute it and/or modify | ||
| 6 | c it under the terms of the GNU General Public License as published by | ||
| 7 | c the Free Software Foundation; either version 2 of the License, or | ||
| 8 | c (at your option) any later version. | ||
| 9 | c | ||
| 10 | c This program is distributed in the hope that it will be useful, | ||
| 11 | c but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | c GNU General Public License for more details. | ||
| 14 | c | ||
| 15 | c You should have received a copy of the GNU General Public License | ||
| 16 | c along with this program; if not, write to the Free Software | ||
| 17 | c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | c | ||
| 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 @@ | |||
| 1 | ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc | ||
| 2 | c | ||
| 3 | c HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | c | ||
| 5 | c This program is free software; you can redistribute it and/or modify | ||
| 6 | c it under the terms of the GNU General Public License as published by | ||
| 7 | c the Free Software Foundation; either version 2 of the License, or | ||
| 8 | c (at your option) any later version. | ||
| 9 | c | ||
| 10 | c This program is distributed in the hope that it will be useful, | ||
| 11 | c but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | c GNU General Public License for more details. | ||
| 14 | c | ||
| 15 | c You should have received a copy of the GNU General Public License | ||
| 16 | c along with this program; if not, write to the Free Software | ||
| 17 | c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | c | ||
| 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 | |||
| 25 | inline sref Skip(const sref& a,const charset& ws=cset_ws) { | ||
| 26 | return a.right_first_not_of(ws); | ||
| 27 | } | ||
| 28 | |||
| 29 | inline 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 | |||
| 33 | inline 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 | |||
| 40 | inline sref First(const sref& a,const charset& ws=cset_ws) { | ||
| 41 | return a.right_first_not_of(ws).left_first_of(ws); | ||
| 42 | } | ||
| 43 | |||
| 44 | inline 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 | |||
| 48 | inline 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 | |||
| 54 | inline 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 | |||
| 62 | inline 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 | |||
| 69 | typedef 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 @@ | |||
| 1 | ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc | ||
| 2 | c | ||
| 3 | c HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | c | ||
| 5 | c This program is free software; you can redistribute it and/or modify | ||
| 6 | c it under the terms of the GNU General Public License as published by | ||
| 7 | c the Free Software Foundation; either version 2 of the License, or | ||
| 8 | c (at your option) any later version. | ||
| 9 | c | ||
| 10 | c This program is distributed in the hope that it will be useful, | ||
| 11 | c but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | c GNU General Public License for more details. | ||
| 14 | c | ||
| 15 | c You should have received a copy of the GNU General Public License | ||
| 16 | c along with this program; if not, write to the Free Software | ||
| 17 | c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | c | ||
| 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 @@ | |||
| 1 | ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc | ||
| 2 | c | ||
| 3 | c HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | c | ||
| 5 | c This program is free software; you can redistribute it and/or modify | ||
| 6 | c it under the terms of the GNU General Public License as published by | ||
| 7 | c the Free Software Foundation; either version 2 of the License, or | ||
| 8 | c (at your option) any later version. | ||
| 9 | c | ||
| 10 | c This program is distributed in the hope that it will be useful, | ||
| 11 | c but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | c GNU General Public License for more details. | ||
| 14 | c | ||
| 15 | c You should have received a copy of the GNU General Public License | ||
| 16 | c along with this program; if not, write to the Free Software | ||
| 17 | c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | c | ||
| 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 | |||
| 26 | template <class T> class stackque { | ||
| 27 | public: | ||
| 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; } | ||
| 58 | private: | ||
| 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 | |||
| 24 | extern "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 | |||
| 44 | char* 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 | |||
| 51 | int 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 | |||
| 58 | void sref::tolower() { sconvert_(map,dim,cset_lcase.map); } | ||
| 59 | void sref::toupper() { sconvert_(map,dim,cset_ucase.map); } | ||
| 60 | void sref::tosim(const charmap& s) { sconvert_(map,dim,s.map); } | ||
| 61 | |||
| 62 | //////////////////////////////////////////////////// | ||
| 63 | |||
| 64 | sref 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 | |||
| 74 | sref 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 | } | ||
| 79 | sref 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 | } | ||
| 84 | sref 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 | } | ||
| 89 | sref 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 | |||
| 97 | int sref::find(char c) const { return cfind_(map,dim,c); } | ||
| 98 | int sref::rfind(char c) const { return crfind_(map,dim,c); } | ||
| 99 | int sref::find(const sref& s) const { return sfind_(map,dim,s.map,s.dim); } | ||
| 100 | int sref::rfind(const sref& s) const { return srfind_(map,dim,s.map,s.dim); } | ||
| 101 | int sref::find(const sref& s,const charmap& tab) const { | ||
| 102 | return sfindtab_(map,dim,s.map,s.dim,tab.map); | ||
| 103 | } | ||
| 104 | int sref::rfind(const sref& s,const charmap& tab) const { | ||
| 105 | return srfindtab_(map,dim,s.map,s.dim,tab.map); | ||
| 106 | } | ||
| 107 | |||
| 108 | int sref::find_of(const charset& s) const { return find_of__(map,dim,s.map); } | ||
| 109 | int sref::rfind_of(const charset& s) const { return rfind_of__(map,dim,s.map); } | ||
| 110 | int sref::find_not_of(const charset& s) const { return find_not_of__(map,dim,s.map); } | ||
| 111 | int sref::rfind_not_of(const charset& s) const { return rfind_not_of__(map,dim,s.map); } | ||
| 112 | |||
| 113 | int sref::skip(const bracket& bra) const { | ||
| 114 | return skip_parentesis__(map,dim,bra.left,bra.right,bra.esc); | ||
| 115 | } | ||
| 116 | |||
| 117 | //////////////////////////////////////////////////////////////// | ||
| 118 | |||
| 119 | int 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 | |||
| 26 | typedef char sref_t[1024]; | ||
| 27 | |||
| 28 | class sref { | ||
| 29 | public: | ||
| 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 | |||
| 182 | protected: | ||
| 183 | char* map; | ||
| 184 | int dim; | ||
| 185 | }; | ||
| 186 | |||
| 187 | //////////////////////////////////////////////////// | ||
| 188 | |||
| 189 | inline bool operator<(const sref& a,const sref& b) { | ||
| 190 | return a.compare(b)<0; | ||
| 191 | } | ||
| 192 | inline bool operator<=(const sref& a,const sref& b) { | ||
| 193 | return a.compare(b)<=0; | ||
| 194 | } | ||
| 195 | inline bool operator==(const sref& a,const sref& b) { | ||
| 196 | return a.compare(b)==0; | ||
| 197 | } | ||
| 198 | inline bool operator!=(const sref& a,const sref& b) { | ||
| 199 | return a.compare(b)!=0; | ||
| 200 | } | ||
| 201 | inline bool operator>=(const sref& a,const sref& b) { | ||
| 202 | return a.compare(b)>=0; | ||
| 203 | } | ||
| 204 | inline bool operator>(const sref& a,const sref& b) { | ||
| 205 | return a.compare(b)>0; | ||
| 206 | } | ||
| 207 | |||
| 208 | ////////////////////////////////////////////////////////////////////////// | ||
| 209 | |||
| 210 | inline int operator-(const sref& a,const sref& b) { return a.data()-b.data(); } | ||
| 211 | |||
| 212 | ////////////////////////////////////////////////////////////////////////// | ||
| 213 | |||
| 214 | inline int ltn(const sref& a,const sref& b) { | ||
| 215 | return a.compare(b,cset_lcase)<0; | ||
| 216 | } | ||
| 217 | inline int len(const sref& a,const sref& b) { | ||
| 218 | return a.compare(b,cset_lcase)<=0; | ||
| 219 | } | ||
| 220 | inline int eqn(const sref& a,const sref& b) { | ||
| 221 | return a.compare(b,cset_lcase)==0; | ||
| 222 | } | ||
| 223 | inline int nen(const sref& a,const sref& b) { | ||
| 224 | return a.compare(b,cset_lcase)!=0; | ||
| 225 | } | ||
| 226 | inline int gen(const sref& a,const sref& b) { | ||
| 227 | return a.compare(b,cset_lcase)>=0; | ||
| 228 | } | ||
| 229 | inline int gtn(const sref& a,const sref& b) { | ||
| 230 | return a.compare(b,cset_lcase)>0; | ||
| 231 | } | ||
| 232 | |||
| 233 | ////////////////////////////////////////////////////////////////////////// | ||
| 234 | |||
| 235 | inline int atob(const sref& s) { sref_t buf; return atoi(s.copyto(buf))!=0; } | ||
| 236 | inline int atoi(const sref& s) { sref_t buf; return atoi(s.copyto(buf)); } | ||
| 237 | inline 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 @@ | |||
| 1 | ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc | ||
| 2 | c | ||
| 3 | c HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | c | ||
| 5 | c This program is free software; you can redistribute it and/or modify | ||
| 6 | c it under the terms of the GNU General Public License as published by | ||
| 7 | c the Free Software Foundation; either version 2 of the License, or | ||
| 8 | c (at your option) any later version. | ||
| 9 | c | ||
| 10 | c This program is distributed in the hope that it will be useful, | ||
| 11 | c but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | c GNU General Public License for more details. | ||
| 14 | c | ||
| 15 | c You should have received a copy of the GNU General Public License | ||
| 16 | c along with this program; if not, write to the Free Software | ||
| 17 | c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | c | ||
| 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 | |||
| 42 | static fp_stream mout(stdout),merr(stderr); | ||
| 43 | |||
| 44 | main(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 | |||
| 32 | template <int N> class uniheap { | ||
| 33 | public: | ||
| 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; } | ||
| 46 | protected: | ||
| 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 | } | ||
| 59 | private: | ||
| 60 | char *head,*chunks[maxchunks]; | ||
| 61 | int chunk,nchunks; | ||
| 62 | mutex_t mutex; | ||
| 63 | }; | ||
| 64 | |||
| 65 | #endif | ||
