CodeCompass

Форк
0
/
ldlogger-util.c 
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

11
static char* makePathAbsRec(const char* path_, char* resolved_)
12
{
13
  char pathBuff[PATH_MAX];
14
  char* slashPos;
15
  char* child;
16

17
  if (realpath(path_, pathBuff))
18
  {
19
    pathBuff[PATH_MAX - 1] = 0;
20
    return strcpy(resolved_, pathBuff);
21
  }
22
  else
23
  {
24
    strcpy(pathBuff, path_);
25
  }
26

27
  /* cut off the last part */
28
  slashPos = strrchr(pathBuff, '/');
29
  if (!slashPos || slashPos == path_)
30
  {
31
    return NULL;
32
  }
33

34
  child = slashPos + 1;
35
  if (strcmp(child, ".") == 0 || strcmp(child, "..") == 0)
36
  {
37
    /* Won't work: the result will be relative. */
38
    return NULL;
39
  }
40

41
  *slashPos = 0;
42
  if (makePathAbsRec(pathBuff, resolved_))
43
  {
44
    strcat(resolved_, "/");
45
    strcat(resolved_, child);
46
    return resolved_;
47
  }
48

49
  return NULL;
50
}
51

52
char* shellEscapeStr(const char* str_, char* buff_)
53
{
54
  char* out = buff_;
55
  int hasSpace = strchr(str_, ' ') != NULL;
56

57
  if (hasSpace)
58
  {
59
    *out++ = '\\';
60
    *out++ = '\"';
61
  }
62

63
  while (*str_)
64
  {
65
    switch (*str_)
66
    {
67
      case '\\':
68
      case '\"':
69
      case '\t':
70
        *out++ = '\\';
71
        *out++ = *str_++;
72
        break;
73

74
      default:
75
        *out++ = *str_++;
76
        break;
77
    }
78
  }
79

80
  if (hasSpace)
81
  {
82
    *out++ = '\\';
83
    *out++ = '\"';
84
  }
85

86
  *out = '\0';
87
  return buff_;
88
}
89

90
char* loggerMakePathAbs(const char* path_, char* resolved_, int mustExist_)
91
{
92
  assert(resolved_ && "resolved_ must be not NULL!");
93

94
  if (!path_ || path_[0] == '\0')
95
  {
96
    return NULL;
97
  }
98

99
  if (mustExist_ && access(path_, F_OK) != 0)
100
  {
101
    return NULL;
102
  }
103

104
  if (path_[0] != '/')
105
  {
106
    /* This is a relative path, prepend the current working dir */
107
    char newPath[PATH_MAX];
108
    if (!getcwd(newPath, PATH_MAX))
109
    {
110
      return NULL;
111
    }
112

113
    strcat(newPath, "/");
114
    strcat(newPath, path_);
115
    return makePathAbsRec(newPath, resolved_);
116
  }
117

118
  return makePathAbsRec(path_, resolved_);
119
}
120

121
LoggerVector* loggerVectorInit(LoggerVector* vec_)
122
{
123
  return loggerVectorInitAdv(vec_, 10, &free);
124
}
125

126
LoggerVector* loggerVectorInitAdv(
127
  LoggerVector* vec_,
128
  size_t cap_,
129
  LoggerFreeFuc freeFunc_)
130
{
131
  assert(vec_ && "vec_ must be not NULL");
132

133
  vec_->size = 0;
134
  vec_->capacity = cap_;
135
  vec_->dataFree = freeFunc_;
136

137
  if (cap_ > 0)
138
  {
139
    vec_->data = (void**) malloc(sizeof(void*) * cap_);
140
    if (!vec_->data)
141
    {
142
      return NULL;
143
    }
144
  }
145
  else
146
  {
147
    vec_->data = NULL;
148
  }
149

150
  return vec_;
151
}
152

153
void loggerVectorClear(LoggerVector* vec_)
154
{
155
  assert(vec_ && "vec_ must be not NULL");
156

157
  if (vec_->data)
158
  {
159
    if (vec_->dataFree)
160
    {
161
      size_t i;
162
      for (i = 0; i < vec_->size; ++i)
163
      {
164
        vec_->dataFree(vec_->data[i]);
165
      }
166
    }
167

168
    free(vec_->data);
169

170
    vec_->data = NULL;
171
    vec_->capacity = 0;
172
    vec_->size = 0;
173
  }
174
}
175

176
int loggerVectorAddFrom(
177
  LoggerVector* vec_,
178
  const LoggerVector* source_,
179
  const size_t* position_,
180
  LoggerDupFuc dup_)
181
{
182
  size_t i;
183
  size_t reqCap;
184
  size_t insPos;
185

186
  assert(vec_ && "vec_ must be not NULL");
187
  assert(source_ && "source_ must be not NULL");
188
  assert(dup_ && "dup_ must be not NULL");
189
  assert((!position_ || *position_ <= vec_->size) && "position_ is out of range!");
190

191
  reqCap = vec_->size + source_->size;
192

193
  if (position_)
194
  {
195
    insPos = *position_;
196
  }
197
  else
198
  {
199
    insPos = vec_->size;
200
  }
201

202
  if (vec_->capacity < reqCap)
203
  {
204
    void** newData = (void**) realloc(vec_->data, sizeof(void*) * reqCap);
205
    if (!newData)
206
    {
207
      return 0;
208
    }
209

210
    vec_->data = newData;
211
    vec_->capacity = reqCap;
212
  }
213

214
  if (insPos < vec_->size)
215
  {
216
    /* Move items to the end of the vector */
217
    for (i = vec_->size - 1; i >= insPos; --i)
218
    {
219
      vec_->data[i + source_->size] = vec_->data[i];
220
      vec_->data[i] = NULL;
221
    }
222
  }
223

224
  for (i = 0; i < source_->size; ++i)
225
  {
226
    vec_->data[i + insPos] = dup_(source_->data[i]);
227
  }
228

229
  vec_->size += source_->size;
230
  return 1;
231
}
232

