2 * Copyright (C) 2013 Intel Corporation.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 * José Bollo <jose.bollo@open.eurogiciel.org>
20 * Stéphane Desneux <stephane.desneux@open.eurogiciel.org>
21 * Jean-Benoit Martin <jean-benoit.martin@open.eurogiciel.org>
32 #ifndef INITIAL_SCRATCH_CAPACITY
33 #define INITIAL_SCRATCH_CAPACITY 240
36 #if INITIAL_SCRATCH_CAPACITY <= 0
37 #error "bad value for INITIAL_SCRATCH_CAPACITY"
40 #ifndef NOT_MULTI_THREAD_SAFE
42 static pthread_key_t tlskey;
43 static int key_initialized = 0;
45 static void *global_scratch = NULL;
48 /* CAUTION: in a multitheaded context, it is expected that
49 =========== the function scratchcat is call under a mutex.
50 If it is not the case please check for initializing 'tlskey'
51 only one time before use of it. */
53 const char *scratchcat( int ispath, const char **strings)
57 size_t length, capacity;
61 /* get the recorded pointer on scrtch area */
62 #ifndef NOT_MULTI_THREAD_SAFE
63 if (!key_initialized) {
65 pthread_key_create( &tlskey, (void(*)(void*))free);
67 scratch = pthread_getspecific( tlskey);
69 scratch = global_scratch;
72 /* create the scratch area if needed */
73 if (scratch == NULL) {
74 capacity = INITIAL_SCRATCH_CAPACITY;
75 p = malloc( capacity + sizeof(size_t));
78 *((size_t*)p) = capacity;
80 #ifndef NOT_MULTI_THREAD_SAFE
81 pthread_setspecific( tlskey, p);
87 /* set local data for scratch area */
88 capacity = *((size_t*)scratch);
89 result = (char*)(1+((size_t*)scratch));
92 /* copy the strings */
105 else if(c != '/' && pc != '/')
107 else if(c == '/' && pc == '/') {
122 /* extend the scratch area if needed */
123 if (length == capacity) {
124 capacity = 2 * capacity;
125 p = realloc( scratch, capacity + sizeof(size_t));
128 *((size_t*)p) = capacity;
131 #ifndef NOT_MULTI_THREAD_SAFE
132 pthread_setspecific( tlskey, p);
136 result = (char*)(1+((size_t*)p));
140 /* append the char */
141 pc = result[length++] = c;
150 int main(int argc, const char**argv) {
153 ispath = argv[0] && argv[0][0] == '-' && argv[0][1] == 'p';
154 printf("%s\n",scratchcat(ispath,argv+ispath));