chiark / gitweb /
(dstr_vputf): Don't try calling @va_arg@ on things @char@-sized.
[mLib] / str.c
1 /* -*-c-*-
2  *
3  * $Id: str.c,v 1.3 1999/12/22 15:41:14 mdw Exp $
4  *
5  * Functions for hacking with strings
6  *
7  * (c) 1999 Straylight/Edgeware
8  */
9
10 /*----- Licensing notice --------------------------------------------------* 
11  *
12  * This file is part of the mLib utilities library.
13  *
14  * mLib is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU Library General Public License as
16  * published by the Free Software Foundation; either version 2 of the
17  * License, or (at your option) any later version.
18  * 
19  * mLib is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU Library General Public License for more details.
23  * 
24  * You should have received a copy of the GNU Library General Public
25  * License along with mLib; if not, write to the Free
26  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
27  * MA 02111-1307, USA.
28  */
29
30 /*----- Revision history --------------------------------------------------* 
31  *
32  * $Log: str.c,v $
33  * Revision 1.3  1999/12/22 15:41:14  mdw
34  * Skip past trailing whitespace in str_getword.
35  *
36  * Revision 1.2  1999/05/26 20:52:57  mdw
37  * Add new `rest' argument for `str_split'.
38  *
39  * Revision 1.1  1999/05/17 20:37:01  mdw
40  * Some trivial string hacks.
41  *
42  */
43
44 /*----- Header files ------------------------------------------------------*/
45
46 #include <ctype.h>
47 #include <stdio.h>
48 #include <stdlib.h>
49 #include <string.h>
50
51 #include "str.h"
52
53 /*----- Main code ---------------------------------------------------------*/
54
55 /* --- @str_getword@ --- *
56  *
57  * Arguments:   @char **pp@ = address of pointer into string
58  *
59  * Returns:     Pointer to the next space-separated word from the string,
60  *              or null.
61  *
62  * Use:         Parses off space-separated words from a string.
63  */
64
65 char *str_getword(char **pp)
66 {
67   char *p = *pp, *q;
68
69   if (!p)
70     return (0);
71
72   while (isspace((unsigned char)*p))
73     p++;
74
75   for (q = p; *q; q++) {
76     if (isspace((unsigned char)*q)) {
77       *q++ = 0;
78       while (*q && isspace((unsigned char)*q))
79         q++;
80       if (!*q)
81         q = 0;
82       *pp = q;
83       return (p);
84     }
85   }
86
87   *pp = 0;
88   return (p);
89 }
90
91 /* --- @str_split@ --- *
92  *
93  * Arguments:   @char *p@ = pointer to string
94  *              @char *v[]@ = pointer to array to fill in
95  *              @size_t c@ = count of strings to fill in
96  *              @char **rest@ = where to store the remainder of the string
97  *
98  * Returns:     Number of strings filled in.
99  *
100  * Use:         Fills an array with pointers to the individual words of a
101  *              string.  The string is modified in place to contain zero
102  *              bytes at the word boundaries, and the words have leading
103  *              and trailing space stripped off.  No more than @c@ words
104  *              are read; the actual number is returned as the value of the
105  *              function.  Unused slots in the array are populated with
106  *              null bytes.  If there's any string left, the address of the
107  *              remainder is stored in @rest@ (if it's non-null); otherwise
108  *              @rest@ is set to a null pointer.
109  */
110
111 size_t str_split(char *p, char *v[], size_t c, char **rest)
112 {
113   size_t n = 0;
114   char *q;
115
116   while (c && (q = str_getword(&p)) != 0) {
117     *v++ = q;
118     c--;
119     n++;
120   }
121   while (c) {
122     *v++ = 0;
123     c--;
124   }
125   if (rest)
126     *rest = p;
127   return (n);
128 }
129
130 /* --- @str_sanitize@ --- *
131  *
132  * Arguments:   @char *d@ = destination buffer
133  *              @const char *p@ = pointer to source string
134  *              @size_t sz@ = size of destination buffer
135  *
136  * Returns:     ---
137  *
138  * Use:         Writes a string into a buffer, being careful not to overflow
139  *              the buffer, to null terminate the result, and to prevent
140  *              nasty nonprintable characters ending up in the buffer.
141  */
142
143 void str_sanitize(char *d, const char *p, size_t sz)
144 {
145   if (!sz)
146     return;
147   sz--;
148   while (*p && sz) {
149     int ch = *p++;
150     if (!isgraph((unsigned char)ch))
151       ch = '_';
152     *d++ = ch;
153     sz--;
154   }
155   *d++ = 0;
156 }
157
158 /*----- That's all, folks -------------------------------------------------*/