xref: /netbsd-src/external/ibm-public/postfix/dist/src/util/extpar.c (revision 67b9b338a7386232ac596b5fd0cd5a9cc8a03c71)
1*67b9b338Schristos /*	$NetBSD: extpar.c,v 1.4 2022/10/08 16:12:50 christos Exp $	*/
2e262b48eSchristos 
3e262b48eSchristos /*++
4e262b48eSchristos /* NAME
5e262b48eSchristos /*	extpar 3
6e262b48eSchristos /* SUMMARY
7e262b48eSchristos /*	extract text from parentheses
8e262b48eSchristos /* SYNOPSIS
9e262b48eSchristos /*	#include <stringops.h>
10e262b48eSchristos /*
11e262b48eSchristos /*	char	*extpar(bp, parens, flags)
12e262b48eSchristos /*	char	**bp;
13e262b48eSchristos /*	const char *parens;
14e262b48eSchristos /*	int	flags;
15e262b48eSchristos /* DESCRIPTION
16e262b48eSchristos /*	extpar() extracts text from an input string that is enclosed
17e262b48eSchristos /*	in the specified parentheses, and updates the buffer pointer
18e262b48eSchristos /*	to point to that text.
19e262b48eSchristos /*
20e262b48eSchristos /*	Arguments:
21e262b48eSchristos /* .IP bp
22e262b48eSchristos /*	Pointer to buffer pointer. Both the buffer and the buffer
23e262b48eSchristos /*	pointer are modified.
24e262b48eSchristos /* .IP parens
25e262b48eSchristos /*	One matching pair of parentheses, opening parenthesis first.
26e262b48eSchristos /* .IP flags
27e262b48eSchristos /*	EXTPAR_FLAG_NONE, or the bitwise OR of one or more flags:
28e262b48eSchristos /* .RS
29e262b48eSchristos /* .IP EXTPAR_FLAG_EXTRACT
30*67b9b338Schristos /*	This flag is intended to instruct extpar() callers that
31*67b9b338Schristos /*	extpar() should be invoked. It has no effect on expar()
32e262b48eSchristos /*	itself.
33e262b48eSchristos /* .IP EXTPAR_FLAG_STRIP
34e262b48eSchristos /*	Skip whitespace after the opening parenthesis, and trim
35e262b48eSchristos /*	whitespace before the closing parenthesis.
36e262b48eSchristos /* .RE
37e262b48eSchristos /* DIAGNOSTICS
38e262b48eSchristos /*	In case of error the result value is a dynamically-allocated
39e262b48eSchristos /*	string with a description of the problem that includes a
40e262b48eSchristos /*	copy of the offending input.  A non-null result value should
4133881f77Schristos /*	be destroyed with myfree(). The following describes the errors
42e262b48eSchristos /*	and the state of the buffer and buffer pointer.
43*67b9b338Schristos /* .IP "no opening parenthesis at start of text"
44*67b9b338Schristos /*	The buffer pointer points to the input text.
45e262b48eSchristos /* .IP "missing closing parenthesis"
46e262b48eSchristos /*	The buffer pointer points to text as if a closing parenthesis
47e262b48eSchristos /*	were present at the end of the input.
48e262b48eSchristos /* .IP "text after closing parenthesis"
49e262b48eSchristos /*	The buffer pointer points to text as if the offending text
50e262b48eSchristos /*	were not present.
51e262b48eSchristos /* SEE ALSO
52e262b48eSchristos /*	balpar(3) determine length of string in parentheses
53e262b48eSchristos /* LICENSE
54e262b48eSchristos /* .ad
55e262b48eSchristos /* .fi
56e262b48eSchristos /*	The Secure Mailer license must be distributed with this software.
57e262b48eSchristos /* AUTHOR(S)
58e262b48eSchristos /*	Wietse Venema
59e262b48eSchristos /*	IBM T.J. Watson Research
60e262b48eSchristos /*	P.O. Box 704
61e262b48eSchristos /*	Yorktown Heights, NY 10598, USA
62*67b9b338Schristos /*
63*67b9b338Schristos /*	Wietse Venema
64*67b9b338Schristos /*	Google, Inc.
65*67b9b338Schristos /*	111 8th Avenue
66*67b9b338Schristos /*	New York, NY 10011, USA
67e262b48eSchristos /*--*/
68e262b48eSchristos 
69e262b48eSchristos  /*
70e262b48eSchristos   * System library.
71e262b48eSchristos   */
72e262b48eSchristos #include <sys_defs.h>
73e262b48eSchristos #include <ctype.h>
74e262b48eSchristos 
75e262b48eSchristos  /*
76e262b48eSchristos   * Utility library.
77e262b48eSchristos   */
78*67b9b338Schristos #include <vstring.h>
79e262b48eSchristos #include <stringops.h>
80e262b48eSchristos 
81e262b48eSchristos /* extpar - extract text from parentheses */
82e262b48eSchristos 
extpar(char ** bp,const char * parens,int flags)83e262b48eSchristos char   *extpar(char **bp, const char *parens, int flags)
84e262b48eSchristos {
85e262b48eSchristos     char   *cp = *bp;
86e262b48eSchristos     char   *err = 0;
87e262b48eSchristos     size_t  len;
88e262b48eSchristos 
89*67b9b338Schristos     if (cp[0] != parens[0]) {
90*67b9b338Schristos 	err = vstring_export(vstring_sprintf(vstring_alloc(100),
91*67b9b338Schristos 		      "no '%c' at start of text in \"%s\"", parens[0], cp));
92*67b9b338Schristos 	len = 0;
93*67b9b338Schristos     } else if ((len = balpar(cp, parens)) == 0) {
94e262b48eSchristos 	err = concatenate("missing '", parens + 1, "' in \"",
95e262b48eSchristos 			  cp, "\"", (char *) 0);
96e262b48eSchristos 	cp += 1;
97e262b48eSchristos     } else {
98e262b48eSchristos 	if (cp[len] != 0)
99e262b48eSchristos 	    err = concatenate("syntax error after '", parens + 1, "' in \"",
100e262b48eSchristos 			      cp, "\"", (char *) 0);
101e262b48eSchristos 	cp += 1;
102e262b48eSchristos 	cp[len -= 2] = 0;
103e262b48eSchristos     }
104e262b48eSchristos     if (flags & EXTPAR_FLAG_STRIP) {
105e262b48eSchristos 	trimblanks(cp, len)[0] = 0;
106e262b48eSchristos 	while (ISSPACE(*cp))
107e262b48eSchristos 	    cp++;
108e262b48eSchristos     }
109e262b48eSchristos     *bp = cp;
110e262b48eSchristos     return (err);
111e262b48eSchristos }
112