Postfix3.3.1
mystrtok.c
[詳解]
1 /*++
2 /* NAME
3 /* mystrtok 3
4 /* SUMMARY
5 /* safe tokenizer
6 /* SYNOPSIS
7 /* #include <stringops.h>
8 /*
9 /* char *mystrtok(bufp, delimiters)
10 /* char **bufp;
11 /* const char *delimiters;
12 /*
13 /* char *mystrtokq(bufp, delimiters, parens)
14 /* char **bufp;
15 /* const char *delimiters;
16 /* const char *parens;
17 /* DESCRIPTION
18 /* mystrtok() splits a buffer on the specified \fIdelimiters\fR.
19 /* Tokens are delimited by runs of delimiters, so this routine
20 /* cannot return zero-length tokens.
21 /*
22 /* mystrtokq() is like mystrtok() but will not split text
23 /* between balanced parentheses. \fIparens\fR specifies the
24 /* opening and closing parenthesis (one of each). The set of
25 /* \fIparens\fR must be distinct from the set of \fIdelimiters\fR.
26 /*
27 /* The \fIbufp\fR argument specifies the start of the search; it
28 /* is updated with each call. The input is destroyed.
29 /*
30 /* The result value is the next token, or a null pointer when the
31 /* end of the buffer was reached.
32 /* LICENSE
33 /* .ad
34 /* .fi
35 /* The Secure Mailer license must be distributed with this software.
36 /* AUTHOR(S)
37 /* Wietse Venema
38 /* IBM T.J. Watson Research
39 /* P.O. Box 704
40 /* Yorktown Heights, NY 10598, USA
41 /*--*/
42 
43 /* System library. */
44 
45 #include "sys_defs.h"
46 #include <string.h>
47 
48 /* Utility library. */
49 
50 #include "stringops.h"
51 
52 /* mystrtok - safe tokenizer */
53 
54 char *mystrtok(char **src, const char *sep)
55 {
56  char *start = *src;
57  char *end;
58 
59  /*
60  * Skip over leading delimiters.
61  */
62  start += strspn(start, sep);
63  if (*start == 0) {
64  *src = start;
65  return (0);
66  }
67 
68  /*
69  * Separate off one token.
70  */
71  end = start + strcspn(start, sep);
72  if (*end != 0)
73  *end++ = 0;
74  *src = end;
75  return (start);
76 }
77 
78 /* mystrtokq - safe tokenizer with quoting support */
79 
80 char *mystrtokq(char **src, const char *sep, const char *parens)
81 {
82  char *start = *src;
83  static char *cp;
84  int ch;
85  int level;
86 
87  /*
88  * Skip over leading delimiters.
89  */
90  start += strspn(start, sep);
91  if (*start == 0) {
92  *src = start;
93  return (0);
94  }
95 
96  /*
97  * Parse out the next token.
98  */
99  for (level = 0, cp = start; (ch = *(unsigned char *) cp) != 0; cp++) {
100  if (ch == parens[0]) {
101  level++;
102  } else if (level > 0 && ch == parens[1]) {
103  level--;
104  } else if (level == 0 && strchr(sep, ch) != 0) {
105  *cp++ = 0;
106  break;
107  }
108  }
109  *src = cp;
110  return (start);
111 }
112 
113 #ifdef TEST
114 
115  /*
116  * Test program: read lines from stdin, split on whitespace.
117  */
118 #include "vstring.h"
119 #include "vstream.h"
120 #include "vstring_vstream.h"
121 
122 int main(void)
123 {
124  VSTRING *vp = vstring_alloc(100);
125  char *start;
126  char *str;
127 
128  while (vstring_fgets(vp, VSTREAM_IN) && VSTRING_LEN(vp) > 0) {
129  start = vstring_str(vp);
130  if (strchr(start, CHARS_BRACE[0]) == 0) {
131  while ((str = mystrtok(&start, CHARS_SPACE)) != 0)
132  vstream_printf(">%s<\n", str);
133  } else {
134  while ((str = mystrtokq(&start, CHARS_SPACE, CHARS_BRACE)) != 0)
135  vstream_printf(">%s<\n", str);
136  }
138  }
139  vstring_free(vp);
140  return (0);
141 }
142 
143 #endif
#define vstring_fgets(s, p)
#define CHARS_BRACE
Definition: sys_defs.h:1763
#define vstring_str(vp)
Definition: vstring.h:71
#define VSTREAM_OUT
Definition: vstream.h:67
int main(int argc, char **argv)
Definition: anvil.c:1010
char * mystrtokq(char **src, const char *sep, const char *parens)
Definition: mystrtok.c:80
#define VSTREAM_IN
Definition: vstream.h:66
char * mystrtok(char **src, const char *sep)
Definition: mystrtok.c:54
#define VSTRING_LEN(vp)
Definition: vstring.h:72
VSTREAM * vstream_printf(const char *fmt,...)
Definition: vstream.c:1335
VSTRING * vstring_alloc(ssize_t len)
Definition: vstring.c:353
#define CHARS_SPACE
Definition: sys_defs.h:1762
int vstream_fflush(VSTREAM *stream)
Definition: vstream.c:1257
VSTRING * vstring_free(VSTRING *vp)
Definition: vstring.c:380