Code indentation.
[midnight-commander.git] / src / vfs / smbfs / helpers / lib / util_str.c
blobfad4225c956b6bb7bb48cd8039a859eef09ec094
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
4 Samba utility functions
6 Copyright (C) Andrew Tridgell 1992-1998
8 Copyright (C) 2011
9 The Free Software Foundation, Inc.
11 This file is part of the Midnight Commander.
13 The Midnight Commander is free software: you can redistribute it
14 and/or modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation, either version 3 of the License,
16 or (at your option) any later version.
18 The Midnight Commander is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with this program. If not, see <http://www.gnu.org/licenses/>.
27 #include "includes.h"
29 extern int DEBUGLEVEL;
31 static char *last_ptr = NULL;
33 void
34 set_first_token (char *ptr)
36 last_ptr = ptr;
39 /****************************************************************************
40 Get the next token from a string, return False if none found
41 handles double-quotes.
42 Based on a routine by GJC@VILLAGE.COM.
43 Extensively modified by Andrew.Tridgell@anu.edu.au
44 ****************************************************************************/
45 BOOL
46 next_token (char **ptr, char *buff, const char *sep, size_t bufsize)
48 char *s;
49 BOOL quoted;
50 size_t len = 1;
52 if (!ptr)
53 ptr = &last_ptr;
54 if (!ptr)
55 return (False);
57 s = *ptr;
59 /* default to simple separators */
60 if (!sep)
61 sep = " \t\n\r";
63 /* find the first non sep char */
64 while (*s && strchr (sep, *s))
65 s++;
67 /* nothing left? */
68 if (!*s)
69 return (False);
71 /* copy over the token */
72 for (quoted = False; len < bufsize && *s && (quoted || !strchr (sep, *s)); s++)
74 if (*s == '\"')
76 quoted = !quoted;
78 else
80 len++;
81 *buff++ = *s;
85 *ptr = (*s) ? s + 1 : s;
86 *buff = 0;
87 last_ptr = *ptr;
89 return (True);
92 #if 0
93 /****************************************************************************
94 Convert list of tokens to array; dependent on above routine.
95 Uses last_ptr from above - bit of a hack.
96 ****************************************************************************/
97 char **
98 toktocliplist (int *ctok, char *sep)
100 char *s = last_ptr;
101 int ictok = 0;
102 char **ret, **iret;
104 if (!sep)
105 sep = " \t\n\r";
107 while (*s && strchr (sep, *s))
108 s++;
110 /* nothing left? */
111 if (!*s)
112 return (NULL);
116 ictok++;
117 while (*s && (!strchr (sep, *s)))
118 s++;
119 while (*s && strchr (sep, *s))
120 *s++ = 0;
122 while (*s);
124 *ctok = ictok;
125 s = last_ptr;
127 if (!(ret = iret = malloc (ictok * sizeof (char *))))
128 return NULL;
130 while (ictok--)
132 *iret++ = s;
133 while (*s++);
134 while (!*s)
135 s++;
138 return ret;
140 #endif /*0 */
142 /*******************************************************************
143 case insensitive string compararison
144 ********************************************************************/
146 StrCaseCmp (const char *s, const char *t)
148 /* compare until we run out of string, either t or s, or find a difference */
149 /* We *must* use toupper rather than tolower here due to the
150 asynchronous upper to lower mapping.
152 #if !defined(KANJI_WIN95_COMPATIBILITY)
154 * For completeness we should put in equivalent code for code pages
155 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
156 * doubt anyone wants Samba to behave differently from Win95 and WinNT
157 * here. They both treat full width ascii characters as case senstive
158 * filenames (ie. they don't do the work we do here).
159 * JRA.
162 if (lp_client_code_page () == KANJI_CODEPAGE)
164 /* Win95 treats full width ascii characters as case sensitive. */
165 int diff;
166 for (;;)
168 if (!*s || !*t)
169 return toupper (*s) - toupper (*t);
170 else if (is_sj_alph (*s) && is_sj_alph (*t))
172 diff = sj_toupper2 (*(s + 1)) - sj_toupper2 (*(t + 1));
173 if (diff)
174 return diff;
175 s += 2;
176 t += 2;
178 else if (is_shift_jis (*s) && is_shift_jis (*t))
180 diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t);
181 if (diff)
182 return diff;
183 diff = ((int) (unsigned char) *(s + 1)) - ((int) (unsigned char) *(t + 1));
184 if (diff)
185 return diff;
186 s += 2;
187 t += 2;
189 else if (is_shift_jis (*s))
190 return 1;
191 else if (is_shift_jis (*t))
192 return -1;
193 else
195 diff = toupper (*s) - toupper (*t);
196 if (diff)
197 return diff;
198 s++;
199 t++;
203 else
204 #endif /* KANJI_WIN95_COMPATIBILITY */
206 while (*s && *t && toupper (*s) == toupper (*t))
208 s++;
209 t++;
212 return (toupper (*s) - toupper (*t));
216 /*******************************************************************
217 case insensitive string compararison, length limited
218 ********************************************************************/
220 StrnCaseCmp (const char *s, const char *t, size_t n)
222 /* compare until we run out of string, either t or s, or chars */
223 /* We *must* use toupper rather than tolower here due to the
224 asynchronous upper to lower mapping.
226 #if !defined(KANJI_WIN95_COMPATIBILITY)
228 * For completeness we should put in equivalent code for code pages
229 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
230 * doubt anyone wants Samba to behave differently from Win95 and WinNT
231 * here. They both treat full width ascii characters as case senstive
232 * filenames (ie. they don't do the work we do here).
233 * JRA.
236 if (lp_client_code_page () == KANJI_CODEPAGE)
238 /* Win95 treats full width ascii characters as case sensitive. */
239 int diff;
240 for (; n > 0;)
242 if (!*s || !*t)
243 return toupper (*s) - toupper (*t);
244 else if (is_sj_alph (*s) && is_sj_alph (*t))
246 diff = sj_toupper2 (*(s + 1)) - sj_toupper2 (*(t + 1));
247 if (diff)
248 return diff;
249 s += 2;
250 t += 2;
251 n -= 2;
253 else if (is_shift_jis (*s) && is_shift_jis (*t))
255 diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t);
256 if (diff)
257 return diff;
258 diff = ((int) (unsigned char) *(s + 1)) - ((int) (unsigned char) *(t + 1));
259 if (diff)
260 return diff;
261 s += 2;
262 t += 2;
263 n -= 2;
265 else if (is_shift_jis (*s))
266 return 1;
267 else if (is_shift_jis (*t))
268 return -1;
269 else
271 diff = toupper (*s) - toupper (*t);
272 if (diff)
273 return diff;
274 s++;
275 t++;
276 n--;
279 return 0;
281 else
282 #endif /* KANJI_WIN95_COMPATIBILITY */
284 while (n && *s && *t && toupper (*s) == toupper (*t))
286 s++;
287 t++;
288 n--;
291 /* not run out of chars - strings are different lengths */
292 if (n)
293 return (toupper (*s) - toupper (*t));
295 /* identical up to where we run out of chars,
296 and strings are same length */
297 return (0);
301 /*******************************************************************
302 compare 2 strings
303 ********************************************************************/
304 BOOL
305 strequal (const char *s1, const char *s2)
307 if (s1 == s2)
308 return (True);
309 if (!s1 || !s2)
310 return (False);
312 return (StrCaseCmp (s1, s2) == 0);
315 /*******************************************************************
316 compare 2 strings up to and including the nth char.
317 ******************************************************************/
318 BOOL
319 strnequal (const char *s1, const char *s2, size_t n)
321 if (s1 == s2)
322 return (True);
323 if (!s1 || !s2 || !n)
324 return (False);
326 return (StrnCaseCmp (s1, s2, n) == 0);
329 /*******************************************************************
330 compare 2 strings (case sensitive)
331 ********************************************************************/
332 BOOL
333 strcsequal (const char *s1, const char *s2)
335 if (s1 == s2)
336 return (True);
337 if (!s1 || !s2)
338 return (False);
340 return (strcmp (s1, s2) == 0);
344 /*******************************************************************
345 convert a string to lower case
346 ********************************************************************/
347 void
348 strlower (char *s)
350 while (*s)
352 #if !defined(KANJI_WIN95_COMPATIBILITY)
354 * For completeness we should put in equivalent code for code pages
355 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
356 * doubt anyone wants Samba to behave differently from Win95 and WinNT
357 * here. They both treat full width ascii characters as case senstive
358 * filenames (ie. they don't do the work we do here).
359 * JRA.
362 if (lp_client_code_page () == KANJI_CODEPAGE)
364 /* Win95 treats full width ascii characters as case sensitive. */
365 if (is_shift_jis (*s))
367 if (is_sj_upper (s[0], s[1]))
368 s[1] = sj_tolower2 (s[1]);
369 s += 2;
371 else if (is_kana (*s))
373 s++;
375 else
377 if (isupper (*s))
378 *s = tolower (*s);
379 s++;
382 else
383 #endif /* KANJI_WIN95_COMPATIBILITY */
385 size_t skip = skip_multibyte_char (*s);
386 if (skip != 0)
387 s += skip;
388 else
390 if (isupper (*s))
391 *s = tolower (*s);
392 s++;
398 /*******************************************************************
399 convert a string to upper case
400 ********************************************************************/
401 void
402 strupper (char *s)
404 while (*s)
406 #if !defined(KANJI_WIN95_COMPATIBILITY)
408 * For completeness we should put in equivalent code for code pages
409 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
410 * doubt anyone wants Samba to behave differently from Win95 and WinNT
411 * here. They both treat full width ascii characters as case senstive
412 * filenames (ie. they don't do the work we do here).
413 * JRA.
416 if (lp_client_code_page () == KANJI_CODEPAGE)
418 /* Win95 treats full width ascii characters as case sensitive. */
419 if (is_shift_jis (*s))
421 if (is_sj_lower (s[0], s[1]))
422 s[1] = sj_toupper2 (s[1]);
423 s += 2;
425 else if (is_kana (*s))
427 s++;
429 else
431 if (islower (*s))
432 *s = toupper (*s);
433 s++;
436 else
437 #endif /* KANJI_WIN95_COMPATIBILITY */
439 size_t skip = skip_multibyte_char (*s);
440 if (skip != 0)
441 s += skip;
442 else
444 if (islower (*s))
445 *s = toupper (*s);
446 s++;
452 #if 0
453 /*******************************************************************
454 convert a string to "normal" form
455 ********************************************************************/
456 void
457 strnorm (char *s)
459 extern int case_default;
460 if (case_default == CASE_UPPER)
461 strupper (s);
462 else
463 strlower (s);
466 /*******************************************************************
467 check if a string is in "normal" case
468 ********************************************************************/
469 BOOL
470 strisnormal (char *s)
472 extern int case_default;
473 if (case_default == CASE_UPPER)
474 return (!strhaslower (s));
476 return (!strhasupper (s));
478 #endif /* 0 */
480 /****************************************************************************
481 string replace
482 ****************************************************************************/
483 void
484 string_replace (char *s, char oldc, char newc)
486 size_t skip;
487 while (*s)
489 skip = skip_multibyte_char (*s);
490 if (skip != 0)
491 s += skip;
492 else
494 if (oldc == *s)
495 *s = newc;
496 s++;
502 /*******************************************************************
503 skip past some strings in a buffer
504 ********************************************************************/
505 char *
506 skip_string (char *buf, size_t n)
508 while (n--)
509 buf += strlen (buf) + 1;
510 return (buf);
513 /*******************************************************************
514 Count the number of characters in a string. Normally this will
515 be the same as the number of bytes in a string for single byte strings,
516 but will be different for multibyte.
517 16.oct.98, jdblair@cobaltnet.com.
518 ********************************************************************/
520 size_t
521 str_charnum (const char *s)
523 size_t len = 0;
525 while (*s != '\0')
527 int skip = skip_multibyte_char (*s);
528 s += (skip ? skip : 1);
529 len++;
531 return len;
534 /*******************************************************************
535 trim the specified elements off the front and back of a string
536 ********************************************************************/
538 BOOL
539 trim_string (char *s, const char *front, const char *back)
541 BOOL ret = False;
542 size_t front_len = (front && *front) ? strlen (front) : 0;
543 size_t back_len = (back && *back) ? strlen (back) : 0;
544 size_t s_len;
546 while (front_len && strncmp (s, front, front_len) == 0)
548 char *p = s;
549 ret = True;
550 while (1)
552 if (!(*p = p[front_len]))
553 break;
554 p++;
559 * We split out the multibyte code page
560 * case here for speed purposes. Under a
561 * multibyte code page we need to walk the
562 * string forwards only and multiple times.
563 * Thanks to John Blair for finding this
564 * one. JRA.
567 if (back_len)
569 if (!is_multibyte_codepage ())
571 s_len = strlen (s);
572 while ((s_len >= back_len) && (strncmp (s + s_len - back_len, back, back_len) == 0))
574 ret = True;
575 s[s_len - back_len] = '\0';
576 s_len = strlen (s);
579 else
583 * Multibyte code page case.
584 * Keep going through the string, trying
585 * to match the 'back' string with the end
586 * of the string. If we get a match, truncate
587 * 'back' off the end of the string and
588 * go through the string again from the
589 * start. Keep doing this until we have
590 * gone through the string with no match
591 * at the string end.
594 size_t mb_back_len = str_charnum (back);
595 size_t mb_s_len = str_charnum (s);
597 while (mb_s_len >= mb_back_len)
599 size_t charcount = 0;
600 char *mbp = s;
602 while (charcount < (mb_s_len - mb_back_len))
604 size_t skip = skip_multibyte_char (*mbp);
605 mbp += (skip ? skip : 1);
606 charcount++;
610 * mbp now points at mb_back_len multibyte
611 * characters from the end of s.
614 if (strcmp (mbp, back) == 0)
616 ret = True;
617 *mbp = '\0';
618 mb_s_len = str_charnum (s);
619 mbp = s;
621 else
622 break;
623 } /* end while mb_s_len... */
624 } /* end else .. */
625 } /* end if back_len .. */
627 return (ret);
630 #if 0
631 /****************************************************************************
632 does a string have any uppercase chars in it?
633 ****************************************************************************/
634 BOOL
635 strhasupper (const char *s)
637 while (*s)
639 #if !defined(KANJI_WIN95_COMPATIBILITY)
641 * For completeness we should put in equivalent code for code pages
642 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
643 * doubt anyone wants Samba to behave differently from Win95 and WinNT
644 * here. They both treat full width ascii characters as case senstive
645 * filenames (ie. they don't do the work we do here).
646 * JRA.
649 if (lp_client_code_page () == KANJI_CODEPAGE)
651 /* Win95 treats full width ascii characters as case sensitive. */
652 if (is_shift_jis (*s))
653 s += 2;
654 else if (is_kana (*s))
655 s++;
656 else
658 if (isupper (*s))
659 return (True);
660 s++;
663 else
664 #endif /* KANJI_WIN95_COMPATIBILITY */
666 size_t skip = skip_multibyte_char (*s);
667 if (skip != 0)
668 s += skip;
669 else
671 if (isupper (*s))
672 return (True);
673 s++;
677 return (False);
681 /****************************************************************************
682 does a string have any lowercase chars in it?
683 ****************************************************************************/
684 BOOL
685 strhaslower (const char *s)
687 while (*s)
689 #if !defined(KANJI_WIN95_COMPATIBILITY)
691 * For completeness we should put in equivalent code for code pages
692 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
693 * doubt anyone wants Samba to behave differently from Win95 and WinNT
694 * here. They both treat full width ascii characters as case senstive
695 * filenames (ie. they don't do the work we do here).
696 * JRA.
699 if (lp_client_code_page () == KANJI_CODEPAGE)
701 /* Win95 treats full width ascii characters as case sensitive. */
702 if (is_shift_jis (*s))
704 if (is_sj_upper (s[0], s[1]))
705 return (True);
706 if (is_sj_lower (s[0], s[1]))
707 return (True);
708 s += 2;
710 else if (is_kana (*s))
712 s++;
714 else
716 if (islower (*s))
717 return (True);
718 s++;
721 else
722 #endif /* KANJI_WIN95_COMPATIBILITY */
724 size_t skip = skip_multibyte_char (*s);
725 if (skip != 0)
726 s += skip;
727 else
729 if (islower (*s))
730 return (True);
731 s++;
735 return (False);
737 #endif /*0 */
739 /****************************************************************************
740 find the number of chars in a string
741 ****************************************************************************/
742 size_t
743 count_chars (const char *s, char c)
745 size_t count = 0;
747 #if !defined(KANJI_WIN95_COMPATIBILITY)
749 * For completeness we should put in equivalent code for code pages
750 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
751 * doubt anyone wants Samba to behave differently from Win95 and WinNT
752 * here. They both treat full width ascii characters as case senstive
753 * filenames (ie. they don't do the work we do here).
754 * JRA.
757 if (lp_client_code_page () == KANJI_CODEPAGE)
759 /* Win95 treats full width ascii characters as case sensitive. */
760 while (*s)
762 if (is_shift_jis (*s))
763 s += 2;
764 else
766 if (*s == c)
767 count++;
768 s++;
772 else
773 #endif /* KANJI_WIN95_COMPATIBILITY */
775 while (*s)
777 size_t skip = skip_multibyte_char (*s);
778 if (skip != 0)
779 s += skip;
780 else
782 if (*s == c)
783 count++;
784 s++;
788 return (count);
793 /*******************************************************************
794 safe string copy into a known length string. maxlength does not
795 include the terminating zero.
796 ********************************************************************/
797 char *
798 safe_strcpy (char *dest, const char *src, size_t maxlength)
800 size_t len;
802 if (!dest)
804 DEBUG (0, ("ERROR: NULL dest in safe_strcpy\n"));
805 return NULL;
808 if (!src)
810 *dest = 0;
811 return dest;
814 len = strlen (src);
816 if (len > maxlength)
818 DEBUG (0, ("ERROR: string overflow by %d in safe_strcpy [%.50s]\n",
819 (int) (len - maxlength), src));
820 len = maxlength;
823 memcpy (dest, src, len);
824 dest[len] = 0;
825 return dest;
828 /*******************************************************************
829 safe string cat into a string. maxlength does not
830 include the terminating zero.
831 ********************************************************************/
832 char *
833 safe_strcat (char *dest, const char *src, size_t maxlength)
835 size_t src_len, dest_len;
837 if (!dest)
839 DEBUG (0, ("ERROR: NULL dest in safe_strcat\n"));
840 return NULL;
843 if (!src)
845 return dest;
848 src_len = strlen (src);
849 dest_len = strlen (dest);
851 if (src_len + dest_len > maxlength)
853 DEBUG (0, ("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
854 (int) (src_len + dest_len - maxlength), src));
855 src_len = maxlength - dest_len;
858 memcpy (&dest[dest_len], src, src_len);
859 dest[dest_len + src_len] = 0;
860 return dest;
863 /****************************************************************************
864 this is a safer strcpy(), meant to prevent core dumps when nasty things happen
865 ****************************************************************************/
866 char *
867 StrCpy (char *dest, const char *src)
869 char *d = dest;
871 /* I don't want to get lazy with these ... */
872 SMB_ASSERT (dest && src);
874 if (!dest)
875 return (NULL);
876 if (!src)
878 *dest = 0;
879 return (dest);
881 while ((*d++ = *src++));
882 return (dest);
885 /****************************************************************************
886 like strncpy but always null terminates. Make sure there is room!
887 ****************************************************************************/
888 char *
889 StrnCpy (char *dest, const char *src, size_t n)
891 char *d = dest;
892 if (!dest)
893 return (NULL);
894 if (!src)
896 *dest = 0;
897 return (dest);
899 while (n-- && (*d++ = *src++));
900 *d = 0;
901 return (dest);
904 #if 0
905 /****************************************************************************
906 like strncpy but copies up to the character marker. always null terminates.
907 returns a pointer to the character marker in the source string (src).
908 ****************************************************************************/
909 char *
910 strncpyn (char *dest, const char *src, size_t n, char c)
912 char *p;
913 size_t str_len;
915 p = strchr (src, c);
916 if (p == NULL)
918 DEBUG (5, ("strncpyn: separator character (%c) not found\n", c));
919 return NULL;
922 str_len = PTR_DIFF (p, src);
923 strncpy (dest, src, MIN (n, str_len));
924 dest[str_len] = '\0';
926 return p;
930 /*************************************************************
931 Routine to get hex characters and turn them into a 16 byte array.
932 the array can be variable length, and any non-hex-numeric
933 characters are skipped. "0xnn" or "0Xnn" is specially catered
934 for.
936 valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
938 **************************************************************/
939 size_t
940 strhex_to_str (char *p, size_t len, const char *strhex)
942 size_t i;
943 size_t num_chars = 0;
944 unsigned char lonybble, hinybble;
945 char *hexchars = "0123456789ABCDEF";
946 char *p1 = NULL, *p2 = NULL;
948 for (i = 0; i < len && strhex[i] != 0; i++)
950 if (strnequal (hexchars, "0x", 2))
952 i++; /* skip two chars */
953 continue;
956 if (!(p1 = strchr (hexchars, toupper (strhex[i]))))
958 break;
961 i++; /* next hex digit */
963 if (!(p2 = strchr (hexchars, toupper (strhex[i]))))
965 break;
968 /* get the two nybbles */
969 hinybble = PTR_DIFF (p1, hexchars);
970 lonybble = PTR_DIFF (p2, hexchars);
972 p[num_chars] = (hinybble << 4) | lonybble;
973 num_chars++;
975 p1 = NULL;
976 p2 = NULL;
978 return num_chars;
981 /****************************************************************************
982 check if a string is part of a list
983 ****************************************************************************/
984 BOOL
985 in_list (char *s, char *list, BOOL casesensitive)
987 pstring tok;
988 char *p = list;
990 if (!list)
991 return (False);
993 while (next_token (&p, tok, LIST_SEP, sizeof (tok)))
995 if (casesensitive)
997 if (strcmp (tok, s) == 0)
998 return (True);
1000 else
1002 if (StrCaseCmp (tok, s) == 0)
1003 return (True);
1006 return (False);
1008 #endif /*0 */
1010 /* this is used to prevent lots of mallocs of size 1 */
1011 static char *null_string = NULL;
1013 /****************************************************************************
1014 set a string value, allocing the space for the string
1015 ****************************************************************************/
1016 BOOL
1017 string_init (char **dest, const char *src)
1019 size_t l;
1020 if (!src)
1021 src = "";
1023 l = strlen (src);
1025 if (l == 0)
1027 if (!null_string)
1029 if ((null_string = (char *) malloc (1)) == NULL)
1031 DEBUG (0, ("string_init: malloc fail for null_string.\n"));
1032 return False;
1034 *null_string = 0;
1036 *dest = null_string;
1038 else
1040 (*dest) = (char *) malloc (l + 1);
1041 if ((*dest) == NULL)
1043 DEBUG (0, ("Out of memory in string_init\n"));
1044 return False;
1047 pstrcpy (*dest, src);
1049 return (True);
1052 /****************************************************************************
1053 free a string value
1054 ****************************************************************************/
1055 void
1056 string_free (char **s)
1058 if (!s || !(*s))
1059 return;
1060 if (*s == null_string)
1061 *s = NULL;
1062 if (*s)
1063 free (*s);
1064 *s = NULL;
1067 /****************************************************************************
1068 set a string value, allocing the space for the string, and deallocating any
1069 existing space
1070 ****************************************************************************/
1071 BOOL
1072 string_set (char **dest, const char *src)
1074 string_free (dest);
1076 return (string_init (dest, src));
1080 /****************************************************************************
1081 substitute a string for a pattern in another string. Make sure there is
1082 enough room!
1084 This routine looks for pattern in s and replaces it with
1085 insert. It may do multiple replacements.
1087 any of " ; ' or ` in the insert string are replaced with _
1088 ****************************************************************************/
1089 void
1090 string_sub (char *s, const char *pattern, const char *insert)
1092 char *p;
1093 size_t ls, lp, li, i;
1095 if (!insert || !pattern || !s)
1096 return;
1098 ls = strlen (s);
1099 lp = strlen (pattern);
1100 li = strlen (insert);
1102 if (!*pattern)
1103 return;
1105 while (lp <= ls && (p = strstr (s, pattern)))
1107 memmove (p + li, p + lp, ls + 1 - (PTR_DIFF (p, s) + lp));
1108 for (i = 0; i < li; i++)
1110 switch (insert[i])
1112 case '`':
1113 case '"':
1114 case '\'':
1115 case ';':
1116 p[i] = '_';
1117 break;
1118 default:
1119 p[i] = insert[i];
1122 s = p + li;
1123 ls += (li - lp);
1127 #if 0
1128 /****************************************************************************
1129 similar to string_sub() but allows for any character to be substituted.
1130 Use with caution!
1131 ****************************************************************************/
1132 void
1133 all_string_sub (char *s, const char *pattern, const char *insert)
1135 char *p;
1136 size_t ls, lp, li;
1138 if (!insert || !pattern || !s)
1139 return;
1141 ls = strlen (s);
1142 lp = strlen (pattern);
1143 li = strlen (insert);
1145 if (!*pattern)
1146 return;
1148 while (lp <= ls && (p = strstr (s, pattern)))
1150 memmove (p + li, p + lp, ls + 1 - (PTR_DIFF (p, s) + lp));
1151 memcpy (p, insert, li);
1152 s = p + li;
1153 ls += (li - lp);
1158 /****************************************************************************
1159 splits out the front and back at a separator.
1160 ****************************************************************************/
1161 void
1162 split_at_last_component (char *path, char *front, char sep, char *back)
1164 char *p = strrchr (path, sep);
1166 if (p != NULL)
1168 *p = 0;
1170 if (front != NULL)
1172 pstrcpy (front, path);
1174 if (p != NULL)
1176 if (back != NULL)
1178 pstrcpy (back, p + 1);
1180 *p = '\\';
1182 else
1184 if (back != NULL)
1186 back[0] = 0;
1190 #endif /*0 */