lib: Remove parser code, now replaced with tini parser.
[sfrench/samba-autobuild/.git] / lib / util / util_str_common.c
1 /*
2    Unix SMB/CIFS implementation.
3    Samba utility functions
4
5    Copyright (C) Andrew Tridgell 1992-2001
6    Copyright (C) Simo Sorce      2001-2002
7    Copyright (C) Martin Pool     2003
8    Copyright (C) James Peach     2005
9
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 3 of the License, or
13    (at your option) any later version.
14
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program.  If not, see <http://www.gnu.org/licenses/>.
22 */
23
24 #include "includes.h"
25
26 /**
27 Do a case-insensitive, whitespace-ignoring ASCII string compare.
28 **/
29 _PUBLIC_ int strwicmp(const char *psz1, const char *psz2)
30 {
31         /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
32         /* appropriate value. */
33         if (psz1 == psz2)
34                 return (0);
35         else if (psz1 == NULL)
36                 return (-1);
37         else if (psz2 == NULL)
38                 return (1);
39
40         /* sync the strings on first non-whitespace */
41         while (1) {
42                 while (isspace((int)*psz1))
43                         psz1++;
44                 while (isspace((int)*psz2))
45                         psz2++;
46
47                 /*
48                  * This does not do a genuine multi-byte comparison,
49                  * instead it just uses the fast-path for ASCII in
50                  * these common routines
51                  */
52                 if (toupper_m((unsigned char)*psz1) != toupper_m((unsigned char)*psz2)
53                     || *psz1 == '\0'
54                     || *psz2 == '\0')
55                         break;
56                 psz1++;
57                 psz2++;
58         }
59         return (*psz1 - *psz2);
60 }
61
62 _PUBLIC_ size_t ucs2_align(const void *base_ptr, const void *p, int flags)
63 {
64         if (flags & (STR_NOALIGN|STR_ASCII))
65                 return 0;
66         return PTR_DIFF(p, base_ptr) & 1;
67 }
68
69 /**
70  String replace.
71  NOTE: oldc and newc must be 7 bit characters
72 **/
73 void string_replace( char *s, char oldc, char newc )
74 {
75         char *p;
76
77         /* this is quite a common operation, so we want it to be
78            fast. We optimise for the ascii case, knowing that all our
79            supported multi-byte character sets are ascii-compatible
80            (ie. they match for the first 128 chars) */
81
82         for (p = s; *p; p++) {
83                 if (*p & 0x80) /* mb string - slow path. */
84                         break;
85                 if (*p == oldc) {
86                         *p = newc;
87                 }
88         }
89
90         if (!*p)
91                 return;
92
93         /* Slow (mb) path. */
94 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
95         /* With compose characters we must restart from the beginning. JRA. */
96         p = s;
97 #endif
98
99         while (*p) {
100                 size_t c_size;
101                 next_codepoint(p, &c_size);
102
103                 if (c_size == 1) {
104                         if (*p == oldc) {
105                                 *p = newc;
106                         }
107                 }
108                 p += c_size;
109         }
110 }
111
112
113 /**
114  Paranoid strcpy into a buffer of given length (includes terminating
115  zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
116  and replaces with '_'. Deliberately does *NOT* check for multibyte
117  characters. Treats src as an array of bytes, not as a multibyte
118  string. Any byte >0x7f is automatically converted to '_'.
119  other_safe_chars must also contain an ascii string (bytes<0x7f).
120 **/
121
122 char *alpha_strcpy(char *dest,
123                    const char *src,
124                    const char *other_safe_chars,
125                    size_t maxlength)
126 {
127         size_t len, i;
128
129         if (!dest) {
130                 smb_panic("ERROR: NULL dest in alpha_strcpy");
131         }
132
133         if (!src) {
134                 *dest = 0;
135                 return dest;
136         }
137
138         len = strlen(src);
139         if (len >= maxlength)
140                 len = maxlength - 1;
141
142         if (!other_safe_chars)
143                 other_safe_chars = "";
144
145         for(i = 0; i < len; i++) {
146                 int val = (src[i] & 0xff);
147                 if (val > 0x7f) {
148                         dest[i] = '_';
149                         continue;
150                 }
151                 if (isupper(val) || islower(val) ||
152                                 isdigit(val) || strchr(other_safe_chars, val))
153                         dest[i] = src[i];
154                 else
155                         dest[i] = '_';
156         }
157
158         dest[i] = '\0';
159
160         return dest;
161 }