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
  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 *
  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
  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
  82 JLI_MemFree(void *ptr)
  83 {
  84     free(ptr);
  85 }
  86 
  87 /*
  88  * debug helpers we use
  89  */
  90 static jboolean _launcher_debug = JNI_FALSE;
  91 
  92 void
  93 JLI_TraceLauncher(const char* fmt, ...)
  94 {
  95     va_list vl;
  96     if (_launcher_debug != JNI_TRUE) return;
  97     va_start(vl, fmt);
  98     vprintf(fmt,vl);
  99     va_end(vl);
 100     fflush(stdout);
 101 }
 102 
 103 JNIEXPORT void JNICALL
 104 JLI_SetTraceLauncher()
 105 {
 106    if (getenv(JLDEBUG_ENV_ENTRY) != 0) {
 107         _launcher_debug = JNI_TRUE;
 108         JLI_TraceLauncher("----%s----\n", JLDEBUG_ENV_ENTRY);
 109    }
 110 }
 111 
 112 jboolean
 113 JLI_IsTraceLauncher()
 114 {
 115    return _launcher_debug;
 116 }
 117 
 118 int
 119 JLI_StrCCmp(const char *s1, const char* s2)
 120 {
 121    return JLI_StrNCmp(s1, s2, JLI_StrLen(s2));
 122 }
 123 
 124 JNIEXPORT JLI_List JNICALL
 125 JLI_List_new(size_t capacity)
 126 {
 127     JLI_List l = (JLI_List) JLI_MemAlloc(sizeof(struct JLI_List_));
 128     l->capacity = capacity;
 129     l->elements = (char **) JLI_MemAlloc(capacity * sizeof(l->elements[0]));
 130     l->size = 0;
 131     return l;
 132 }
 133 
 134 void
 135 JLI_List_free(JLI_List sl)
 136 {
 137     if (sl) {
 138         if (sl->elements) {
 139             size_t i;
 140             for (i = 0; i < sl->size; i++)
 141                 JLI_MemFree(sl->elements[i]);
 142             JLI_MemFree(sl->elements);
 143         }
 144         JLI_MemFree(sl);
 145     }
 146 }
 147 
 148 void
 149 JLI_List_ensureCapacity(JLI_List sl, size_t capacity)
 150 {
 151     if (sl->capacity < capacity) {
 152         while (sl->capacity < capacity)
 153             sl->capacity *= 2;
 154         sl->elements = JLI_MemRealloc(sl->elements,
 155             sl->capacity * sizeof(sl->elements[0]));
 156     }
 157 }
 158 
 159 JNIEXPORT void JNICALL
 160 JLI_List_add(JLI_List sl, char *str)
 161 {
 162     JLI_List_ensureCapacity(sl, sl->size+1);
 163     sl->elements[sl->size++] = str;
 164 }
 165 
 166 void
 167 JLI_List_addSubstring(JLI_List sl, const char *beg, size_t len)
 168 {
 169     char *str = (char *) JLI_MemAlloc(len+1);
 170     memcpy(str, beg, len);
 171     str[len] = '\0';
 172     JLI_List_ensureCapacity(sl, sl->size+1);
 173     sl->elements[sl->size++] = str;
 174 }
 175 
 176 char *
 177 JLI_List_combine(JLI_List sl)
 178 {
 179     size_t i;
 180     size_t size;
 181     char *str;
 182     char *p;
 183     for (i = 0, size = 1; i < sl->size; i++)
 184         size += JLI_StrLen(sl->elements[i]);
 185 
 186     str = JLI_MemAlloc(size);
 187 
 188     for (i = 0, p = str; i < sl->size; i++) {
 189         size_t len = JLI_StrLen(sl->elements[i]);
 190         memcpy(p, sl->elements[i], len);
 191         p += len;
 192     }
 193     *p = '\0';
 194 
 195     return str;
 196 }
 197 
 198 char *
 199 JLI_List_join(JLI_List sl, char sep)
 200 {
 201     size_t i;
 202     size_t size;
 203     char *str;
 204     char *p;
 205     for (i = 0, size = 1; i < sl->size; i++)
 206         size += JLI_StrLen(sl->elements[i]) + 1;
 207 
 208     str = JLI_MemAlloc(size);
 209 
 210     for (i = 0, p = str; i < sl->size; i++) {
 211         size_t len = JLI_StrLen(sl->elements[i]);
 212         if (i > 0) *p++ = sep;
 213         memcpy(p, sl->elements[i], len);
 214         p += len;
 215     }
 216     *p = '\0';
 217 
 218     return str;
 219 }
 220 
 221 JLI_List
 222 JLI_List_split(const char *str, char sep)
 223 {
 224     const char *p, *q;
 225     size_t len = JLI_StrLen(str);
 226     int count;
 227     JLI_List sl;
 228     for (count = 1, p = str; p < str + len; p++)
 229         count += (*p == sep);
 230     sl = JLI_List_new(count);
 231     for (p = str;;) {
 232         for (q = p; q <= str + len; q++) {
 233             if (*q == sep || *q == '\0') {
 234                 JLI_List_addSubstring(sl, p, q - p);
 235                 if (*q == '\0')
 236                     return sl;
 237                 p = q + 1;
 238             }
 239         }
 240     }
 241 }