PostgreSQL Source Code  git master
regis.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  RegisNode
 
struct  Regis
 

Macros

#define RNHDRSZ   (offsetof(RegisNode,data))
 
#define RSF_ONEOF   1
 
#define RSF_NONEOF   2
 

Typedefs

typedef struct RegisNode RegisNode
 
typedef struct Regis Regis
 

Functions

bool RS_isRegis (const char *str)
 
void RS_compile (Regis *r, bool issuffix, const char *str)
 
void RS_free (Regis *r)
 
bool RS_execute (Regis *r, char *str)
 

Macro Definition Documentation

◆ RNHDRSZ

#define RNHDRSZ   (offsetof(RegisNode,data))

Definition at line 27 of file regis.h.

◆ RSF_NONEOF

#define RSF_NONEOF   2

Definition at line 30 of file regis.h.

◆ RSF_ONEOF

#define RSF_ONEOF   1

Definition at line 29 of file regis.h.

Typedef Documentation

◆ Regis

typedef struct Regis Regis

◆ RegisNode

typedef struct RegisNode RegisNode

Function Documentation

◆ RS_compile()

void RS_compile ( Regis r,
bool  issuffix,
const char *  str 
)

Definition at line 85 of file regis.c.

86 {
87  int len = strlen(str);
88  int state = RS_IN_WAIT;
89  const char *c = str;
90  RegisNode *ptr = NULL;
91 
92  memset(r, 0, sizeof(Regis));
93  r->issuffix = (issuffix) ? 1 : 0;
94 
95  while (*c)
96  {
97  if (state == RS_IN_WAIT)
98  {
99  if (t_isalpha(c))
100  {
101  if (ptr)
102  ptr = newRegisNode(ptr, len);
103  else
104  ptr = r->node = newRegisNode(NULL, len);
105  COPYCHAR(ptr->data, c);
106  ptr->type = RSF_ONEOF;
107  ptr->len = pg_mblen(c);
108  }
109  else if (t_iseq(c, '['))
110  {
111  if (ptr)
112  ptr = newRegisNode(ptr, len);
113  else
114  ptr = r->node = newRegisNode(NULL, len);
115  ptr->type = RSF_ONEOF;
116  state = RS_IN_ONEOF;
117  }
118  else /* shouldn't get here */
119  elog(ERROR, "invalid regis pattern: \"%s\"", str);
120  }
121  else if (state == RS_IN_ONEOF)
122  {
123  if (t_iseq(c, '^'))
124  {
125  ptr->type = RSF_NONEOF;
127  }
128  else if (t_isalpha(c))
129  {
130  COPYCHAR(ptr->data, c);
131  ptr->len = pg_mblen(c);
133  }
134  else /* shouldn't get here */
135  elog(ERROR, "invalid regis pattern: \"%s\"", str);
136  }
137  else if (state == RS_IN_ONEOF_IN || state == RS_IN_NONEOF)
138  {
139  if (t_isalpha(c))
140  {
141  COPYCHAR(ptr->data + ptr->len, c);
142  ptr->len += pg_mblen(c);
143  }
144  else if (t_iseq(c, ']'))
145  state = RS_IN_WAIT;
146  else /* shouldn't get here */
147  elog(ERROR, "invalid regis pattern: \"%s\"", str);
148  }
149  else
150  elog(ERROR, "internal error in RS_compile: state %d", state);
151  c += pg_mblen(c);
152  }
153 
154  if (state != RS_IN_WAIT) /* shouldn't get here */
155  elog(ERROR, "invalid regis pattern: \"%s\"", str);
156 
157  ptr = r->node;
158  while (ptr)
159  {
160  r->nchar++;
161  ptr = ptr->next;
162  }
163 }
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:224
const char * str
int pg_mblen(const char *mbstr)
Definition: mbutils.c:1023
const void size_t len
char * c
#define RS_IN_WAIT
Definition: regis.c:23
#define RS_IN_ONEOF_IN
Definition: regis.c:21
#define RS_IN_ONEOF
Definition: regis.c:20
#define RS_IN_NONEOF
Definition: regis.c:22
static RegisNode * newRegisNode(RegisNode *prev, int len)
Definition: regis.c:74
#define RSF_ONEOF
Definition: regis.h:29
#define RSF_NONEOF
Definition: regis.h:30
unsigned char data[FLEXIBLE_ARRAY_MEMBER]
Definition: regis.h:24
uint32 len
Definition: regis.h:21
struct RegisNode * next
Definition: regis.h:23
uint32 type
Definition: regis.h:20
Definition: regis.h:33
uint32 issuffix
Definition: regis.h:36
RegisNode * node
Definition: regis.h:34
uint32 nchar
Definition: regis.h:37
Definition: regguts.h:323
int t_isalpha(const char *ptr)
Definition: ts_locale.c:65
#define t_iseq(x, c)
Definition: ts_locale.h:38
#define COPYCHAR(d, s)
Definition: ts_locale.h:40

