Postfix3.3.1
split_nameval.c
[詳解]
1 /*++
2 /* NAME
3 /* split_nameval 3
4 /* SUMMARY
5 /* name-value splitter
6 /* SYNOPSIS
7 /* #include <split_nameval.h>
8 /*
9 /* const char *split_nameval(buf, name, value)
10 /* char *buf;
11 /* char **name;
12 /* char **value;
13 /* DESCRIPTION
14 /* split_nameval() takes a logical line from readlline() and expects
15 /* text of the form "name = value" or "name =". The buffer
16 /* argument is broken up into name and value substrings.
17 /*
18 /* Arguments:
19 /* .IP buf
20 /* Result from readlline() or equivalent. The buffer is modified.
21 /* .IP name
22 /* Upon successful completion, this is set to the name
23 /* substring.
24 /* .IP value
25 /* Upon successful completion, this is set to the value
26 /* substring.
27 /* FEATURES
28 /* SEE ALSO
29 /* dict(3) mid-level dictionary routines
30 /* BUGS
31 /* DIAGNOSTICS
32 /* Fatal errors: out of memory.
33 /*
34 /* The result is a null pointer in case of success, a string
35 /* describing the error otherwise: missing '=' after attribute
36 /* name; missing attribute name.
37 /* LICENSE
38 /* .ad
39 /* .fi
40 /* The Secure Mailer license must be distributed with this software.
41 /* AUTHOR(S)
42 /* Wietse Venema
43 /* IBM T.J. Watson Research
44 /* P.O. Box 704
45 /* Yorktown Heights, NY 10598, USA
46 /*--*/
47 
48 /* System libraries. */
49 
50 #include "sys_defs.h"
51 #include <ctype.h>
52 #include <string.h>
53 
54 /* Utility library. */
55 
56 #include <msg.h>
57 #include <stringops.h>
58 
59 /* split_nameval - split text into name and value */
60 
61 const char *split_nameval(char *buf, char **name, char **value)
62 {
63  char *np; /* name substring */
64  char *vp; /* value substring */
65  char *cp;
66  char *ep;
67 
68  /*
69  * Ugly macros to make complex expressions less unreadable.
70  */
71 #define SKIP(start, var, cond) do { \
72  for (var = start; *var && (cond); var++) \
73  /* void */; \
74  } while (0)
75 
76 #define TRIM(s) do { \
77  char *p; \
78  for (p = (s) + strlen(s); p > (s) && ISSPACE(p[-1]); p--) \
79  /* void */; \
80  *p = 0; \
81  } while (0)
82 
83  SKIP(buf, np, ISSPACE(*np)); /* find name begin */
84  if (*np == 0)
85  return ("missing attribute name");
86  SKIP(np, ep, !ISSPACE(*ep) && *ep != '='); /* find name end */
87  SKIP(ep, cp, ISSPACE(*cp)); /* skip blanks before '=' */
88  if (*cp != '=') /* need '=' */
89  return ("missing '=' after attribute name");
90  *ep = 0; /* terminate name */
91  cp++; /* skip over '=' */
92  SKIP(cp, vp, ISSPACE(*vp)); /* skip leading blanks */
93  TRIM(vp); /* trim trailing blanks */
94  *name = np;
95  *value = vp;
96  return (0);
97 }
#define TRIM(s)
const char * split_nameval(char *buf, char **name, char **value)
Definition: split_nameval.c:61
#define ISSPACE(c)
Definition: sys_defs.h:1753
#define SKIP(start, var, cond)