233
int loggerVectorAdd(LoggerVector* vec_, void* data_)
234
{
235
  assert(vec_ && "vec_ must be not NULL");
236

237
  if (!data_)
238
  {
239
    return 0;
240
  }
241

242
  if (vec_->size == vec_->capacity)
243
  {
244
    size_t newCap = vec_->capacity ? vec_->capacity * 2 : 10;
245
    void** newData = (void**) realloc(vec_->data, sizeof(void*) * newCap);
246
    if (!newData)
247
    {
248
      return 0;
249
    }
250

251
    vec_->data = newData;
252
    vec_->capacity = newCap;
253
  }
254

255
  vec_->data[vec_->size] = data_;
256
  vec_->size += 1;
257

258
  return 1;
259
}
260

261
int loggerVectorAddUnique(LoggerVector* vec_, void* data_, LoggerCmpFuc cmp_)
262
{
263
  if (loggerVectorFind(vec_, data_, cmp_) != SIZE_MAX)
264
  {
265
    if (vec_->dataFree)
266
    {
267
      vec_->dataFree(data_);
268
    }
269

270
    return 2;
271
  }
272

273
  return loggerVectorAdd(vec_, data_);
274
}
275

276
size_t loggerVectorFind(
277
  LoggerVector* vec_,
278
  const void* data_,
279
  LoggerCmpFuc cmp_)
280
{
281
  size_t i;
282
  for (i = 0; i < vec_->size; ++i)
283
  {
284
    if (cmp_(data_, vec_->data[i]) == 0)
285
    {
286
      return i;
287
    }
288
  }
289

290
  return SIZE_MAX;
291
}
292

293
void loggerVectorErase(LoggerVector* vec_, size_t index_)
294
{
295
  size_t i;
296

297
  if (index_ >= vec_->size)
298
  {
299
    return;
300
  }
301

302
  if (vec_->dataFree)
303
  {
304
    vec_->dataFree(vec_->data[index_]);
305
  }
306

307
  for (i = index_ + 1; i < vec_->size; ++i)
308
  {
309
    vec_->data[i-1] = vec_->data[i];
310
  }
311

312
  vec_->size -= 1;
313
}
314

315
char* loggerStrDup(const char* str_)
316
{
317
  return loggerStrNDup(str_, strlen(str_));
318
}
319

320
char* loggerStrNDup(const char* str_, size_t n_)
321
{
322
  char* dup;
323
  size_t len = strlen(str_);
324
  if (len > n_)
325
  {
326
    len = n_;
327
  }
328

329
  dup = malloc(sizeof(char) * (len + 1));
330
  if (!dup)
331
  {
332
    return NULL;
333
  }
334

335
  memcpy(dup, str_, sizeof(char) * len);
336

337
  dup[len] = 0;
338
  return dup;
339
}
340

341
char* loggerGetFileExt(const char* path_, int tolower_)
342
{
343
  size_t i;
344
  size_t size;
345
  const char* ext;
346
  char* fname = loggerGetFileName(path_, 0);
347
  if (!fname)
348
  {
349
    return NULL;
350
  }
351

352
  ext = strrchr(fname, '.');
353
  if (!ext)
354
  {
355
    free(fname);
356
    return NULL;
357
  }
358

359
  ++ext;
360
  size = strlen(ext) + 1;
361
  for (i = 0; i < size; ++i)
362
  {
363
    if (tolower_)
364
    {
365
      fname[i] = tolower(ext[i]);
366
    }
367
    else
368
    {
369
      fname[i] = ext[i];
370
    }
371
  }
372

373
  return fname;
374
}
375

376
char* loggerGetFileDir(const char* absPath_)
377
{
378
  const char* slashPos = strrchr(absPath_, '/');
379
  if (slashPos == absPath_)
380
  {
381
    return loggerStrDup("/");
382
  }
383
  else if (slashPos)
384
  {
385
    return loggerStrNDup(absPath_,  slashPos - absPath_);
386
  }
387

388
  return NULL;
389
}
390

391
char* loggerGetFilePathWithoutExt(const char* absPath_)
392
{
393
  const char* extpos = strrchr(absPath_, '.');
394
  if (extpos)
395
  {
396
    return loggerStrNDup(absPath_, extpos - absPath_);
397
  }
398

399
  return loggerStrDup(absPath_);
400
}
401

402
char* loggerGetFileName(const char* absPath_, int withoutExt_)
403
{
404
  const char* fileName = strrchr(absPath_, '/');
405
  if (!fileName || fileName[1] == 0)
406
  {
407
    return NULL;
408
  }
409

410
  ++fileName;
411
  if (withoutExt_)
412
  {
413
    const char* extpos = strrchr(fileName, '.');
414
    if (extpos)
415
    {
416
      return loggerStrNDup(fileName, extpos - fileName);
417
    }
418
  }
419

420
  return loggerStrDup(fileName);
421
}
422

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.