CodeCompass
421 строка · 6.9 Кб
1#include <limits.h>2#include <stdlib.h>3#include <stdint.h>4#include <unistd.h>5#include <assert.h>6#include <ctype.h>7#include <string.h>8
9#include "ldlogger-util.h"10
11static char* makePathAbsRec(const char* path_, char* resolved_)12{
13char pathBuff[PATH_MAX];14char* slashPos;15char* child;16
17if (realpath(path_, pathBuff))18{19pathBuff[PATH_MAX - 1] = 0;20return strcpy(resolved_, pathBuff);21}22else23{24strcpy(pathBuff, path_);25}26
27/* cut off the last part */28slashPos = strrchr(pathBuff, '/');29if (!slashPos || slashPos == path_)30{31return NULL;32}33
34child = slashPos + 1;35if (strcmp(child, ".") == 0 || strcmp(child, "..") == 0)36{37/* Won't work: the result will be relative. */38return NULL;39}40
41*slashPos = 0;42if (makePathAbsRec(pathBuff, resolved_))43{44strcat(resolved_, "/");45strcat(resolved_, child);46return resolved_;47}48
49return NULL;50}
51
52char* shellEscapeStr(const char* str_, char* buff_)53{
54char* out = buff_;55int hasSpace = strchr(str_, ' ') != NULL;56
57if (hasSpace)58{59*out++ = '\\';60*out++ = '\"';61}62
63while (*str_)64{65switch (*str_)66{67case '\\':68case '\"':69case '\t':70*out++ = '\\';71*out++ = *str_++;72break;73
74default:75*out++ = *str_++;76break;77}78}79
80if (hasSpace)81{82*out++ = '\\';83*out++ = '\"';84}85
86*out = '\0';87return buff_;88}
89
90char* loggerMakePathAbs(const char* path_, char* resolved_, int mustExist_)91{
92assert(resolved_ && "resolved_ must be not NULL!");93
94if (!path_ || path_[0] == '\0')95{96return NULL;97}98
99if (mustExist_ && access(path_, F_OK) != 0)100{101return NULL;102}103
104if (path_[0] != '/')105{106/* This is a relative path, prepend the current working dir */107char newPath[PATH_MAX];108if (!getcwd(newPath, PATH_MAX))109{110return NULL;111}112
113strcat(newPath, "/");114strcat(newPath, path_);115return makePathAbsRec(newPath, resolved_);116}117
118return makePathAbsRec(path_, resolved_);119}
120
121LoggerVector* loggerVectorInit(LoggerVector* vec_)122{
123return loggerVectorInitAdv(vec_, 10, &free);124}
125
126LoggerVector* loggerVectorInitAdv(127LoggerVector* vec_,128size_t cap_,129LoggerFreeFuc freeFunc_)130{
131assert(vec_ && "vec_ must be not NULL");132
133vec_->size = 0;134vec_->capacity = cap_;135vec_->dataFree = freeFunc_;136
137if (cap_ > 0)138{139vec_->data = (void**) malloc(sizeof(void*) * cap_);140if (!vec_->data)141{142return NULL;143}144}145else146{147vec_->data = NULL;148}149
150return vec_;151}
152
153void loggerVectorClear(LoggerVector* vec_)154{
155assert(vec_ && "vec_ must be not NULL");156
157if (vec_->data)158{159if (vec_->dataFree)160{161size_t i;162for (i = 0; i < vec_->size; ++i)163{164vec_->dataFree(vec_->data[i]);165}166}167
168free(vec_->data);169
170vec_->data = NULL;171vec_->capacity = 0;172vec_->size = 0;173}174}
175
176int loggerVectorAddFrom(177LoggerVector* vec_,178const LoggerVector* source_,179const size_t* position_,180LoggerDupFuc dup_)181{
182size_t i;183size_t reqCap;184size_t insPos;185
186assert(vec_ && "vec_ must be not NULL");187assert(source_ && "source_ must be not NULL");188assert(dup_ && "dup_ must be not NULL");189assert((!position_ || *position_ <= vec_->size) && "position_ is out of range!");190
191reqCap = vec_->size + source_->size;192
193if (position_)194{195insPos = *position_;196}197else198{199insPos = vec_->size;200}201
202if (vec_->capacity < reqCap)203{204void** newData = (void**) realloc(vec_->data, sizeof(void*) * reqCap);205if (!newData)206{207return 0;208}209
210vec_->data = newData;211vec_->capacity = reqCap;212}213
214if (insPos < vec_->size)215{216/* Move items to the end of the vector */217for (i = vec_->size - 1; i >= insPos; --i)218{219vec_->data[i + source_->size] = vec_->data[i];220vec_->data[i] = NULL;221}222}223
224for (i = 0; i < source_->size; ++i)225{226vec_->data[i + insPos] = dup_(source_->data[i]);227}228
229vec_->size += source_->size;230return 1;231}
232
233int loggerVectorAdd(LoggerVector* vec_, void* data_)234{
235assert(vec_ && "vec_ must be not NULL");236
237if (!data_)238{239return 0;240}241
242if (vec_->size == vec_->capacity)243{244size_t newCap = vec_->capacity ? vec_->capacity * 2 : 10;245void** newData = (void**) realloc(vec_->data, sizeof(void*) * newCap);246if (!newData)247{248return 0;249}250
251vec_->data = newData;252vec_->capacity = newCap;253}254
255vec_->data[vec_->size] = data_;256vec_->size += 1;257
258return 1;259}
260
261int loggerVectorAddUnique(LoggerVector* vec_, void* data_, LoggerCmpFuc cmp_)262{
263if (loggerVectorFind(vec_, data_, cmp_) != SIZE_MAX)264{265if (vec_->dataFree)266{267vec_->dataFree(data_);268}269
270return 2;271}272
273return loggerVectorAdd(vec_, data_);274}
275
276size_t loggerVectorFind(277LoggerVector* vec_,278const void* data_,279LoggerCmpFuc cmp_)280{
281size_t i;282for (i = 0; i < vec_->size; ++i)283{284if (cmp_(data_, vec_->data[i]) == 0)285{286return i;287}288}289
290return SIZE_MAX;291}
292
293void loggerVectorErase(LoggerVector* vec_, size_t index_)294{
295size_t i;296
297if (index_ >= vec_->size)298{299return;300}301
302if (vec_->dataFree)303{304vec_->dataFree(vec_->data[index_]);305}306
307for (i = index_ + 1; i < vec_->size; ++i)308{309vec_->data[i-1] = vec_->data[i];310}311
312vec_->size -= 1;313}
314
315char* loggerStrDup(const char* str_)316{
317return loggerStrNDup(str_, strlen(str_));318}
319
320char* loggerStrNDup(const char* str_, size_t n_)321{
322char* dup;323size_t len = strlen(str_);324if (len > n_)325{326len = n_;327}328
329dup = malloc(sizeof(char) * (len + 1));330if (!dup)331{332return NULL;333}334
335memcpy(dup, str_, sizeof(char) * len);336
337dup[len] = 0;338return dup;339}
340
341char* loggerGetFileExt(const char* path_, int tolower_)342{
343size_t i;344size_t size;345const char* ext;346char* fname = loggerGetFileName(path_, 0);347if (!fname)348{349return NULL;350}351
352ext = strrchr(fname, '.');353if (!ext)354{355free(fname);356return NULL;357}358
359++ext;360size = strlen(ext) + 1;361for (i = 0; i < size; ++i)362{363if (tolower_)364{365fname[i] = tolower(ext[i]);366}367else368{369fname[i] = ext[i];370}371}372
373return fname;374}
375
376char* loggerGetFileDir(const char* absPath_)377{
378const char* slashPos = strrchr(absPath_, '/');379if (slashPos == absPath_)380{381return loggerStrDup("/");382}383else if (slashPos)384{385return loggerStrNDup(absPath_, slashPos - absPath_);386}387
388return NULL;389}
390
391char* loggerGetFilePathWithoutExt(const char* absPath_)392{
393const char* extpos = strrchr(absPath_, '.');394if (extpos)395{396return loggerStrNDup(absPath_, extpos - absPath_);397}398
399return loggerStrDup(absPath_);400}
401
402char* loggerGetFileName(const char* absPath_, int withoutExt_)403{
404const char* fileName = strrchr(absPath_, '/');405if (!fileName || fileName[1] == 0)406{407return NULL;408}409
410++fileName;411if (withoutExt_)412{413const char* extpos = strrchr(fileName, '.');414if (extpos)415{416return loggerStrNDup(fileName, extpos - fileName);417}418}419
420return loggerStrDup(fileName);421}
422