1 /*
   2  * Copyright (c) 2005, 2012, 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 "jli_util.h"
  30 
  31 /*
  32  * Returns a pointer to a block of at least 'size' bytes of memory.
  33  * Prints error message and exits if the memory could not be allocated.
  34  */
  35 void *
  36 JLI_MemAlloc(size_t size)
  37 {
  38     void *p = malloc(size);
  39     if (p == 0) {
  40         perror("malloc");
  41         exit(1);
  42     }
  43     return p;
  44 }
  45 
  46 /*
  47  * Equivalent to realloc(size).
  48  * Prints error message and exits if the memory could not be reallocated.
  49  */
  50 void *
  51 JLI_MemRealloc(void *ptr, size_t size)
  52 {
  53     void *p = realloc(ptr, size);
  54     if (p == 0) {
  55         perror("realloc");
  56         exit(1);
  57     }
  58     return p;
  59 }
  60 
  61 /*
  62  * Wrapper over strdup(3C) which prints an error message and exits if memory
  63  * could not be allocated.
  64  */
  65 char *
  66 JLI_StringDup(const char *s1)
  67 {
  68     char *s = strdup(s1);
  69     if (s == NULL) {
  70         perror("strdup");
  71         exit(1);
  72     }
  73     return s;
  74 }
  75 
  76 /*
  77  * Very equivalent to free(ptr).
  78  * Here to maintain pairing with the above routines.
  79  */
  80 void
  81 JLI_MemFree(void *ptr)
  82 {
  83     free(ptr);
  84 }
  85 
  86 /*
  87  * debug helpers we use
  88  */
  89 static jboolean _launcher_debug = JNI_FALSE;
  90 
  91 void
  92 JLI_TraceLauncher(const char* fmt, ...)
  93 {
  94     va_list vl;
  95     if (_launcher_debug != JNI_TRUE) return;
  96     va_start(vl, fmt);
  97     vprintf(fmt,vl);
  98     va_end(vl);
  99     fflush(stdout);
 100 }
 101 
 102 void
 103 JLI_SetTraceLauncher()
 104 {
 105    if (getenv(JLDEBUG_ENV_ENTRY) != 0) {
 106         _launcher_debug = JNI_TRUE;
 107         JLI_TraceLauncher("----%s----\n", JLDEBUG_ENV_ENTRY);
 108    }
 109 }
 110 
 111 jboolean
 112 JLI_IsTraceLauncher()
 113 {
 114    return _launcher_debug;
 115 }
 116 
 117 int
 118 JLI_StrCCmp(const char *s1, const char* s2)
 119 {
 120    return JLI_StrNCmp(s1, s2, JLI_StrLen(s2));
 121 }
 122 
 123 JLI_List
 124 JLI_List_new(size_t capacity)
 125 {
 126     JLI_List l = (JLI_List) JLI_MemAlloc(sizeof(struct JLI_List_));
 127     l->capacity = capacity;
 128     l->elements = (char **) JLI_MemAlloc(capacity * sizeof(l->elements[0]));
 129     l->size = 0;
 130     return l;
 131 }
 132 
 133 void
 134 JLI_List_free(JLI_List sl)
 135 {
 136     if (sl) {
 137         if (sl->elements) {
 138             size_t i;
 139             for (i = 0; i < sl->size; i++)
 140                 JLI_MemFree(sl->elements[i]);
 141             JLI_MemFree(sl->elements);
 142         }
 143         JLI_MemFree(sl);
 144     }
 145 }
 146 
 147 void
 148 JLI_List_ensureCapacity(JLI_List sl, size_t capacity)
 149 {
 150     if (sl->capacity < capacity) {
 151         while (sl->capacity < capacity)
 152             sl->capacity *= 2;
 153         sl->elements = JLI_MemRealloc(sl->elements,
 154             sl->capacity * sizeof(sl->elements[0]));
 155     }
 156 }
 157 
 158 void
 159 JLI_List_add(JLI_List sl, char *str)
 160 {
 161     JLI_List_ensureCapacity(sl, sl->size+1);
 162     sl->elements[sl->size++] = str;
 163 }
 164 
 165 void
 166 JLI_List_addSubstring(JLI_List sl, const char *beg, size_t len)
 167 {
 168     char *str = (char *) JLI_MemAlloc(len+1);
 169     memcpy(str, beg, len);
 170     str[len] = '\0';
 171     JLI_List_ensureCapacity(sl, sl->size+1);
 172     sl->elements[sl->size++] = str;
 173 }
 174 
 175 char *
 176 JLI_List_combine(JLI_List sl)
 177 {
 178     size_t i;
 179     size_t size;
 180     char *str;
 181     char *p;
 182     for (i = 0, size = 1; i < sl->size; i++)
 183         size += JLI_StrLen(sl->elements[i]);
 184 
 185     str = JLI_MemAlloc(size);
 186 
 187     for (i = 0, p = str; i < sl->size; i++) {
 188         size_t len = JLI_StrLen(sl->elements[i]);
 189         memcpy(p, sl->elements[i], len);
 190         p += len;
 191     }
 192     *p = '\0';
 193 
 194     return str;
 195 }
 196 
 197 char *
 198 JLI_List_join(JLI_List sl, char sep)
 199 {
 200     size_t i;
 201     size_t size;
 202     char *str;
 203     char *p;
 204     for (i = 0, size = 1; i < sl->size; i++)
 205         size += JLI_StrLen(sl->elements[i]) + 1;
 206 
 207     str = JLI_MemAlloc(size);
 208 
 209     for (i = 0, p = str; i < sl->size; i++) {
 210         size_t len = JLI_StrLen(sl->elements[i]);
 211         if (i > 0) *p++ = sep;
 212         memcpy(p, sl->elements[i], len);
 213         p += len;
 214     }
 215     *p = '\0';
 216 
 217     return str;
 218 }
 219 
 220 JLI_List
 221 JLI_List_split(const char *str, char sep)
 222 {
 223     const char *p, *q;
 224     size_t len = JLI_StrLen(str);
 225     int count;
 226     JLI_List sl;
 227     for (count = 1, p = str; p < str + len; p++)
 228         count += (*p == sep);
 229     sl = JLI_List_new(count);
 230     for (p = str;;) {
 231         for (q = p; q <= str + len; q++) {
 232             if (*q == sep || *q == '\0') {
 233                 JLI_List_addSubstring(sl, p, q - p);
 234                 if (*q == '\0')
 235                     return sl;
 236                 p = q + 1;
 237             }
 238         }
 239     }
 240 }