From 5df79c53745fde5d6c3340a2979b1429cd5892c1 Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Sat, 8 Oct 2011 20:30:28 +0200 Subject: Initial import of htcd system 1.0 Signed-off-by: Henrik Rydberg --- src/mt/cfind.f | 80 +++++++++++ src/mt/charset.h | 131 ++++++++++++++++++ src/mt/config.cc | 33 +++++ src/mt/config.h | 27 ++++ src/mt/crfind.f | 80 +++++++++++ src/mt/dates.cc | 207 +++++++++++++++++++++++++++++ src/mt/dates.h | 49 +++++++ src/mt/find_not_of.f | 80 +++++++++++ src/mt/find_of.f | 80 +++++++++++ src/mt/issue.cc | 51 +++++++ src/mt/issue.h | 55 ++++++++ src/mt/lock.cc | 114 ++++++++++++++++ src/mt/lock.h | 72 ++++++++++ src/mt/lookup.cc | 88 +++++++++++++ src/mt/lookup.h | 32 +++++ src/mt/mlock.h | 48 +++++++ src/mt/mread.cc | 135 +++++++++++++++++++ src/mt/mread.h | 63 +++++++++ src/mt/mset.cc | 81 ++++++++++++ src/mt/mset.h | 62 +++++++++ src/mt/msmap.cc | 84 ++++++++++++ src/mt/msmap.h | 89 +++++++++++++ src/mt/mstream.cc | 72 ++++++++++ src/mt/mstream.h | 103 +++++++++++++++ src/mt/mstring.cc | 139 +++++++++++++++++++ src/mt/mstring.h | 222 +++++++++++++++++++++++++++++++ src/mt/mvec.h | 149 +++++++++++++++++++++ src/mt/qran.h | 34 +++++ src/mt/random.cc | 95 +++++++++++++ src/mt/random.h | 39 ++++++ src/mt/rfind_not_of.f | 80 +++++++++++ src/mt/rfind_of.f | 80 +++++++++++ src/mt/scomptab.f | 44 +++++++ src/mt/sconvert.f | 35 +++++ src/mt/sfind.f | 40 ++++++ src/mt/sfindtab.f | 40 ++++++ src/mt/skip_parentesis.f | 42 ++++++ src/mt/split.h | 72 ++++++++++ src/mt/srfind.f | 40 ++++++ src/mt/srfindtab.f | 40 ++++++ src/mt/stackque.h | 64 +++++++++ src/mt/stringref.cc | 126 ++++++++++++++++++ src/mt/stringref.h | 239 +++++++++++++++++++++++++++++++++ src/mt/strip.f | 31 +++++ src/mt/test.cc | 337 +++++++++++++++++++++++++++++++++++++++++++++++ src/mt/uniheap.h | 65 +++++++++ 46 files changed, 3969 insertions(+) create mode 100644 src/mt/cfind.f create mode 100644 src/mt/charset.h create mode 100644 src/mt/config.cc create mode 100644 src/mt/config.h create mode 100644 src/mt/crfind.f create mode 100644 src/mt/dates.cc create mode 100644 src/mt/dates.h create mode 100644 src/mt/find_not_of.f create mode 100644 src/mt/find_of.f create mode 100644 src/mt/issue.cc create mode 100644 src/mt/issue.h create mode 100644 src/mt/lock.cc create mode 100644 src/mt/lock.h create mode 100644 src/mt/lookup.cc create mode 100644 src/mt/lookup.h create mode 100644 src/mt/mlock.h create mode 100644 src/mt/mread.cc create mode 100644 src/mt/mread.h create mode 100644 src/mt/mset.cc create mode 100644 src/mt/mset.h create mode 100644 src/mt/msmap.cc create mode 100644 src/mt/msmap.h create mode 100644 src/mt/mstream.cc create mode 100644 src/mt/mstream.h create mode 100644 src/mt/mstring.cc create mode 100644 src/mt/mstring.h create mode 100644 src/mt/mvec.h create mode 100644 src/mt/qran.h create mode 100644 src/mt/random.cc create mode 100644 src/mt/random.h create mode 100644 src/mt/rfind_not_of.f create mode 100644 src/mt/rfind_of.f create mode 100644 src/mt/scomptab.f create mode 100644 src/mt/sconvert.f create mode 100644 src/mt/sfind.f create mode 100644 src/mt/sfindtab.f create mode 100644 src/mt/skip_parentesis.f create mode 100644 src/mt/split.h create mode 100644 src/mt/srfind.f create mode 100644 src/mt/srfindtab.f create mode 100644 src/mt/stackque.h create mode 100644 src/mt/stringref.cc create mode 100644 src/mt/stringref.h create mode 100644 src/mt/strip.f create mode 100644 src/mt/test.cc create mode 100644 src/mt/uniheap.h (limited to 'src/mt') 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 @@ +ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +c +c HTCd - Copyright (C) 1998-2006 Henrik Rydberg +c +c This program is free software; you can redistribute it and/or modify +c it under the terms of the GNU General Public License as published by +c the Free Software Foundation; either version 2 of the License, or +c (at your option) any later version. +c +c This program is distributed in the hope that it will be useful, +c but WITHOUT ANY WARRANTY; without even the implied warranty of +c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +c GNU General Public License for more details. +c +c You should have received a copy of the GNU General Public License +c along with this program; if not, write to the Free Software +c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +c + + integer function cfind(s,n,c) + character s(0:1),c + integer i,m,n + m=mod(n,16) + do 10 i=0,m-1 + if(s(i).eq.c)go to 100 + 10 continue + do 20 i=m,n-1,16 + if(s(i).eq.c)go to 100 + if(s(i+1).eq.c)go to 101 + if(s(i+2).eq.c)go to 102 + if(s(i+3).eq.c)go to 103 + if(s(i+4).eq.c)go to 104 + if(s(i+5).eq.c)go to 105 + if(s(i+6).eq.c)go to 106 + if(s(i+7).eq.c)go to 107 + if(s(i+8).eq.c)go to 108 + if(s(i+9).eq.c)go to 109 + if(s(i+10).eq.c)go to 110 + if(s(i+11).eq.c)go to 111 + if(s(i+12).eq.c)go to 112 + if(s(i+13).eq.c)go to 113 + if(s(i+14).eq.c)go to 114 + if(s(i+15).eq.c)go to 115 + 20 continue + cfind=-1 + return + 100 cfind=i + return + 101 cfind=i+1 + return + 102 cfind=i+2 + return + 103 cfind=i+3 + return + 104 cfind=i+4 + return + 105 cfind=i+5 + return + 106 cfind=i+6 + return + 107 cfind=i+7 + return + 108 cfind=i+8 + return + 109 cfind=i+9 + return + 110 cfind=i+10 + return + 111 cfind=i+11 + return + 112 cfind=i+12 + return + 113 cfind=i+13 + return + 114 cfind=i+14 + return + 115 cfind=i+15 + return + end + 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef CHARSETH +#define CHARSETH + +#include + +struct charset { + explicit charset(const char s[]) { + memset(negmap,0,256); while(*s) map[*s++]=1; + } + charset(char beg,char end) { + memset(negmap,0,256); while(beg<=end) map[beg++]=1; + } + int test(char c) const { return map[c]; } + int operator[](char c) const { return map[c]; } + char negmap[128],map[128]; +}; + +inline charset operator|(const charset& a,const charset& b) { + charset c(a); for(int i=-127;i<128;i++) c.map[i]|=b.map[i]; return c; +} +inline charset operator|(const charset& a,char b) { + charset c(a); c.map[b]=(b!=0); return c; +} +inline charset operator|(char a,const charset& b) { + charset c(b); c.map[a]=(a!=0); return c; +} +inline charset operator&(const charset& a,const charset& b) { + charset c(a); for(int i=-127;i<128;i++) c.map[i]&=b.map[i]; return c; +} +inline charset operator^(const charset& a,const charset& b) { + charset c(a); for(int i=-127;i<128;i++) c.map[i]^=b.map[i]; return c; +} +inline charset operator-(const charset& a,const charset& b) { + charset c(a); for(int i=-127;i<128;i++) c.map[i]&=~b.map[i]; return c; +} +inline charset operator-(const charset& a,char b) { + charset c(a); c.map[b]=0; return c; +} +inline charset operator~(const charset& a) { + charset c(a); for(int i=-127;i<128;i++) c.map[i]=!c.map[i]; c.map[0]=0; + return c; +} + +////////////////////////////////////////////////////////////////////////// + +struct charmap { + charmap() { for(int i=-127;i<128;i++) map[i]=i; } + charmap(const charset& a,const charset& b) { + for(int i=-127,j=-127;i<128;i++) { + if(a[i]) { while(j<128&&!b[j]) j++; map[i]=j++; } + else map[i]=i; + } + } + charmap(const charset& a,const char* b) { + for(int i=-127;i<128;i++) if(a[i]&&*b) map[i]=*b++; else map[i]=i; + } + char operator[](char c) const { return map[c]; } + char negmap[128],map[128]; +}; + +inline charmap operator<<(const charmap& a,const charmap& b) { + charmap c(a); + for(int i=-127;i<128;i++) if(b.map[i]!=i) c.map[i]=b.map[i]; + for(int i=-127;i<128;i++) c.map[i]=c.map[c.map[i]]; + return c; +} + +////////////////////////////////////////////////////////////////////////// + +struct bracket { + explicit bracket(const char s[]) { strncpy(&left,s,sizeof(bracket)); } + int test(char c) const { return c==left||c==right; } + char left,right,esc,end; +}; + +////////////////////////////////////////////////////////////////////////// + +const charset cset_spaces(" \t"); +const charset cset_newl("\r\n"); +const charset cset_ws=cset_spaces|cset_newl; +const charset cset_printable(' ','~'); +const charset cset_digit('0','9'); +const charset cset_real=cset_digit|'.'; +const charset cset_sign("+-"); +const charset cset_lalpha('a','z'); +const charset cset_ualpha('A','Z'); +const charset cset_alpha=cset_lalpha|cset_ualpha; +const charset cset_alphanum=cset_alpha|cset_digit; +const charset cset_alphareal=cset_alpha|cset_real; +const charset cset_lext1(-32,-10),cset_lext2(-8,-2); +const charset cset_uext1(-64,-42),cset_uext2(-40,-34); +const charset cset_liso=cset_lalpha|cset_lext1|cset_lext2; +const charset cset_uiso=cset_ualpha|cset_uext1|cset_uext2; + +const charmap cset_ident; +const charmap cset_leqv1(cset_lext1,"aaaaaaaceeeeiiiidnooooo"); +const charmap cset_leqv2(cset_lext2,"ouuuuyp"); +const charmap cset_ueqv1(cset_uext1,"AAAAAAACEEEEIIIIDNOOOOO"); +const charmap cset_ueqv2(cset_uext2,"OUUUUYP"); + +const charmap cset_lcase(cset_uiso,cset_liso); +const charmap cset_ucase(cset_liso,cset_uiso); +const charmap cset_sim=cset_lcase<\\"); + +#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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +mstring htchome() +{ + const char* p=getenv("HTCHOME"); + if(!p) { + fprintf(stderr,"env: HTCHOME not set, exiting\n"); + exit(-1); + } + mstring home=p; + if(home.back()=='/') home=home.popb(); + return home; +} + 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef CONFIGH +#define CONFIGH + +#include + +mstring htchome(); + +#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 @@ +ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +c +c HTCd - Copyright (C) 1998-2006 Henrik Rydberg +c +c This program is free software; you can redistribute it and/or modify +c it under the terms of the GNU General Public License as published by +c the Free Software Foundation; either version 2 of the License, or +c (at your option) any later version. +c +c This program is distributed in the hope that it will be useful, +c but WITHOUT ANY WARRANTY; without even the implied warranty of +c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +c GNU General Public License for more details. +c +c You should have received a copy of the GNU General Public License +c along with this program; if not, write to the Free Software +c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +c + + integer function crfind(s,n,c) + character s(0:1),c + integer i,m,n + m=mod(n,16) + do 10 i=n-16,m,-16 + if(s(i+15).eq.c)go to 115 + if(s(i+14).eq.c)go to 114 + if(s(i+13).eq.c)go to 113 + if(s(i+12).eq.c)go to 112 + if(s(i+11).eq.c)go to 111 + if(s(i+10).eq.c)go to 110 + if(s(i+9).eq.c)go to 109 + if(s(i+8).eq.c)go to 108 + if(s(i+7).eq.c)go to 107 + if(s(i+6).eq.c)go to 106 + if(s(i+5).eq.c)go to 105 + if(s(i+4).eq.c)go to 104 + if(s(i+3).eq.c)go to 103 + if(s(i+2).eq.c)go to 102 + if(s(i+1).eq.c)go to 101 + if(s(i).eq.c)go to 100 + 10 continue + do 20 i=m-1,0,-1 + if(s(i).eq.c)go to 100 + 20 continue + crfind=-1 + return + 100 crfind=i + return + 101 crfind=i+1 + return + 102 crfind=i+2 + return + 103 crfind=i+3 + return + 104 crfind=i+4 + return + 105 crfind=i+5 + return + 106 crfind=i+6 + return + 107 crfind=i+7 + return + 108 crfind=i+8 + return + 109 crfind=i+9 + return + 110 crfind=i+10 + return + 111 crfind=i+11 + return + 112 crfind=i+12 + return + 113 crfind=i+13 + return + 114 crfind=i+14 + return + 115 crfind=i+15 + return + end + 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include + +const mstring SWEEK[MAXLANG][7]={ + "Sun","Mon","Tue","Wed","Thu","Fri","Sat", + "Sön","Mån","Tis","Ons","Tor","Fre","Lör" +}; +const mstring SMONTH[MAXLANG][12]={ + "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec", + "Jan","Feb","Mar","Apr","Maj","Jun","Jul","Aug","Sep","Okt","Nov","Dec" +}; +const mstring WEEK[MAXLANG][7]={ + "Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday", + "Söndag","Måndag","Tisdag","Onsdag","Torsdag","Fredag","Lördag" +}; +const mstring MONTH[MAXLANG][12]={ + "January","February","March","April","May","June", + "July","August","September","October","November","December", + "Januari","Februari","Mars","April","Maj","Juni", + "Juli","Augusti","September","Oktober","November","December" +}; + +time_t Today(time_t now) +{ + tm s; localtime_r(&now,&s); + s.tm_hour=0; + s.tm_min=0; + s.tm_sec=0; + return mktime(&s); +} + +time_t Sunday(time_t now) +{ + tm s; localtime_r(&now,&s); + s.tm_mday-=s.tm_wday; + return mktime(&s); +} + +const mstring& Week(int lang,time_t t) +{ + tm s; return WEEK[lang][localtime_r(&t,&s)->tm_wday]; +} + +const mstring& Month(int lang,time_t t) +{ + tm s; return MONTH[lang][localtime_r(&t,&s)->tm_mon]; +} + +const mstring& SWeek(int lang,time_t t) +{ + tm s; return SWEEK[lang][localtime_r(&t,&s)->tm_wday]; +} + +const mstring& SMonth(int lang,time_t t) +{ + tm s; return SMONTH[lang][localtime_r(&t,&s)->tm_mon]; +} + +mstring httpTime(time_t t) +{ + tm tt; gmtime_r(&t,&tt); + return mstring().convert("%s, %02d %s %4d %02d:%02d:%02d GMT", + SWEEK[0][tt.tm_wday].c_str(), + tt.tm_mday, + SMONTH[0][tt.tm_mon].c_str(), + tt.tm_year+1900, + tt.tm_hour, + tt.tm_min, + tt.tm_sec); +} + +mstring htcTime(int lang,time_t t) +{ + tm tt; localtime_r(&t,&tt); + mstring s(32); asctime_r(&tt,s.data()); s.resize(24); + if(lang) { + for(int i=0;i<7;i++) if(s(0,3)==SWEEK[0][i]) { + s.replace(0,3,SWEEK[lang][i]); + break; + } + for(int i=0;i<12;i++) if(s(4,3)==SMONTH[0][i]) { + s.replace(4,3,SMONTH[lang][i]); + break; + } + } + return s; +} + +static int Month(int& mon,const sref& st) +{ + mstring s=st; s.tolower(); s[0]=toupper(s[0]); + for(int lang=0;lang=0&&h<=24&&m>=0&&m<60&&s>=0&&s<60) { th=h; tmi=m; ts=s; return 1; } + return 0; +} + +static int Day(int& day,const sref& s) +{ + if(s.find_not_of(cset_digit)>=0) return 0; + int d=atoi(s); + if(d>0&&d<32) { day=d; return 1; } + return 0; +} + +static int Year(int& year,const sref& s) +{ + if(s.find_not_of(cset_digit)>=0) return 0; + int y=atoi(s); + if(y>=32&&y<9999) { year=y; return 1; } + return 0; +} + +time_t htcTime(int lang,const sref& date) +{ + sref week,month,day,when,year,rest=date; + Split(week,rest); + Split(month,rest); + Split(day,rest); + Split(when,rest); + Split(year,rest); + struct tm t; + Time(t.tm_hour,t.tm_min,t.tm_sec,when); + t.tm_mday=atoi(day); + Month(t.tm_mon,month); + t.tm_year=atoi(year)-1900; + Week(t.tm_wday,week); + t.tm_isdst=-1; + return mktime(&t); +} + +time_t cvtTime(const sref& code) +{ + time_t now=time(0); + tm t; localtime_r(&now,&t); + t.tm_hour=0;t.tm_min=0;t.tm_sec=0; + //Start with 00:00:00 today + sref first,rest=code; + int w=0,m=0,d=0,h=0,y=0; + while(Split(first,rest)) { + if(!w) w=Week(t.tm_wday,first); + if(!m) m=Month(t.tm_mon,first); + if(!h) h=Time(t.tm_hour,t.tm_min,t.tm_sec,first); + if(!d) d=Day(t.tm_mday,first); + if(!y) if(y=Year(t.tm_year,first)) t.tm_year-=1900; + } + t.tm_isdst=-1; + return mktime(&t); +} + +////////////////////////////// + +int Language(const sref& st) +{ + static const charset seps=cset_ws|charset(",;"); + mstring s=st; s.tolower(); + sref first,rest=s; + while(Split(first,rest,seps)) { + for(int i=0;i +#include + +const time_t SEC_PER_DAY=86400; +const int MAXLANG=2; +const mstring LANG[MAXLANG]={"en","sv"}; + +inline time_t Now() { return time(0); } +inline time_t Days(int days) { return days*SEC_PER_DAY; } + +time_t Today(time_t); +time_t Sunday(time_t); + +const mstring& Week(int lang,time_t t); +const mstring& Month(int lang,time_t t); + +const mstring& SWeek(int lang,time_t t); +const mstring& SMonth(int lang,time_t t); + +mstring httpTime(time_t t); +mstring htcTime(int lang,time_t t); +time_t htcTime(int lang,const sref& date); +time_t cvtTime(const sref& code); + +int Language(const sref& s); + +#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 @@ +ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +c +c HTCd - Copyright (C) 1998-2006 Henrik Rydberg +c +c This program is free software; you can redistribute it and/or modify +c it under the terms of the GNU General Public License as published by +c the Free Software Foundation; either version 2 of the License, or +c (at your option) any later version. +c +c This program is distributed in the hope that it will be useful, +c but WITHOUT ANY WARRANTY; without even the implied warranty of +c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +c GNU General Public License for more details. +c +c You should have received a copy of the GNU General Public License +c along with this program; if not, write to the Free Software +c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +c + + integer function find_not_of(s,n,c) + byte s(0:1),c(0:1) + integer i,m,n + m=mod(n,16) + do 10 i=0,m-1 + if(c(s(i)).eq.0)go to 100 + 10 continue + do 20 i=m,n-1,16 + if(c(s(i)).eq.0)go to 100 + if(c(s(i+1)).eq.0)go to 101 + if(c(s(i+2)).eq.0)go to 102 + if(c(s(i+3)).eq.0)go to 103 + if(c(s(i+4)).eq.0)go to 104 + if(c(s(i+5)).eq.0)go to 105 + if(c(s(i+6)).eq.0)go to 106 + if(c(s(i+7)).eq.0)go to 107 + if(c(s(i+8)).eq.0)go to 108 + if(c(s(i+9)).eq.0)go to 109 + if(c(s(i+10)).eq.0)go to 110 + if(c(s(i+11)).eq.0)go to 111 + if(c(s(i+12)).eq.0)go to 112 + if(c(s(i+13)).eq.0)go to 113 + if(c(s(i+14)).eq.0)go to 114 + if(c(s(i+15)).eq.0)go to 115 + 20 continue + find_not_of=-1 + return + 100 find_not_of=i + return + 101 find_not_of=i+1 + return + 102 find_not_of=i+2 + return + 103 find_not_of=i+3 + return + 104 find_not_of=i+4 + return + 105 find_not_of=i+5 + return + 106 find_not_of=i+6 + return + 107 find_not_of=i+7 + return + 108 find_not_of=i+8 + return + 109 find_not_of=i+9 + return + 110 find_not_of=i+10 + return + 111 find_not_of=i+11 + return + 112 find_not_of=i+12 + return + 113 find_not_of=i+13 + return + 114 find_not_of=i+14 + return + 115 find_not_of=i+15 + return + end + 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 @@ +ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +c +c HTCd - Copyright (C) 1998-2006 Henrik Rydberg +c +c This program is free software; you can redistribute it and/or modify +c it under the terms of the GNU General Public License as published by +c the Free Software Foundation; either version 2 of the License, or +c (at your option) any later version. +c +c This program is distributed in the hope that it will be useful, +c but WITHOUT ANY WARRANTY; without even the implied warranty of +c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +c GNU General Public License for more details. +c +c You should have received a copy of the GNU General Public License +c along with this program; if not, write to the Free Software +c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +c + + integer function find_of(s,n,c) + byte s(0:1),c(0:1) + integer i,m,n + m=mod(n,16) + do 10 i=0,m-1 + if(c(s(i)).ne.0)go to 100 + 10 continue + do 20 i=m,n-1,16 + if(c(s(i)).ne.0)go to 100 + if(c(s(i+1)).ne.0)go to 101 + if(c(s(i+2)).ne.0)go to 102 + if(c(s(i+3)).ne.0)go to 103 + if(c(s(i+4)).ne.0)go to 104 + if(c(s(i+5)).ne.0)go to 105 + if(c(s(i+6)).ne.0)go to 106 + if(c(s(i+7)).ne.0)go to 107 + if(c(s(i+8)).ne.0)go to 108 + if(c(s(i+9)).ne.0)go to 109 + if(c(s(i+10)).ne.0)go to 110 + if(c(s(i+11)).ne.0)go to 111 + if(c(s(i+12)).ne.0)go to 112 + if(c(s(i+13)).ne.0)go to 113 + if(c(s(i+14)).ne.0)go to 114 + if(c(s(i+15)).ne.0)go to 115 + 20 continue + find_of=-1 + return + 100 find_of=i + return + 101 find_of=i+1 + return + 102 find_of=i+2 + return + 103 find_of=i+3 + return + 104 find_of=i+4 + return + 105 find_of=i+5 + return + 106 find_of=i+6 + return + 107 find_of=i+7 + return + 108 find_of=i+8 + return + 109 find_of=i+9 + return + 110 find_of=i+10 + return + 111 find_of=i+11 + return + 112 find_of=i+12 + return + 113 find_of=i+13 + return + 114 find_of=i+14 + return + 115 find_of=i+15 + return + end + 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include + +void issue_t::run(mstream& out,const sref& in) throw(merror_t) +{ + int ip[2],op[2]; + pipe(ip); pipe(op); + sigignore(SIGPIPE); + int pid=fork(); + if(pid) { + close(ip[0]); + close(op[1]); + write(ip[1],in.data(),in.size()); + close(ip[1]); + sref_t buf; int n; + while((n=read(op[0],buf,sizeof(sref_t)))>0) out.write(buf,n); + close(op[0]); + if(wait(0)<0) kill(pid,SIGKILL); + } + else { + close(ip[1]); + close(op[0]); + dup2(ip[0],0); + close(ip[0]); + dup2(op[1],1); + close(op[1]); + execv(*argv(),argv()); + _exit(0); + } +} + 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef ISSUEH +#define ISSUEH + +#include +#include +#include + +// ISSUE A PIPED COMMAND +// +// This class is tuned to work in a mt environment. +// The aim is to make this work locally as if it was +// a single thread returning something to the stream out +// depending on the input in. + +struct issue_t { + mrvec arg; + + issue_t() {} + ~issue_t() { clear(); } + + issue_t(const sref& s,const charset& ws=cset_ws) { + sref first,rest=s; + while(Split(first,rest,ws)) arg.push_back(first.news()); + arg.push_back(0); + } + + void clear() { for(int i=0;i +#include +#include +#include +#include +#include +using namespace std; + +const mstring LOCK=".lock"; + +void LockFile(const mstring& path,int prot) throw(merror_t) +{ + mstring name=path+LOCK; int fd; + while((fd=open(name.c_str(),O_CREAT|O_WRONLY|O_TRUNC|O_EXCL,prot))==-1&& + errno==EEXIST) sleep(1); + if(fd<0) THROW("lock: could not create lock file "<=0) { + if(buf.nempty()&&buf!=sref(uts.nodename)) + THROW("nodelock: already locked on "<=0) while(!kill(atoi(buf),SIGTERM)) sleep(stime); +} + 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef LOCKH +#define LOCKH + +#include + +// OFFERS TWO LOCKING MECHANISMS + +void LockFile(const mstring& path,int prot=0660) throw(merror_t); +void UnlockFile(const mstring& path); + +// These functions create an exclusive lock on path by +// creating a file path.lock. +// Works well and is the same mechnism used by +// mailing systems. + +//////////////////////////////////////////// + +struct proclock_t { + pid_t pid; + mstring path; + proclock_t(const mstring& p,int prot=0660); + ~proclock_t(); +}; + +#define PROCLOCK(p) proclock_t proclock(p) + +// The proclock class creates a file named path.lock +// and stores the curent process id in it. +// once the destructor is called in the same +// process, the file is removed. + +//////////////////////////////////////////// + +struct nodelock_t { + pid_t pid; + mstring path; + nodelock_t(const mstring& p,int prot=0660); + ~nodelock_t(); +}; + +#define NODELOCK(p) nodelock_t nodelock(p) + +// The nodelock class creates a file named path.lock +// and stores the curent network node name in it. +// once the destructor is called in the same +// process, the file is removed. + +//////////////////////////////////////////// + +void ProcTerminate(const mstring& path,int stime=2); + +#endif + 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include + +const time_t VALIDSEC=120; +static msvec cache; +static mutex_t mutex; + +int Lookup(IPnode& node,const in_addr& ia) +{ + MLOCK(mutex); + IPnode* p=cache.begin(); + time_t now=time(0); + while(pp->valid) cache.erase(p); + else if(memcmp(&p->addr,&ia,sizeof(ia))==0) {p->valid=now+VALIDSEC;node=*p;return 1;} + else p++; + } + hostent hent; + sref_t buf; + int herr; + hostent* hp=0; + gethostbyaddr_r((const char*)&ia,sizeof(ia),AF_INET, + &hent, + buf,sizeof(sref_t), + &hp, + &herr); + if(!hp) return 0; + memcpy(&node.addr,hp->h_addr,sizeof(hp->h_length)); + node.ip=inet_ntoa(node.addr); + node.name=hp->h_name; + node.valid=now+VALIDSEC; + cache.push_back(node); + return 1; +} + +int Lookup(IPnode& node,const sref& s) +{ + MLOCK(mutex); + IPnode* p=cache.begin(); + time_t now=time(0); + while(pp->valid) cache.erase(p); + else if(p->ip==s||p->name==s) { p->valid=now+VALIDSEC; node=*p; return 1; } + else p++; + } + hostent hent; + sref_t sbuf,buf; + int herr; + hostent* hp=0; + for(int i=0;s[i];i++) if(s[i]!='.'&&(s[i]<'0'||s[i]>'9')) { + gethostbyname_r(s.copyto(sbuf),&hent,buf,sizeof(sref_t),&hp,&herr); + break; + } + if(!hp) { + unsigned long a=inet_addr(s.copyto(buf)); + gethostbyaddr_r((char*)&a,sizeof(a),AF_INET,&hent,buf,sizeof(sref_t),&hp,&herr); + } + if(!hp) return 0; + memcpy(&node.addr,hp->h_addr,sizeof(hp->h_length)); + node.ip=inet_ntoa(node.addr); + node.name=hp->h_name; + node.valid=now+VALIDSEC; + cache.push_back(node); + return 1; +} 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef LOOKUPH +#define LOOKUPH + +#include +#include +#include + +struct IPnode { time_t valid; in_addr addr; mstring ip,name; }; + +int Lookup(IPnode& node,const sref& s); +int Lookup(IPnode& node,const in_addr& ia); + +#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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef MLOCKH +#define MLOCKH + +#if 1 +#include +typedef pthread_mutex_t mutex_t; +typedef pthread_cond_t mtcond_t; +const mutex_t MUTEX_INIT=PTHREAD_MUTEX_INITIALIZER; +const mtcond_t MTCOND_INIT=PTHREAD_COND_INITIALIZER; +struct mlock_t { + mutex_t* lock; + + mlock_t(mutex_t& m) { pthread_mutex_lock(lock=&m); } + ~mlock_t() { if(lock) pthread_mutex_unlock(lock); } +}; +#define MLOCK(m) mlock_t mlock(m) +#define MSUSPEND(m,c) { MLOCK(m); pthread_cond_wait(&c,&m); } +#define MCONTINUE(c) pthread_cond_signal(&c) +#else +typedef int mutex_t; +typedef int mtcond_t; +const mutex_t MUTEX_INIT=0; +const mtcond_t MTCOND_INIT=0; +#define MLOCK(m) +#define MSUSPEND(m,c) +#define MCONTINUE(c) +#endif + +#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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include + +const int MSEC=4000; +const int RETRY=3; +const int TIMEOUT=2; + +////////////////////////////////////////////////////////////////////////// + +mread::mread() : fd(-1),buf() +{ +} + +mread::mread(int f) : fd(f),buf() +{ +} + +////////////////////////////////////////////////////////////////////////// + +void mread::clear() +{ + buf.clear(); +} + +int mread::poll() +{ + pollfd pfd={fd,POLLIN,0}; + return ::poll(&pfd,1,MSEC); +} + +int mread::read(char* s,int n) +{ + if(buf.empty()) { + int m=::read(fd,s,n); + for(int i=0;i=0;i++) m=::read(fd,s,n); + if(m<0&&n) *s=0; + return m; + } + else { + if(n>buf.size()) n=buf.size(); + memcpy(s,buf.data(),n); + buf.erase(0,n); + return n; + } +} + +void mread::putback(const sref& s) +{ + if(s.nempty()) buf.insert(0,s); +} + +////////////////////////////////////////////////////////////////////////// + +int mread::readx(char* s,int n) +{ + int tries=0,acc=0; + while(acc=TIMEOUT) return acc; + } + else { + acc+=m; + tries=0; + } + } + return acc; +} + +////////////////////////////////////////////////////////////////////////// + +int mread::readln(char* s,int n) +{ + int tries=0,acc=0; + while(acc=TIMEOUT) return acc?-1:0; + } + else { + int p=sref(s+acc,m).find('\n')+1; + if(p>0) { acc+=p; putback(sref(s+acc,m-p)); return acc; } + else { acc+=m; tries=0; } + } + } + return acc; +} + +int mread::readpara(char* s,int n) +{ + int tries=0,acc=0; + while(acc=TIMEOUT) return acc?-1:0; + } + else { + int found=0; + sref first,rest(s+acc,m); + while(Splitln(first,rest)) if(first.empty()) { found=1; break; } + if(found) { acc=rest.begin()-s; putback(rest); return acc; } + else { acc+=m; tries=0; } + } + } + return acc; +} + 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef MREADH +#define MREADH + +// These functions work with nonblocking pipes +// as well as normal devices, and does not produce +// any signals on pipe errors + +#include +#include +#include + +class mread { +public: + mread(); + mread(int f); + + void setfd(int f) { clear(); fd=f; } + int getfd() const { return fd; } + + void setflag(int f) { fcntl(fd,F_SETFL,f); } + int getflag() const { return fcntl(fd,F_GETFL,0); } + + // Basic, pipe-safe, normally non-blocking, reads + void clear(); + int poll(); + int read(char* s,int n); + void putback(const sref& s); + + // Buffered reads + int readx(char* s,int n); // may timeout and return less than wanted + int readln(char* s,int n); + int readpara(char* s,int n); + +private: + int fd; + mstring buf; +}; + +// All functions return number of bytes written, or -1 on error. +// Note that although ln and para continues to read until +// it finds a newline or a paragraph, it may read more than that. +// Use clear() to restore reading state + +#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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +using namespace std; + +mset::mset() : rpile() {} +mset::mset(const sref& in) : rpile() { + sref first,rest=in; + while(Split(first,rest)) insert(first); +} + +///////////////////////////////////////////////////////////////////////////// + +int mset::exist(const sref& t) const { + pair p=equal_range(begin(),end(),t); + return p.first!=p.second; +} +int mset::insert(const sref& t) { + pair p=equal_range(begin(),end(),t); + if(p.first==p.second) { rpile::insert(p.second,t); return 1; } + else return 0; +} + +///////////////////////////////////////////////////////////////////////////// + +void mset::Union(const mset& a,const mset& b) { + clear(); + for(int i=0;i p=equal_range(begin(),end(),t); + return p.first!=p.second; +} +int msset::insert(const mstring& t) { + pair p=equal_range(begin(),end(),t); + if(p.first==p.second) { spile::insert(p.second,t); return 1; } + else return 0; +} + +///////////////////////////////////////////////////////////////////////////// + +mstream& operator<<(mstream& out,const msset& m) { + for(int i=0;i +#include +#include + +typedef mrvec rpile; + +struct mset : public rpile +{ + typedef rpile::iterator iterator; + typedef rpile::const_iterator const_iterator; + + mset(); + mset(const sref& in); + + int exist(const sref& t) const; + int insert(const sref& t); + + void Union(const mset& a,const mset& b); + void Intersection(const mset& a,const mset& b); + void Difference(const mset& a,const mset& b); +}; + +mstream& operator<<(mstream& out,const mset& m); + +////////////////////////////////////////////////////////// + +typedef msvec spile; + +struct msset : public spile +{ + typedef spile::iterator iterator; + typedef spile::const_iterator const_iterator; + + int exist(const mstring& t) const; + int insert(const mstring& t); +}; + +mstream& operator<<(mstream& out,const mset& m); + +#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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +using namespace std; + +const sref* rrmap::get(const sref& t) const +{ + pair p=equal_range(begin(),end(),rrstring(t)); + return p.first!=p.second?&p.first->second:0; +} + +const sref* rrmap::add(const sref& t,const sref& s) +{ + rrstring tmp(t,s); + pair p=equal_range(begin(),end(),tmp); + if(p.first!=p.second) return &(*p.first=tmp).second; + else return &insert(p.second,tmp)->second; +} + +void rrmap::sort() +{ + ::sort(begin(),end()); +} + +//////////////////////////////////////////////////////////////// + +int rimap::get(const sref& t) const +{ + pair p=equal_range(begin(),end(),rimap_t(t)); + return p.first!=p.second?p.first->at:-1; +} + +int rimap::add(const sref& t,int at) +{ + rimap_t tmp(t,at); + pair p=equal_range(begin(),end(),tmp); + if(p.first!=p.second) return (*p.first=tmp).at; + else return insert(p.second,tmp)->at; +} + +void rimap::sort() +{ + ::sort(begin(),end()); +} + +//////////////////////////////////////////////////////////////// + +const mstring* ssmap::get(const mstring& t) const +{ + pair p=equal_range(begin(),end(),sstring(t)); + return p.first!=p.second?&p.first->second:0; +} + +const mstring* ssmap::add(const mstring& t,const mstring& s) +{ + sstring tmp(t,s); + pair p=equal_range(begin(),end(),tmp); + if(p.first!=p.second) return &(*p.first=tmp).second; + else return &insert(p.second,tmp)->second; +} + +void ssmap::sort() +{ + ::sort(begin(),end()); +} + 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef MSMAPH +#define MSMAPH + +#include +#include + +struct rrstring { + sref first,second; + rrstring() : first(),second() {} + explicit rrstring(const sref& a) : first(a),second() {} + rrstring(const sref& a,const sref& b) : first(a),second(b) {} +}; +inline bool operator<(const rrstring& a,const rrstring& b) { return a.first rrpile; + +struct rrmap : public rrpile +{ + typedef rrpile::iterator iterator; + typedef rrpile::const_iterator const_iterator; + + const sref* get(const sref& t) const; + const sref* add(const sref& t,const sref& s); + void sort(); +}; + +////////////////////////////////////////////////////////////////// + +struct rimap_t { + sref name; + int at; + rimap_t() : name(),at(0) {} + explicit rimap_t(const sref& a) : name(a),at(0) {} + rimap_t(const sref& a,int p) : name(a),at(p) {} +}; +inline bool operator<(const rimap_t& a,const rimap_t& b) { return a.name +{ + typedef mrvec::iterator iterator; + typedef mrvec::const_iterator const_iterator; + + int get(const sref& t) const; + int add(const sref& t,int at); + void sort(); +}; + +////////////////////////////////////////////////////////////////// + +struct sstring { + mstring first,second; + sstring() : first(),second() {} + explicit sstring(const mstring& a) : first(a),second() {} + sstring(const mstring& a,const mstring& b) : first(a),second(b) {} +}; +inline bool operator<(const sstring& a,const sstring& b) { return a.first sspile; + +struct ssmap : public sspile +{ + typedef sspile::iterator iterator; + typedef sspile::const_iterator const_iterator; + + const mstring* get(const mstring& t) const; + const mstring* add(const mstring& t,const mstring& s); + void sort(); +}; + +#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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include + +const char cvt_form_f[]="%#.12f"; +const int MSEC=4000; + +sref ftoa(sref_t& buf,double f) +{ + char* e=buf+sprintf(buf,cvt_form_f,f)-1; + while(*e=='0') e--; if(*e=='.') e--; + return sref(buf,e-buf+1); +} + +/////////////////////////////////////////////////////////// + +int mstream::appc(char c) { return -1; } +int mstream::appi(int i) { return -1; } +int mstream::appf(double f) { return -1; } +int mstream::apps(const sref& s) { return -1; } + +/////////////////////////////////////////////////////////// + +int cvt_stream::appi(int i) { sref_t buf; return apps(itoa(buf,i)); } +int cvt_stream::appf(double f) { sref_t buf; return apps(ftoa(buf,f)); } + +/////////////////////////////////////////////////////////// + +int fp_stream::appc(char c) { return putc(c,fp)<0?-1:1; } +int fp_stream::apps(const sref& s) { return fwrite(s.data(),s.size(),1,fp); } + +/////////////////////////////////////////////////////////// + +int fd_stream::appc(char c) { return ::write(fd,&c,1); } +int fd_stream::apps(const sref& s) { return ::write(fd,s.data(),s.size()); } + +/////////////////////////////////////////////////////////// + +int pipe_stream::appc(char c) { return mwrite(&c,1); } +int pipe_stream::apps(const sref& s) { return mwrite(s.data(),s.size()); } + +int pipe_stream::mwrite(const char* s,int n) +{ + int old=n; + while(n>0&&!hup) { + pollfd pfd={fd,POLLOUT,0}; + if(::poll(&pfd,1,MSEC)<0) return hup=-1; + int m=::write(fd,s,n); + if(m<0) return hup=-1; + s+=m; n-=m; + } + return hup?-1:old; +} 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef MSTREAMH +#define MSTREAMH + +#include +#include +#include + +/////////////////////////////////////////////////////////// + +const char cvt_form_i[]="%d"; + +/////////////////////////////////////////////////////////// + +inline sref itoa(sref_t& buf,int i) { return sref(buf,sprintf(buf,cvt_form_i,i)); } +sref ftoa(sref_t& buf,double f); + +/////////////////////////////////////////////////////////// + +struct mstream { + virtual int appc(char c); + virtual int appi(int i); + virtual int appf(double f); + virtual int apps(const sref& s); + + mstream& put(char c) { return appc(c),*this; } + int write(const char* s,int n) { return apps(sref(s,n)); } +}; + +inline mstream& operator<<(mstream& out,int i) { return out.appi(i),out; } +inline mstream& operator<<(mstream& out,long l) { return out.appi(l),out; } +inline mstream& operator<<(mstream& out,unsigned u) { return out.appi(u),out; } +inline mstream& operator<<(mstream& out,unsigned long ul) { return out.appi(ul),out; } +inline mstream& operator<<(mstream& out,double f) { return out.appf(f),out; } + +inline mstream& operator<<(mstream& out,const sref& s) { return out.apps(s),out; } +inline mstream& operator<<(mstream& out,const char* s) { return out.apps(sref(s)),out; } + +/////////////////////////////////////////////////////////// + +struct cvt_stream : public mstream { + int appi(int i); + int appf(double f); +}; + +/////////////////////////////////////////////////////////// + +struct fp_stream : public cvt_stream { + FILE* fp; + + int appc(char c); + int apps(const sref& s); + + fp_stream(FILE* f) : fp(f) {} + + int flush() { return fflush(fp); } +}; + +/////////////////////////////////////////////////////////// + +struct fd_stream : public cvt_stream { + int fd; + + int appc(char c); + int apps(const sref& s); + + fd_stream(int f) : fd(f) {} +}; + +/////////////////////////////////////////////////////////// + +struct pipe_stream : public cvt_stream { + int fd,hup; + + int appc(char c); + int apps(const sref& s); + + pipe_stream(int f) : fd(f),hup(0) {} + + int mwrite(const char* s,int n); +}; + +/////////////////////////////////////////////////////////// + +#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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include + +uniheap mstring::heap; + +/////////////////////////////////////////////////////////////////// + +mstring::mstring() : sref(heap.push(),0),caps(ms_mincaps) { + map[dim]=0; +} +mstring::mstring(int n) : sref(heap.push(),0),caps(ms_mincaps) { + if(caps=dim-pos) map[dim=pos]=0; + else { memmove(map+pos,map+pos+n,dim-pos-n); map[dim-=n]=0; } + } +} + +void mstring::reserve(int n) { + if(caps<=n) { + if(caps==ms_mincaps) { + while(caps<=n) caps<<=1; + char* p=(char*)memcpy(malloc(caps),map,dim); + heap.pop(map); + map=p; + } + else { + while(caps<=n) caps<<=1; + map=(char*)realloc(map,caps); + } + } +} + +/////////////////////////////////////////////////////////////////// + +int mstring::load(const mstring& path) +{ + int fd=open(path.c_str(),O_RDONLY); + if(fd<0) return -1; + struct stat fs; fstat(fd,&fs); + resize(fs.st_size); + read(fd,map,dim); + close(fd); + return dim; +} + +/////////////////////////////////////////////////////////////////// + +mstring& mstring::convert(const char* format,...) +{ + sref_t buf; + va_list ap; + va_start(ap,format); + resize(vsprintf(buf,format,ap)); + memcpy(map,buf,dim); + va_end(ap); + return *this; +} + +/////////////////////////////////////////////////////////////////// + +int swrite::appc(char c) { return mp->put(c),1; } +int swrite::apps(const sref& s) { return mp->put(s),s.size(); } + +/////////////////////////////////////////////////////////////////// + +int mswrite::appc(char c) { return m.put(c),1; } +int mswrite::apps(const sref& s) { return m.put(s),s.size(); } + +/////////////////////////////////////////////////////////////////// + +int merror_t::appc(char c) { return desc.put(c),1; } +int merror_t::apps(const sref& s) { return desc.put(s),s.size(); } + +/////////////////////////////////////////////////////////////////// + +void getline(mstring& m,FILE* fp,char end) +{ + m.clear(); + int c=getc(fp); + while(c!=end&&c!=EOF) { m.append(1,c); c=getc(fp); } +} + + 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef MSTRINGH +#define MSTRINGH + +#include +#include + +const int ms_mincaps=32; + +class mstring : public sref { +public: + mstring(); + explicit mstring(int n); + mstring(int n,char c); + mstring(const char* s); + mstring(const char* s,int n); + mstring(const sref& s); + mstring(const mstring& s); + ~mstring(); + + //////////////////////////////////////////////////////////////// + + const char* c_str() const { return map; } + int capacity() const { return caps; } + + void clear() { map[dim=0]=0; } + + int own(const sref& s) const { int p=s.data()-map; return p>=0&&p=caps) reserve(dim+1); map[dim++]=c; map[dim]=0; } + void put(const sref& s) { + reserve(dim+s.size()); + memcpy(map+dim,s.data(),s.size()); + map[dim+=s.size()]=0; + } + + mstring& append(int sdim,char c) { + reserve(dim+sdim); + memset(map+dim,c,sdim); + map[dim+=sdim]=0; + return *this; + } + + mstring& append(const sref& s) { + reserve(dim+s.size()); + memmove(map+dim,s.data(),s.size()); + map[dim+=s.size()]=0; + return *this; + } + + int insert(int pos,int n) { + if(pos<0||pos>dim) return 0; + if(n) { reserve(dim+n); memmove(map+pos+n,map+pos,dim-pos); map[dim+=n]=0; } + return 1; + } + + mstring& insert(int pos,int sdim,char c) { + if(insert(pos,sdim)) memset(map+pos,c,sdim); + return *this; + } + mstring& insert(int pos,const sref& s) { + if(insert(pos,s.size())) memcpy(map+pos,s.data(),s.size()); + return *this; + } + + mstring& replace(int pos,int n,int sdim,char c) { + if(insert(pos+n,sdim-n)) memset(map+pos,c,sdim); + return *this; + } + mstring& replace(int pos,int n,const sref& s) { + if(insert(pos+n,s.size()-n)) memcpy(map+pos,s.data(),s.size()); + return *this; + } + + //////////////////////////////////////////////////////////////// + + void erase(int pos,int n=-1); + void reserve(int n); + void resize(int n) { reserve(n); map[dim=n]=0; } + + //////////////////////////////////////////////////////////////// + + mstring& operator=(const mstring& s) { assign(s); return *this; } + mstring& operator=(const sref& s) { assign(s); return *this; } + mstring& operator=(char c) { assign(1,c); return *this; } + + mstring& operator+=(const sref& s) { return append(s); } + mstring& operator+=(char c) { return append(1,c); } + + //////////////////////////////////////////////////////////////// + + int load(const mstring& path); + + //////////////////////////////////////////////////////////////// + + // NOTE: if you apply convert to %s or any unbound data, + // you're in trouble. Internal buffer is sref_t. + + mstring& convert(const char* format,...); + +protected: + static uniheap heap; +private: + int caps; +}; + +/////////////////////////////////////////////////////////////////// + +inline void swap(mstring& a,mstring& b) +{ + char buf[sizeof(mstring)]; + memcpy(buf,&a,sizeof(mstring)); + memcpy(&a,&b,sizeof(mstring)); + memcpy(&b,buf,sizeof(mstring)); +} + +/////////////////////////////////////////////////////////////////// + +inline mstring operator+(const sref& a,const sref& b) +{ + return mstring(a).append(b); +} +inline mstring operator+(const sref& a,char b) { + return mstring(a).append(1,b); +} +inline mstring operator+(char a,const sref& b) { + return mstring(1,a).append(b); +} + +/////////////////////////////////////////////////////////////////// + +inline mstring btoa(int b) { return mstring(1,b?'1':'0'); } +inline mstring itoa(int i) { sref_t buf; return mstring(itoa(buf,i)); } +inline mstring ftoa(double f) { sref_t buf; return mstring(ftoa(buf,f)); } + +/////////////////////////////////////////////////////////////////// + +const mstring ms_empty; + +/////////////////////////////////////////////////////////////////// + +struct swrite : public cvt_stream { + mstring* mp; + + int appc(char c); + int apps(const sref& s); + + swrite() : mp(0) {} + swrite(mstring& m) : mp(&m) { mp->clear(); } + + swrite& operator()(mstring& m) { (mp=&m)->clear(); return *this; } + swrite& hold(mstring& m) { mp=&m; return *this; } +}; + +/////////////////////////////////////////////////////////////////// + +class mswrite : public cvt_stream { +public: + mstring m; + + int appc(char c); + int apps(const sref& s); + + const mstring& str() const { return m; } // compatibility + void clear() { m.clear(); } + + mswrite() : m() {} +private: + mswrite(mstring&) {} // make no mistakes due to similarity with swrite +}; + +/////////////////////////////////////////////////////////////////// + +struct merror_t : public cvt_stream { + int num; + mstring desc; + + int appc(char c); + int apps(const sref& s); + + merror_t(int n) : num(n),desc() {} +}; + +#define THROW(x) { merror_t merr(0); merr< +#include +#include + +const int mv_mincaps=16; + +template class mrvec { +public: + typedef T* iterator; + typedef const T* const_iterator; + + mrvec(): + map((T*)malloc(mv_mincaps*sizeof(T))),dim(0),caps(mv_mincaps) {} + mrvec(int n): + map((T*)malloc(mv_mincaps*sizeof(T))),dim(0),caps(mv_mincaps) { resize(n); } + ~mrvec() { free(map); } + + int size() const { return dim; } + int capacity() const { return caps; } + + bool empty() const { return dim==0; } + bool nempty() const { return dim!=0; } + + T& at(int pos) { return map[pos]; } + const T& at(int pos) const { return map[pos]; } + + T& operator[](int pos) { return map[pos]; } + const T& operator[](int pos) const { return map[pos]; } + + iterator begin() { return map; } + const_iterator begin() const { return map; } + + iterator end() { return map+dim; } + const_iterator end() const { return map+dim; } + + T& front() { return map[0]; } + const T& front() const { return map[0]; } + + T& back() { return map[dim?dim-1:0]; } + const T& back() const { return map[dim?dim-1:0]; } + + //////////////////////////////////////////////////////////////// + + void clear() { dim=0; } + + iterator insert(iterator it,const T& s) { + int pos=it-map; ins(pos,1); return &(map[pos]=s); + } + void insert(iterator it,int n,const T& s) { + int pos=it-map; ins(pos,n); while(n--) map[pos++]=s; + } + void insert(iterator it,const_iterator p,const_iterator e) { + int pos=it-map; ins(pos,e-p); while(p class msvec : public mrvec { +public: + using mrvec::map; + using mrvec::dim; + typedef typename mrvec::iterator iterator; + typedef typename mrvec::const_iterator const_iterator; + + msvec() : mrvec() {} + msvec(int n) : mrvec(n) { for(int i=0;i::ins(pos,1); return new(map+pos) T(s); + } + void insert(iterator it,int n,const T& s) { + int pos=it-map; mrvec::ins(pos,n); while(n--) new(map+pos++) T(s); + } + void insert(iterator it,const_iterator p,const_iterator e) { + int pos=it-map; mrvec::ins(pos,e-p); while(p~T(); int pos=it-map; mrvec::ins(pos+1,-1); return map+pos; + } + + void push_back(const T& s) { reserve(dim+1); new(map+dim++) T(s); } + void pop_back(const T& s) { if(dim) map[--dim].~T(); } + + //////////////////////////////////////////////////////////////// + + void resize(int n) { + while(dim>n) map[--dim].~T(); + mrvec::reserve(n); + while(dim + +inline double QUniform(unsigned long& q) { + q=1664525L*q+1013904223L; + unsigned long long s=q;s<<=20;s|=(1023ULL<<52);return *(double*)&s-1; +} +inline int QRanBit(unsigned long& q) { + if(q&131072U) { q=((q^19U)<<1)|1U; return 1; } + else { q<<=1; return 0; } +} + +#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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include + +////////////////////////////////////////////////////// +// +// This file implements some routines from NumRec +// + +const int NTAB=32; // NOTE: change in header if changing this + +const int IA=16807; +const int IM=2147483647; +const float AM=1/float(IM); +const int IQ=127773; +const int IR=2836; +const int NDIV=1+(IM-1)/NTAB; +const float EPS=1.2e-7; +const float RNMX=1-EPS; + +static int idum,iy,iv[32],flag; +static float extra; +static int inited; +static mutex_t mutex; + +unsigned long RandomInit(unsigned long seed) +{ + inited=1; + idum=seed?seed:1; + for(int j=NTAB+7;j>=0;j--) { + int k=idum/IQ; + idum=IA*(idum-k*IQ)-IR*k; + if(idum<0) idum+=IM; + if(jRNMX) temp=RNMX; + return temp; +} + +float Exponential() +{ + return -log(Uniform()); +} + +float Gaussian() +{ + MLOCK(mutex); + float v1,v2,rsq; + if(flag) { + flag=0; + return extra; + } else { + do { + v1=2*Uniform()-1; + v2=2*Uniform()-1; + rsq=v1*v1+v2*v2; + } while(rsq>=1||rsq<=0); + float fac=sqrt(-2*log(rsq)/rsq); + flag=1; extra=v1*fac; + return v2*fac; + } +} 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef RANDOMH +#define RANDOMH + +#include + +/////////////////////////////////////////////////////////////////// +// +// Uniform distribution ]x0..x1[ +// +// Granularity approx 1.2e-7, ie more than 1e6 different values +// Perodicity approx 1e8 +// + +unsigned long RandomInit(unsigned long seed); + +float Uniform(); +float Exponential(); +float Gaussian(); + +#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 @@ +ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +c +c HTCd - Copyright (C) 1998-2006 Henrik Rydberg +c +c This program is free software; you can redistribute it and/or modify +c it under the terms of the GNU General Public License as published by +c the Free Software Foundation; either version 2 of the License, or +c (at your option) any later version. +c +c This program is distributed in the hope that it will be useful, +c but WITHOUT ANY WARRANTY; without even the implied warranty of +c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +c GNU General Public License for more details. +c +c You should have received a copy of the GNU General Public License +c along with this program; if not, write to the Free Software +c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +c + + integer function rfind_not_of(s,n,c) + byte s(0:1),c(0:1) + integer i,m,n + m=mod(n,16) + do 10 i=n-16,m,-16 + if(c(s(i+15)).eq.0)go to 115 + if(c(s(i+14)).eq.0)go to 114 + if(c(s(i+13)).eq.0)go to 113 + if(c(s(i+12)).eq.0)go to 112 + if(c(s(i+11)).eq.0)go to 111 + if(c(s(i+10)).eq.0)go to 110 + if(c(s(i+9)).eq.0)go to 109 + if(c(s(i+8)).eq.0)go to 108 + if(c(s(i+7)).eq.0)go to 107 + if(c(s(i+6)).eq.0)go to 106 + if(c(s(i+5)).eq.0)go to 105 + if(c(s(i+4)).eq.0)go to 104 + if(c(s(i+3)).eq.0)go to 103 + if(c(s(i+2)).eq.0)go to 102 + if(c(s(i+1)).eq.0)go to 101 + if(c(s(i)).eq.0)go to 100 + 10 continue + do 20 i=m-1,0,-1 + if(c(s(i)).eq.0)go to 100 + 20 continue + rfind_not_of=-1 + return + 100 rfind_not_of=i + return + 101 rfind_not_of=i+1 + return + 102 rfind_not_of=i+2 + return + 103 rfind_not_of=i+3 + return + 104 rfind_not_of=i+4 + return + 105 rfind_not_of=i+5 + return + 106 rfind_not_of=i+6 + return + 107 rfind_not_of=i+7 + return + 108 rfind_not_of=i+8 + return + 109 rfind_not_of=i+9 + return + 110 rfind_not_of=i+10 + return + 111 rfind_not_of=i+11 + return + 112 rfind_not_of=i+12 + return + 113 rfind_not_of=i+13 + return + 114 rfind_not_of=i+14 + return + 115 rfind_not_of=i+15 + return + end + 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 @@ +ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +c +c HTCd - Copyright (C) 1998-2006 Henrik Rydberg +c +c This program is free software; you can redistribute it and/or modify +c it under the terms of the GNU General Public License as published by +c the Free Software Foundation; either version 2 of the License, or +c (at your option) any later version. +c +c This program is distributed in the hope that it will be useful, +c but WITHOUT ANY WARRANTY; without even the implied warranty of +c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +c GNU General Public License for more details. +c +c You should have received a copy of the GNU General Public License +c along with this program; if not, write to the Free Software +c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +c + + integer function rfind_of(s,n,c) + byte s(0:1),c(0:1) + integer i,m,n + m=mod(n,16) + do 10 i=n-16,m,-16 + if(c(s(i+15)).ne.0)go to 115 + if(c(s(i+14)).ne.0)go to 114 + if(c(s(i+13)).ne.0)go to 113 + if(c(s(i+12)).ne.0)go to 112 + if(c(s(i+11)).ne.0)go to 111 + if(c(s(i+10)).ne.0)go to 110 + if(c(s(i+9)).ne.0)go to 109 + if(c(s(i+8)).ne.0)go to 108 + if(c(s(i+7)).ne.0)go to 107 + if(c(s(i+6)).ne.0)go to 106 + if(c(s(i+5)).ne.0)go to 105 + if(c(s(i+4)).ne.0)go to 104 + if(c(s(i+3)).ne.0)go to 103 + if(c(s(i+2)).ne.0)go to 102 + if(c(s(i+1)).ne.0)go to 101 + if(c(s(i)).ne.0)go to 100 + 10 continue + do 20 i=m-1,0,-1 + if(c(s(i)).ne.0)go to 100 + 20 continue + rfind_of=-1 + return + 100 rfind_of=i + return + 101 rfind_of=i+1 + return + 102 rfind_of=i+2 + return + 103 rfind_of=i+3 + return + 104 rfind_of=i+4 + return + 105 rfind_of=i+5 + return + 106 rfind_of=i+6 + return + 107 rfind_of=i+7 + return + 108 rfind_of=i+8 + return + 109 rfind_of=i+9 + return + 110 rfind_of=i+10 + return + 111 rfind_of=i+11 + return + 112 rfind_of=i+12 + return + 113 rfind_of=i+13 + return + 114 rfind_of=i+14 + return + 115 rfind_of=i+15 + return + end + 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 @@ +ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +c +c HTCd - Copyright (C) 1998-2006 Henrik Rydberg +c +c This program is free software; you can redistribute it and/or modify +c it under the terms of the GNU General Public License as published by +c the Free Software Foundation; either version 2 of the License, or +c (at your option) any later version. +c +c This program is distributed in the hope that it will be useful, +c but WITHOUT ANY WARRANTY; without even the implied warranty of +c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +c GNU General Public License for more details. +c +c You should have received a copy of the GNU General Public License +c along with this program; if not, write to the Free Software +c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +c + + integer function scomptab(s,c,n,tab) + byte s(0:1),c(0:1),tab(0:1) + integer i,m,n + m=mod(n,4) + do 10 i=0,m-1 + if(tab(s(i)).ne.tab(c(i)))go to 100 + 10 continue + do 20 i=m,n-1,4 + if(tab(s(i)).ne.tab(c(i)))go to 100 + if(tab(s(i+1)).ne.tab(c(i+1)))go to 101 + if(tab(s(i+2)).ne.tab(c(i+2)))go to 102 + if(tab(s(i+3)).ne.tab(c(i+3)))go to 103 + 20 continue + scomptab=0 + return + 100 scomptab=tab(s(i))-tab(c(i)) + return + 101 scomptab=tab(s(i+1))-tab(c(i+1)) + return + 102 scomptab=tab(s(i+2))-tab(c(i+2)) + return + 103 scomptab=tab(s(i+3))-tab(c(i+3)) + return + end + 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 @@ +ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +c +c HTCd - Copyright (C) 1998-2006 Henrik Rydberg +c +c This program is free software; you can redistribute it and/or modify +c it under the terms of the GNU General Public License as published by +c the Free Software Foundation; either version 2 of the License, or +c (at your option) any later version. +c +c This program is distributed in the hope that it will be useful, +c but WITHOUT ANY WARRANTY; without even the implied warranty of +c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +c GNU General Public License for more details. +c +c You should have received a copy of the GNU General Public License +c along with this program; if not, write to the Free Software +c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +c + + subroutine sconvert(s,sn,tab) + byte s(0:1),tab(0:1) + integer i,m,sn + m=mod(sn,4) + do 10 i=0,m-1 + s(i)=tab(s(i)) + 10 continue + do 20 i=m,sn-1,4 + s(i)=tab(s(i)) + s(i+1)=tab(s(i+1)) + s(i+2)=tab(s(i+2)) + s(i+3)=tab(s(i+3)) + 20 continue + return + end + 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 @@ +ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +c +c HTCd - Copyright (C) 1998-2006 Henrik Rydberg +c +c This program is free software; you can redistribute it and/or modify +c it under the terms of the GNU General Public License as published by +c the Free Software Foundation; either version 2 of the License, or +c (at your option) any later version. +c +c This program is distributed in the hope that it will be useful, +c but WITHOUT ANY WARRANTY; without even the implied warranty of +c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +c GNU General Public License for more details. +c +c You should have received a copy of the GNU General Public License +c along with this program; if not, write to the Free Software +c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +c + + integer function sfind(s,sn,c,cn) + character s(0:1),c(0:1) + integer i,j,m,sn,cn + m=mod(cn,4) + do 10 i=0,sn-1 + do 20 j=0,m-1 + if(s(i+j).ne.c(j))go to 50 + 20 continue + do 30 j=m,cn-1,4 + if(s(i+j).ne.c(j))go to 50 + if(s(i+j+1).ne.c(j+1))go to 50 + if(s(i+j+2).ne.c(j+2))go to 50 + if(s(i+j+3).ne.c(j+3))go to 50 + 30 continue + 50 if(j.eq.cn)go to 100 + 10 continue + sfind=-1 + return + 100 sfind=i + return + 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 @@ +ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +c +c HTCd - Copyright (C) 1998-2006 Henrik Rydberg +c +c This program is free software; you can redistribute it and/or modify +c it under the terms of the GNU General Public License as published by +c the Free Software Foundation; either version 2 of the License, or +c (at your option) any later version. +c +c This program is distributed in the hope that it will be useful, +c but WITHOUT ANY WARRANTY; without even the implied warranty of +c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +c GNU General Public License for more details. +c +c You should have received a copy of the GNU General Public License +c along with this program; if not, write to the Free Software +c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +c + + integer function sfindtab(s,sn,c,cn,tab) + byte s(0:1),c(0:1),tab(0:1) + integer i,j,m,sn,cn + m=mod(cn,4) + do 10 i=0,sn-1 + do 20 j=0,m-1 + if(tab(s(i+j)).ne.tab(c(j)))go to 50 + 20 continue + do 30 j=m,cn-1,4 + if(tab(s(i+j)).ne.tab(c(j)))go to 50 + if(tab(s(i+j+1)).ne.tab(c(j+1)))go to 50 + if(tab(s(i+j+2)).ne.tab(c(j+2)))go to 50 + if(tab(s(i+j+3)).ne.tab(c(j+3)))go to 50 + 30 continue + 50 if(j.eq.cn)go to 100 + 10 continue + sfindtab=-1 + return + 100 sfindtab=i + return + 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 @@ +ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +c +c HTCd - Copyright (C) 1998-2006 Henrik Rydberg +c +c This program is free software; you can redistribute it and/or modify +c it under the terms of the GNU General Public License as published by +c the Free Software Foundation; either version 2 of the License, or +c (at your option) any later version. +c +c This program is distributed in the hope that it will be useful, +c but WITHOUT ANY WARRANTY; without even the implied warranty of +c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +c GNU General Public License for more details. +c +c You should have received a copy of the GNU General Public License +c along with this program; if not, write to the Free Software +c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +c + + integer function skip_parentesis(s,n,left,right,esc) + character s(0:1),left,right,esc + integer i,n,cnt + if(n.eq.0)go to 40 + if(s(0).ne.left)go to 40 + cnt=1 + do 10 i=1,n-1 + if(s(i-1).eq.esc)go to 10 + if(s(i).eq.right)then + cnt=cnt-1 + if(cnt.eq.0)go to 30 + else if(s(i).eq.left)then + cnt=cnt+1 + end if + 10 continue + 20 skip_parentesis=-1 + return + 30 skip_parentesis=i+1 + return + 40 skip_parentesis=0 + return + end + 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef MSPLITH +#define MSPLITH + +#include + +inline sref Skip(const sref& a,const charset& ws=cset_ws) { + return a.right_first_not_of(ws); +} + +inline sref Trim(const sref& a,const charset& ws=cset_ws) { + return a.right_first_not_of(ws).leftand_last_not_of(ws); +} + +inline sref Trim(const sref& a,const bracket& enc,const charset& ws=cset_ws) { + sref s=a.right_first_not_of(ws).leftand_last_not_of(ws); + while(s.nempty()&&s.skip(enc)==s.size()) + s=s(1,-3).right_first_not_of(ws).leftand_last_not_of(ws); + return s; +} + +inline sref First(const sref& a,const charset& ws=cset_ws) { + return a.right_first_not_of(ws).left_first_of(ws); +} + +inline sref Rest(const sref& a,const charset& ws=cset_ws) { + return a.right_first_not_of(ws).right_first_of(ws).right_first_not_of(ws); +} + +inline sref Last(const sref& a,const charset& ws=cset_ws) { + sref p=a.leftand_last_not_of(ws); + sref e=p.past_last_of(ws); + return e.nempty()?e:p; +} + +inline int Split(sref& first,sref& rest,const charset& ws=cset_ws) { + rest=rest.right_first_not_of(ws); + int s=rest.find_of(ws); + first=rest.left(s); + rest=rest.right(s); + return first.nempty(); +} + +inline int Splitln(sref& first,sref& rest) { + int s=rest.find_of(cset_newl); + first=rest.left(s); + rest=rest.right(s).past_nl(); + return first.begin()!=rest.begin(); +} + +typedef int (*split_t)(sref& first,sref& rest); + +#endif + 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 @@ +ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +c +c HTCd - Copyright (C) 1998-2006 Henrik Rydberg +c +c This program is free software; you can redistribute it and/or modify +c it under the terms of the GNU General Public License as published by +c the Free Software Foundation; either version 2 of the License, or +c (at your option) any later version. +c +c This program is distributed in the hope that it will be useful, +c but WITHOUT ANY WARRANTY; without even the implied warranty of +c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +c GNU General Public License for more details. +c +c You should have received a copy of the GNU General Public License +c along with this program; if not, write to the Free Software +c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +c + + integer function srfind(s,sn,c,cn) + character s(0:1),c(0:1) + integer i,j,m,sn,cn + m=mod(cn,4) + do 10 i=sn-1,0,-1 + do 20 j=0,m-1 + if(s(i+j).ne.c(j))go to 50 + 20 continue + do 30 j=m,cn-1,4 + if(s(i+j).ne.c(j))go to 50 + if(s(i+j+1).ne.c(j+1))go to 50 + if(s(i+j+2).ne.c(j+2))go to 50 + if(s(i+j+3).ne.c(j+3))go to 50 + 30 continue + 50 if(j.eq.cn)go to 100 + 10 continue + srfind=-1 + return + 100 srfind=i + return + 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 @@ +ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +c +c HTCd - Copyright (C) 1998-2006 Henrik Rydberg +c +c This program is free software; you can redistribute it and/or modify +c it under the terms of the GNU General Public License as published by +c the Free Software Foundation; either version 2 of the License, or +c (at your option) any later version. +c +c This program is distributed in the hope that it will be useful, +c but WITHOUT ANY WARRANTY; without even the implied warranty of +c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +c GNU General Public License for more details. +c +c You should have received a copy of the GNU General Public License +c along with this program; if not, write to the Free Software +c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +c + + integer function srfindtab(s,sn,c,cn,tab) + byte s(0:1),c(0:1),tab(0:1) + integer i,j,m,sn,cn + m=mod(cn,4) + do 10 i=sn-1,0,-1 + do 20 j=0,m-1 + if(tab(s(i+j)).ne.tab(c(j)))go to 50 + 20 continue + do 30 j=m,cn-1,4 + if(tab(s(i+j)).ne.tab(c(j)))go to 50 + if(tab(s(i+j+1)).ne.tab(c(j+1)))go to 50 + if(tab(s(i+j+2)).ne.tab(c(j+2)))go to 50 + if(tab(s(i+j+3)).ne.tab(c(j+3)))go to 50 + 30 continue + 50 if(j.eq.cn)go to 100 + 10 continue + srfindtab=-1 + return + 100 srfindtab=i + return + 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef STACKQUEH +#define STACKQUEH + +#include +#include + +template class stackque { +public: + stackque(int m) { + put=get=n=0; + base=new T[caps=m]; + memset(&mutex,0,sizeof(mutex_t)); + } + ~stackque() { delete base; } + + int push(const T& a) throw(merror_t) { + MLOCK(mutex); + if(n>=caps) THROW("stackque: Full"); + base[put++]=a; + if(put==caps) put=0; + return ++n; + } + + int pop(T& a) { + MLOCK(mutex); + if(n) { + a=base[get++]; + if(get==caps) get=0; + return n--; + } + else return 0; + } + + int capacity() const { return caps; } + int size() const { return n; } + int empty() const { return n==0; } + int full() const { return n==caps; } + void clear() { put=get=n=0; } +private: + int put,get,n,caps; + T* base; + mutex_t mutex; +}; + +#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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include + +extern "C" { + int cfind_(const char* s,const int& sn,const char& c); + int crfind_(const char* s,const int& sn,const char& c); + int sfind_(const char* s,const int& sn,const char* c,const int& cn); + int srfind_(const char* s,const int& sn,const char* c,const int& cn); + int sfindtab_(const char* s,const int& sn,const char* c,const int& cn,const char* tab); + int srfindtab_(const char* s,const int& sn,const char* c,const int& cn,const char* tab); + int scomptab_(const char* s,const char* c,const int& n,const char* tab); + void sconvert_(char* s,const int& sn,const char* tab); + int find_of__(const char* s,const int& sn,const char* set); + int rfind_of__(const char* s,const int& sn,const char* set); + int find_not_of__(const char* s,const int& sn,const char* set); + int rfind_not_of__(const char* s,const int& sn,const char* set); + int skip_parentesis__(const char* s,const int& sn, + const char& left,const char& right,const char& esc); + int strip_(char* s,const char* c,const int& cn,const char& esc); +} + +//////////////////////////////////////////////////// + +char* sref::copyto(char* buf,int max) const { + if(!dim) buf[0]=0; + else if(dim=dim) return sref(map+dim,0); + else { + if(n<0) { n+=dim+1; if(n<0) n=0; } + if(n>=dim-pos) return sref(map+pos,dim-pos); + else return sref(map+pos,n); + } +} + +sref sref::left(int n) const { + if(n<0) { n+=dim+1; if(n<0) n=0; } + if(n>dim) return sref(map,dim); + else return sref(map,n); +} +sref sref::leftand(int n,int m) const { + if(n<0) { n+=dim+1; if(n<0) n=0; } + if((n+=m)>dim) return sref(map,dim); + else return sref(map,n); +} +sref sref::right(int n) const { + if(n<0) { n+=dim+1; if(n<0) n=0; } + if(n>dim) return sref(map+dim,0); + else return sref(map+n,dim-n); +} +sref sref::past(int n,int m) const { + if(n<0) { n+=dim+1; if(n<0) n=0; } + if((n+=m)>dim) return sref(map+dim,0); + else return sref(map+n,dim-n); +} + +//////////////////////////////////////////////////////////////// + +int sref::find(char c) const { return cfind_(map,dim,c); } +int sref::rfind(char c) const { return crfind_(map,dim,c); } +int sref::find(const sref& s) const { return sfind_(map,dim,s.map,s.dim); } +int sref::rfind(const sref& s) const { return srfind_(map,dim,s.map,s.dim); } +int sref::find(const sref& s,const charmap& tab) const { + return sfindtab_(map,dim,s.map,s.dim,tab.map); +} +int sref::rfind(const sref& s,const charmap& tab) const { + return srfindtab_(map,dim,s.map,s.dim,tab.map); +} + +int sref::find_of(const charset& s) const { return find_of__(map,dim,s.map); } +int sref::rfind_of(const charset& s) const { return rfind_of__(map,dim,s.map); } +int sref::find_not_of(const charset& s) const { return find_not_of__(map,dim,s.map); } +int sref::rfind_not_of(const charset& s) const { return rfind_not_of__(map,dim,s.map); } + +int sref::skip(const bracket& bra) const { + return skip_parentesis__(map,dim,bra.left,bra.right,bra.esc); +} + +//////////////////////////////////////////////////////////////// + +int sref::save(const sref& s,int prot) const { + sref_t path; s.copyto(path); + int fd=open(path,O_WRONLY|O_CREAT,prot); + if(fd<0) return -1; + write(fd,map,dim); + close(fd); + return dim; +} 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef SREFH +#define SREFH + +#include +#include + +typedef char sref_t[1024]; + +class sref { +public: + sref() : map((char*)&dim),dim(0) {} + explicit sref(char* p) : map(p),dim(strlen(p)) {} + explicit sref(const char* p) : map((char*)p),dim(strlen(p)) {} + sref(char* p,int n) : map(p),dim(n) {} + sref(const char* p,int n) : map((char*)p),dim(n) {} + + int size() const { return dim; } + bool empty() const { return dim==0; } + bool nempty() const { return dim!=0; } + + char* data() { return map; } + const char* data() const { return map; } + + char& operator[](int pos) { return map[pos]; } + const char& operator[](int pos) const { return map[pos]; } + + char* begin() { return map; } + const char* begin() const { return map; } + + char* end() { return map+dim; } + const char* end() const { return map+dim; } + + int operator*() const { return dim?*map:0; } + int front() const { return dim?*map:0; } + int back() const { return dim?map[dim-1]:0; } + + //////////////////////////////////////////////////////////////// + + sref popf() const { return dim?sref(map+1,dim-1):*this; } + sref popb() const { return dim?sref(map,dim-1):*this; } + + sref adv(int n) const { return n>0?(n=(const sref& a,const sref& b) { + return a.compare(b)>=0; +} +inline bool operator>(const sref& a,const sref& b) { + return a.compare(b)>0; +} + +////////////////////////////////////////////////////////////////////////// + +inline int operator-(const sref& a,const sref& b) { return a.data()-b.data(); } + +////////////////////////////////////////////////////////////////////////// + +inline int ltn(const sref& a,const sref& b) { + return a.compare(b,cset_lcase)<0; +} +inline int len(const sref& a,const sref& b) { + return a.compare(b,cset_lcase)<=0; +} +inline int eqn(const sref& a,const sref& b) { + return a.compare(b,cset_lcase)==0; +} +inline int nen(const sref& a,const sref& b) { + return a.compare(b,cset_lcase)!=0; +} +inline int gen(const sref& a,const sref& b) { + return a.compare(b,cset_lcase)>=0; +} +inline int gtn(const sref& a,const sref& b) { + return a.compare(b,cset_lcase)>0; +} + +////////////////////////////////////////////////////////////////////////// + +inline int atob(const sref& s) { sref_t buf; return atoi(s.copyto(buf))!=0; } +inline int atoi(const sref& s) { sref_t buf; return atoi(s.copyto(buf)); } +inline double atof(const sref& s) { sref_t buf; return atof(s.copyto(buf)); } + +#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 @@ +ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +c +c HTCd - Copyright (C) 1998-2006 Henrik Rydberg +c +c This program is free software; you can redistribute it and/or modify +c it under the terms of the GNU General Public License as published by +c the Free Software Foundation; either version 2 of the License, or +c (at your option) any later version. +c +c This program is distributed in the hope that it will be useful, +c but WITHOUT ANY WARRANTY; without even the implied warranty of +c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +c GNU General Public License for more details. +c +c You should have received a copy of the GNU General Public License +c along with this program; if not, write to the Free Software +c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +c + + integer function strip(s,c,cn,esc) + character s(0:1),c(0:1),esc + integer i,j,cn + j=0 + do 10 i=0,cn-1 + if(c(i).eq.esc)go to 10 + s(j)=c(i) + j=j+1 + 10 continue + strip=j + return + 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define GENERAL 0 +#define STREAM 1 +#define HEAPS 0 +#define CHARSET 0 +#define RANDOM 0 +#define LOOKUP 0 +#define ISSUE 1 +#define MSET 0 +#define CVTS 0 +#define VECTOR 0 +#define MSMAP 0 + +static fp_stream mout(stdout),merr(stderr); + +main(int argc,char* argv[]) +{ + mstring s; +#if GENERAL + s="asdfwerfindfindis?? asdf wert nnvnbn\n"; + + mout<<"["< stack; stack.init(); + for(int i=0;i<48;i++) { + //stack.pop(stack.push()); + stack.push(); + } + mout<<"--\n"; + mout< que(8); + for(int i=0;i<8;i++) que.push(i); + + try { + que.push(5); + } + catch(const merror_t& e) { + merr<"; + getline(ip,stdin); + IPnode node; + for(int i=0;i<4;i++) { + if(Lookup(node,ip)) { + merr< v(4); + for(int i=0;ifirst<<" "<second<<"\n"; + } + + const mstring* p=map.get("one"); + if(p) merr<<"got "<<*p<<"\n"; + +#endif + + return 0; +} 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef UNIHEAPH +#define UNIHEAPH + +#include +#include +#include + +// NOTE - must be in extern/static scope, or zeroed before use +// by a call to init. constructors will fail badly. +// A minimum of sizeof(T)==4 is required. +// Furthermore, the upper limit of heap space is 1Gb. + +template class uniheap { +public: + static const int maxchunks=24; + + void init() { + head=0; + chunk=0; + nchunks=0; + memset(&mutex,0,sizeof(mutex_t)); + } + + char* push() { MLOCK(mutex); char* p=news(); head=*(char**)p; return p; } + void pop(void* p) { MLOCK(mutex); *((char**)p)=head; head=(char*)p; } + int chunksize() const { return chunk; } +protected: + char* news() { + if(!head) { + if(!chunk) chunk=N<<4; + if(nchunks>=maxchunks) throw((int)0); + head=chunks[nchunks++]=(char*)malloc(chunk); + if(!head) throw((int)0); + for(int i=0;i