1 /*
2  * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 #include <stdio.h>
27 #include <string.h>
28 #include <stdarg.h>
29 #include "jni.h"
30 #include "jli_util.h"
31 
32 /*
33  * Returns a pointer to a block of at least 'size' bytes of memory.
34  * Prints error message and exits if the memory could not be allocated.
35  */
36 JNIEXPORT void * JNICALL
JLI_MemAlloc(size_t size)37 JLI_MemAlloc(size_t size)
38 {
39     void *p = malloc(size);
40     if (p == 0) {
41         perror("malloc");
42         exit(1);
43     }
44     return p;
45 }
46 
47 /*
48  * Equivalent to realloc(size).
49  * Prints error message and exits if the memory could not be reallocated.
50  */
51 void *
JLI_MemRealloc(void * ptr,size_t size)52 JLI_MemRealloc(void *ptr, size_t size)
53 {
54     void *p = realloc(ptr, size);
55     if (p == 0) {
56         perror("realloc");
57         exit(1);
58     }
59     return p;
60 }
61 
62 /*
63  * Wrapper over strdup(3C) which prints an error message and exits if memory
64  * could not be allocated.
65  */
66 JNIEXPORT char * JNICALL
JLI_StringDup(const char * s1)67 JLI_StringDup(const char *s1)
68 {
69     char *s = strdup(s1);
70     if (s == NULL) {
71         perror("strdup");
72         exit(1);
73     }
74     return s;
75 }
76 
77 /*
78  * Very equivalent to free(ptr).
79  * Here to maintain pairing with the above routines.
80  */
81 JNIEXPORT void JNICALL
JLI_MemFree(void * ptr)82 JLI_MemFree(void *ptr)
83 {
84     free(ptr);
85 }
86 
87 jboolean
JLI_HasSuffix(const char * s1,const char * s2)88 JLI_HasSuffix(const char *s1, const char *s2)
89 {
90     char *p = JLI_StrRChr(s1, '.');
91     if (p == NULL || *p == '\0') {
92         return JNI_FALSE;
93     }
94     return (JLI_StrCaseCmp(p, s2) == 0);
95 }
96 
97 /*
98  * debug helpers we use
99  */
100 static jboolean _launcher_debug = JNI_FALSE;
101 
102 void
JLI_TraceLauncher(const char * fmt,...)103 JLI_TraceLauncher(const char* fmt, ...)
104 {
105     va_list vl;
106     if (_launcher_debug != JNI_TRUE) return;
107     va_start(vl, fmt);
108     vprintf(fmt,vl);
109     va_end(vl);
110     fflush(stdout);
111 }
112 
113 JNIEXPORT void JNICALL
JLI_SetTraceLauncher()114 JLI_SetTraceLauncher()
115 {
116    if (getenv(JLDEBUG_ENV_ENTRY) != 0) {
117         _launcher_debug = JNI_TRUE;
118         JLI_TraceLauncher("----%s----\n", JLDEBUG_ENV_ENTRY);
119    }
120 }
121 
122 jboolean
JLI_IsTraceLauncher()123 JLI_IsTraceLauncher()
124 {
125    return _launcher_debug;
126 }
127 
128 int
JLI_StrCCmp(const char * s1,const char * s2)129 JLI_StrCCmp(const char *s1, const char* s2)
130 {
131    return JLI_StrNCmp(s1, s2, JLI_StrLen(s2));
132 }
133 
134 JNIEXPORT JLI_List JNICALL
JLI_List_new(size_t capacity)135 JLI_List_new(size_t capacity)
136 {
137     JLI_List l = (JLI_List) JLI_MemAlloc(sizeof(struct JLI_List_));
138     l->capacity = capacity;
139     l->elements = (char **) JLI_MemAlloc(capacity * sizeof(l->elements[0]));
140     l->size = 0;
141     return l;
142 }
143 
144 void
JLI_List_free(JLI_List sl)145 JLI_List_free(JLI_List sl)
146 {
147     if (sl) {
148         if (sl->elements) {
149             size_t i;
150             for (i = 0; i < sl->size; i++)
151                 JLI_MemFree(sl->elements[i]);
152             JLI_MemFree(sl->elements);
153         }
154         JLI_MemFree(sl);
155     }
156 }
157 
158 void
JLI_List_ensureCapacity(JLI_List sl,size_t capacity)159 JLI_List_ensureCapacity(JLI_List sl, size_t capacity)
160 {
161     if (sl->capacity < capacity) {
162         while (sl->capacity < capacity)
163             sl->capacity *= 2;
164         sl->elements = JLI_MemRealloc(sl->elements,
165             sl->capacity * sizeof(sl->elements[0]));
166     }
167 }
168 
169 JNIEXPORT void JNICALL
JLI_List_add(JLI_List sl,char * str)170 JLI_List_add(JLI_List sl, char *str)
171 {
172     JLI_List_ensureCapacity(sl, sl->size+1);
173     sl->elements[sl->size++] = str;
174 }
175 
176 void
JLI_List_addSubstring(JLI_List sl,const char * beg,size_t len)177 JLI_List_addSubstring(JLI_List sl, const char *beg, size_t len)
178 {
179     char *str = (char *) JLI_MemAlloc(len+1);
180     memcpy(str, beg, len);
181     str[len] = '\0';
182     JLI_List_ensureCapacity(sl, sl->size+1);
183     sl->elements[sl->size++] = str;
184 }
185 
186 char *
JLI_List_combine(JLI_List sl)187 JLI_List_combine(JLI_List sl)
188 {
189     size_t i;
190     size_t size;
191     char *str;
192     char *p;
193     for (i = 0, size = 1; i < sl->size; i++)
194         size += JLI_StrLen(sl->elements[i]);
195 
196     str = JLI_MemAlloc(size);
197 
198     for (i = 0, p = str; i < sl->size; i++) {
199         size_t len = JLI_StrLen(sl->elements[i]);
200         memcpy(p, sl->elements[i], len);
201         p += len;
202     }
203     *p = '\0';
204 
205     return str;
206 }
207 
208 char *
JLI_List_join(JLI_List sl,char sep)209 JLI_List_join(JLI_List sl, char sep)
210 {
211     size_t i;
212     size_t size;
213     char *str;
214     char *p;
215     for (i = 0, size = 1; i < sl->size; i++)
216         size += JLI_StrLen(sl->elements[i]) + 1;
217 
218     str = JLI_MemAlloc(size);
219 
220     for (i = 0, p = str; i < sl->size; i++) {
221         size_t len = JLI_StrLen(sl->elements[i]);
222         if (i > 0) *p++ = sep;
223         memcpy(p, sl->elements[i], len);
224         p += len;
225     }
226     *p = '\0';
227 
228     return str;
229 }
230 
231 JLI_List
JLI_List_split(const char * str,char sep)232 JLI_List_split(const char *str, char sep)
233 {
234     const char *p, *q;
235     size_t len = JLI_StrLen(str);
236     int count;
237     JLI_List sl;
238     for (count = 1, p = str; p < str + len; p++)
239         count += (*p == sep);
240     sl = JLI_List_new(count);
241     for (p = str;;) {
242         for (q = p; q <= str + len; q++) {
243             if (*q == sep || *q == '\0') {
244                 JLI_List_addSubstring(sl, p, q - p);
245                 if (*q == '\0')
246                     return sl;
247                 p = q + 1;
248             }
249         }
250     }
251 }
252