2 * Copyright (C) 2008 Kristian Høgsberg <krh@redhat.com>
3 * Copyright (C) 2008 Red Hat, Inc
4 * Copyright (C) 2009, 2011, 2012, 2014, 2016 J. Ali Harlow <ali@juiblex.co.uk>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
31 #include <sys/utsname.h>
36 #include "types/types.h"
37 #include "razor-internal.h"
39 /* Required by gnulib on non-libc platforms */
40 char *program_name = "librazor";
53 struct qsort_context {
55 razor_compare_with_data_func_t compare;
60 qsort_swap(void *p1, void *p2, size_t size)
65 memcpy(buffer, p1, size);
67 memcpy(p2, buffer, size);
72 __qsort_with_data(void *base, size_t nelem, uint32_t *map,
73 struct qsort_context *ctx)
75 void *p, *start, *end, *pivot;
76 uint32_t *mp, *mstart, *mend, tmp;
77 int left, right, result;
78 size_t size = ctx->size;
82 end = base + nelem * size;
86 pivot = base + (rand() % nelem) * size;
89 result = ctx->compare(p, pivot, ctx->data);
91 qsort_swap(p, start, size);
101 } else if (result == 0) {
107 qsort_swap(p, end, size);
116 left = (start - base) / size;
117 right = (base + nelem * size - end) / size;
119 __qsort_with_data(base, left, map, ctx);
121 __qsort_with_data(end, right, mend, ctx);
125 razor_qsort_with_data(void *base, size_t nelem, size_t size,
126 razor_compare_with_data_func_t compare, void *data)
128 struct qsort_context ctx;
136 ctx.compare = compare;
139 map = malloc(nelem * sizeof (uint32_t));
140 for (i = 0; i < nelem; i++)
143 __qsort_with_data(base, nelem, map, &ctx);
148 void environment_init(struct environment *env)
151 array_init(&env->string_pool);
152 array_init(&env->vars);
155 void environment_add_variable(struct environment *env,
156 const char *variable, const char *value)
160 assert(!env->is_set);
162 s = array_add(&env->string_pool,
163 strlen(variable) + strlen(value) + 2);
164 sprintf(s, "%s=%s", variable, value);
165 r = array_add(&env->vars, sizeof *r);
166 *r = s - (char *)env->string_pool.data;
169 void environment_set(struct environment *env)
179 count = env->vars.size / sizeof(uint32_t);
180 r = (uint32_t *)env->vars.data;
181 for (i = 0; i < count; i++) {
182 s = env->string_pool.data + *r++;
197 void environment_unset(struct environment *env)
204 count = env->vars.size / sizeof(uint32_t);
205 r = (uint32_t *)env->vars.data;
206 for (i = 0; i < count; i++) {
207 s = env->string_pool.data + *r++;
227 void environment_release(struct environment *env)
229 environment_unset(env);
230 array_release(&env->string_pool);
231 array_release(&env->vars);
234 RAZOR_EXPORT char *razor_concat(const char *s, ...)
244 while((string = va_arg(args, const char *)))
245 len += strlen(string);
249 concat = malloc(len + 1);
257 memcpy(concat, s, len);
259 while((string = va_arg(args, const char *))) {
260 len = strlen(string);
261 memcpy(concat + n, string, len);
273 razor_resolve_relative_uri(const char *base_uri, const char *relative_uri,
274 struct razor_error **error)
277 struct razor_uri ru, base, ref;
279 if (razor_uri_parse_uri(&base, base_uri, 1, error))
282 if (razor_uri_parse_relative_ref(&ref, relative_uri, error)) {
283 razor_uri_destroy(&base);
287 razor_uri_resolve(&ru, &base, &ref);
289 razor_uri_destroy(&base);
290 razor_uri_destroy(&ref);
292 result = razor_uri_recompose(&ru);
294 razor_uri_destroy(&ru);
299 RAZOR_EXPORT const char *razor_system_arch(void)
304 GetNativeSystemInfo(&si);
305 switch(si.wProcessorArchitecture)
307 case PROCESSOR_ARCHITECTURE_INTEL:
309 case PROCESSOR_ARCHITECTURE_AMD64:
315 static struct utsname un;
326 char *razor_utf16_to_utf8(const wchar_t *utf16, int len)
334 n = WideCharToMultiByte(CP_UTF8, 0, utf16, len, NULL, 0, NULL, NULL);
338 (void)WideCharToMultiByte(CP_UTF8, 0, utf16, len, utf8, n, NULL, NULL);
345 wchar_t *razor_utf8_to_utf16(const char *utf8, int len)
351 utf16 = calloc(1, sizeof(wchar_t));
355 n = MultiByteToWideChar(CP_UTF8, 0, utf8, len, NULL, 0);
358 utf16 = malloc(n * sizeof(wchar_t));
359 (void)MultiByteToWideChar(CP_UTF8, 0, utf8, len, utf16, n);
366 #endif /* MSWIN_API */
369 * Returns an absolute path (ie., not relative to the current directory on the
370 * default, or any other, disk). Note that the absolute path may still have
371 * "." or ".." path segments present (ie., this is not equivalent to realpath).
373 char *razor_abspath(const char *path)
378 wchar_t *wpath, *wabspath;
381 wpath = razor_utf8_to_utf16(path, -1);
383 n = GetFullPathNameW(wpath, 0, NULL, NULL);
389 wabspath = malloc(n * sizeof(sizeof(wchar_t)));
390 if (!GetFullPathNameW(wpath, n, wabspath, NULL)) {
397 abspath = razor_utf16_to_utf8(wabspath, n - 1);
402 #else /* MSWIN_API */
408 abspath = strdup(path);
410 pathlen = strlen(path);
411 for (len = 32;; len *= 2) {
412 abspath = malloc(pathlen + 1 + len);
413 if (getcwd(abspath, len))
415 if (errno != ERANGE) {
421 len = strlen(abspath);
422 if (abspath[len - 1] != '/')
423 abspath[len++] = '/';
424 memcpy(abspath + len, path, pathlen + 1);
425 abspath = realloc(abspath, len + pathlen + 1);