1/*
2 * string.c - string manipulation
3 *
4 * This file is part of zsh, the Z shell.
5 *
6 * Copyright (c) 2000 Peter Stephenson
7 * All rights reserved.
8 *
9 * Permission is hereby granted, without written agreement and without
10 * license or royalty fees, to use, copy, modify, and distribute this
11 * software and to distribute modified versions of this software for any
12 * purpose, provided that the above copyright notice and the following
13 * two paragraphs appear in all copies of this software.
14 *
15 * In no event shall Peter Stephenson or the Zsh Development Group be liable
16 * to any party for direct, indirect, special, incidental, or consequential
17 * damages arising out of the use of this software and its documentation,
18 * even if Peter Stephenson and the Zsh Development Group have been advised of
19 * the possibility of such damage.
20 *
21 * Peter Stephenson and the Zsh Development Group specifically disclaim any
22 * warranties, including, but not limited to, the implied warranties of
23 * merchantability and fitness for a particular purpose.  The software
24 * provided hereunder is on an "as is" basis, and Peter Stephenson and the
25 * Zsh Development Group have no obligation to provide maintenance,
26 * support, updates, enhancements, or modifications.
27 */
28
29#include "zsh.mdh"
30
31/**/
32mod_export char *
33dupstring(const char *s)
34{
35    char *t;
36
37    if (!s)
38	return NULL;
39    t = (char *) zhalloc(strlen((char *)s) + 1);
40    strcpy(t, s);
41    return t;
42}
43
44/**/
45mod_export char *
46ztrdup(const char *s)
47{
48    char *t;
49
50    if (!s)
51	return NULL;
52    t = (char *)zalloc(strlen((char *)s) + 1);
53    strcpy(t, s);
54    return t;
55}
56
57/**/
58#ifdef MULTIBYTE_SUPPORT
59/**/
60mod_export wchar_t *
61wcs_ztrdup(const wchar_t *s)
62{
63    wchar_t *t;
64
65    if (!s)
66	return NULL;
67    t = (wchar_t *)zalloc(sizeof(wchar_t) * (wcslen((wchar_t *)s) + 1));
68    wcscpy(t, s);
69    return t;
70}
71/**/
72#endif /* MULTIBYTE_SUPPORT */
73
74
75/* concatenate s1, s2, and s3 in dynamically allocated buffer */
76
77/**/
78mod_export char *
79tricat(char const *s1, char const *s2, char const *s3)
80{
81    /* This version always uses permanently-allocated space. */
82    char *ptr;
83    size_t l1 = strlen(s1);
84    size_t l2 = strlen(s2);
85
86    ptr = (char *)zalloc(l1 + l2 + strlen(s3) + 1);
87    strcpy(ptr, s1);
88    strcpy(ptr + l1, s2);
89    strcpy(ptr + l1 + l2, s3);
90    return ptr;
91}
92
93/**/
94mod_export char *
95zhtricat(char const *s1, char const *s2, char const *s3)
96{
97    char *ptr;
98    size_t l1 = strlen(s1);
99    size_t l2 = strlen(s2);
100
101    ptr = (char *)zhalloc(l1 + l2 + strlen(s3) + 1);
102    strcpy(ptr, s1);
103    strcpy(ptr + l1, s2);
104    strcpy(ptr + l1 + l2, s3);
105    return ptr;
106}
107
108/* concatenate s1 and s2 in dynamically allocated buffer */
109
110/**/
111mod_export char *
112dyncat(const char *s1, const char *s2)
113{
114    /* This version always uses space from the current heap. */
115    char *ptr;
116    size_t l1 = strlen(s1);
117
118    ptr = (char *)zhalloc(l1 + strlen(s2) + 1);
119    strcpy(ptr, s1);
120    strcpy(ptr + l1, s2);
121    return ptr;
122}
123
124/**/
125mod_export char *
126bicat(const char *s1, const char *s2)
127{
128    /* This version always uses permanently-allocated space. */
129    char *ptr;
130    size_t l1 = strlen(s1);
131
132    ptr = (char *)zalloc(l1 + strlen(s2) + 1);
133    strcpy(ptr, s1);
134    strcpy(ptr + l1, s2);
135    return ptr;
136}
137
138/* like dupstring(), but with a specified length */
139
140/**/
141mod_export char *
142dupstrpfx(const char *s, int len)
143{
144    char *r = zhalloc(len + 1);
145
146    memcpy(r, s, len);
147    r[len] = '\0';
148    return r;
149}
150
151/**/
152mod_export char *
153ztrduppfx(const char *s, int len)
154{
155    /* This version always uses permanently-allocated space. */
156    char *r = zalloc(len + 1);
157
158    memcpy(r, s, len);
159    r[len] = '\0';
160    return r;
161}
162
163/* Append a string to an allocated string, reallocating to make room. */
164
165/**/
166mod_export char *
167appstr(char *base, char const *append)
168{
169    return strcat(realloc(base, strlen(base) + strlen(append) + 1), append);
170}
171
172/* Return a pointer to the last character of a string,
173   unless the string is empty. */
174
175/**/
176mod_export char *
177strend(char *str)
178{
179    if (*str == '\0')
180	return str;
181    return str + strlen (str) - 1;
182}
183