summaryrefslogtreecommitdiff
path: root/src/mt/charset.h
blob: 84742b9a5a394a0a0a1b2ca42fd33918d83824f7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/*************************************************************************
 *
 * 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 <string.h>

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<<cset_leqv1<<cset_leqv2;

const bracket cset_quotes("\"\"\\");
const bracket cset_indices("[]\\");
const bracket cset_braces("{}\\");
const bracket cset_para("()\\");
const bracket cset_dollars("$$\\");
const bracket cset_hooks("<>\\");

#endif