References COPYCHAR, RegisNode::data, elog, ERROR, Regis::issuffix, RegisNode::len, len, Regis::nchar, newRegisNode(), RegisNode::next, Regis::node, pg_mblen(), RS_IN_NONEOF, RS_IN_ONEOF, RS_IN_ONEOF_IN, RS_IN_WAIT, RSF_NONEOF, RSF_ONEOF, str, t_isalpha(), t_iseq, and RegisNode::type.

Referenced by NIAddAffix().

◆ RS_execute()

bool RS_execute ( Regis r,
char *  str 
)

Definition at line 213 of file regis.c.

214 {
215  RegisNode *ptr = r->node;
216  char *c = str;
217  int len = 0;
218 
219  while (*c)
220  {
221  len++;
222  c += pg_mblen(c);
223  }
224 
225  if (len < r->nchar)
226  return 0;
227 
228  c = str;
229  if (r->issuffix)
230  {
231  len -= r->nchar;
232  while (len-- > 0)
233  c += pg_mblen(c);
234  }
235 
236 
237  while (ptr)
238  {
239  switch (ptr->type)
240  {
241  case RSF_ONEOF:
242  if (!mb_strchr((char *) ptr->data, c))
243  return false;
244  break;
245  case RSF_NONEOF:
246  if (mb_strchr((char *) ptr->data, c))
247  return false;
248  break;
249  default:
250  elog(ERROR, "unrecognized regis node type: %d", ptr->type);
251  }
252  ptr = ptr->next;
253  c += pg_mblen(c);
254  }
255 
256  return true;
257 }
static bool mb_strchr(char *str, char *c)
Definition: regis.c:182

References RegisNode::data, elog, ERROR, Regis::issuffix, len, mb_strchr(), Regis::nchar, RegisNode::next, Regis::node, pg_mblen(), RSF_NONEOF, RSF_ONEOF, str, and RegisNode::type.

Referenced by CheckAffix().

◆ RS_free()

void RS_free ( Regis r)

Definition at line 166 of file regis.c.

167 {
168  RegisNode *ptr = r->node,
169  *tmp;
170 
171  while (ptr)
172  {
173  tmp = ptr->next;
174  pfree(ptr);
175  ptr = tmp;
176  }
177 
178  r->node = NULL;
179 }
void pfree(void *pointer)
Definition: mcxt.c:1520

References RegisNode::next, Regis::node, and pfree().

◆ RS_isRegis()

bool RS_isRegis ( const char *  str)

Definition at line 31 of file regis.c.

32 {
33  int state = RS_IN_WAIT;
34  const char *c = str;
35 
36  while (*c)
37  {
38  if (state == RS_IN_WAIT)
39  {
40  if (t_isalpha(c))
41  /* okay */ ;
42  else if (t_iseq(c, '['))
44  else
45  return false;
46  }
47  else if (state == RS_IN_ONEOF)
48  {
49  if (t_iseq(c, '^'))
51  else if (t_isalpha(c))
53  else
54  return false;
55  }
56  else if (state == RS_IN_ONEOF_IN || state == RS_IN_NONEOF)
57  {
58  if (t_isalpha(c))
59  /* okay */ ;
60  else if (t_iseq(c, ']'))
61  state = RS_IN_WAIT;
62  else
63  return false;
64  }
65  else
66  elog(ERROR, "internal error in RS_isRegis: state %d", state);
67  c += pg_mblen(c);
68  }
69 
70  return (state == RS_IN_WAIT);
71 }

References elog, ERROR, pg_mblen(), RS_IN_NONEOF, RS_IN_ONEOF, RS_IN_ONEOF_IN, RS_IN_WAIT, str, t_isalpha(), and t_iseq.

Referenced by NIAddAffix().