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