1 /*********************************************************
2 * cc90hfe (c) Teo Developers
3 *********************************************************
4 *
5 * Copyright (C) 2012-2017 Fran�ois Mouret
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22 /*
23 * Module : std.c
24 * Version : 0.7.0
25 * Cr�� par : Fran�ois Mouret 27/02/2013
26 * Modifi� par:
27 *
28 * Utility functions.
29 */
30
31
32 #ifndef SCAN_DEPEND
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <ctype.h>
37 #include <sys/stat.h>
38 #include <unistd.h>
39 #include <stdarg.h>
40 #endif
41
42 #include "defs.h"
43 #include "main.h"
44 #include "std.h"
45
46
47
48 /* std_StringListLast:
49 * Renvoit le pointeur sur le dernier �l�ment de la stringlist.
50 */
std_StringListLast(struct STRING_LIST * p)51 static struct STRING_LIST *std_StringListLast (struct STRING_LIST *p)
52 {
53 while ((p!=NULL) && (p->next!=NULL))
54 p=p->next;
55
56 return p;
57 }
58
59
60
61 /* std_strdup_sprintf_add:
62 * Concatenate two strings.
63 *
64 * String memory is dynamically allocated.
65 * Must be MSDOS compatible.
66 * Return pointer to the concatenated string.
67 */
std_strdup_printf_add(char * p0,char * p1,int length)68 static char *std_strdup_printf_add (char *p0, char *p1, int length)
69 {
70 char *p = NULL;
71 int size;
72
73 if ((p0 != NULL) && (p1 != NULL))
74 {
75 size = strlen (p0);
76 p = calloc (1, size+length+1);
77 if (p != NULL)
78 {
79 strcpy (p, p0);
80 strncat (p, p1, length);
81 }
82 free (p0);
83 }
84 return p;
85 }
86
87
88
89 /* std_strdup_printf_run:
90 * Strings concatenation.
91 *
92 * String memory is dynamically allocated.
93 * Must be MSDOS compatible, that's why vsnprintf isn't used.
94 * Only for char*, char, and int.
95 */
std_strdup_printf_run(char * fmt,va_list ap)96 static char *std_strdup_printf_run (char *fmt, va_list ap)
97 {
98 int i;
99 int d;
100 char c;
101 char *s;
102 char *buf = calloc(1,33);
103 char *ptr = calloc(1,1);
104 char fill_char = '\0';
105 char fill_size = 0;
106 char *fmt_tmp = calloc(1,33);
107
108 while ((ptr != NULL)
109 && (buf != NULL)
110 && (fmt != NULL)
111 && (*fmt != '\0')
112 && ((ptr = std_strdup_printf_add(ptr, fmt, strcspn (fmt, "%"))) != NULL))
113 {
114 fmt += strcspn (fmt, "%");
115 if (*fmt == '%')
116 {
117 fmt++;
118
119 if ((*(fmt) == '0') || (*(fmt) == ' '))
120 {
121 fill_char = *fmt;
122 fmt++;
123 }
124
125 if ((*(fmt) >= '1') && (*(fmt) <= '9'))
126 fill_size = (int)strtol (fmt, &fmt, 0);
127
128 switch (*fmt)
129 {
130 /* Cha�ne */
131 case 's': s = va_arg (ap, char *);
132 ptr = std_strdup_printf_add(ptr, s, (s)?strlen(s):0);
133 break;
134
135 /* Entier */
136 case 'd': d = va_arg (ap, int);
137 sprintf (fmt_tmp, "%%d");
138 if (fill_size != 0)
139 {
140 if (fill_char != '\0')
141 sprintf (fmt_tmp, "%%%c%dd", fill_char, fill_size);
142 else
143 sprintf (fmt_tmp, "%%%dd", fill_size);
144 }
145 i = sprintf (buf, fmt_tmp, d);
146
147 ptr = std_strdup_printf_add(ptr, buf, i);
148 break;
149
150 /* Caract�re, % */
151 case '%':
152 case 'c': c = va_arg (ap, int);
153 buf[0] = (char)c;
154 buf[1] = '\0';
155 ptr = std_strdup_printf_add(ptr, buf, 1);
156 break;
157
158 /* Passe */
159 default : break;
160 }
161 fill_char = '\0';
162 fill_size = 0;
163 fmt++;
164 }
165 }
166 buf = std_free (buf);
167 if (ptr == NULL)
168 ptr = calloc(1,1);
169
170 return ptr;
171 }
172
173 /* ------------------------------------------------------------------------- */
174
175
176 /* std_free:
177 * Lib�re une m�moire.
178 */
std_free(void * p)179 void *std_free (void *p)
180 {
181 if (p != NULL)
182 free (p);
183
184 return NULL;
185 }
186
187
188
189 /* std_stralloc:
190 * Alloue de la m�moire pour une cha�ne.
191 */
std_stralloc(void * p,char * s)192 void *std_stralloc (void *p, char *s)
193 {
194 p = std_free (p);
195 p = calloc (1, strlen(s)+1);
196 if (p != NULL) strcpy (p, s);
197 return p;
198 }
199
200
201
202 /* std_fclose:
203 * Referme un fichier.
204 */
std_fclose(FILE * fp)205 FILE *std_fclose (FILE *fp)
206 {
207 if (fp != NULL)
208 fclose (fp);
209 return NULL;
210 }
211
212
213
214 /* std_IsFile:
215 * V�rifie si le chemin est un fichier.
216 */
std_IsFile(const char filename[])217 int std_IsFile (const char filename[])
218 {
219 struct stat st;
220
221 return ((stat(filename, &st) == 0)
222 && (S_ISREG(st.st_mode) != 0)) ? TRUE : FALSE;
223 }
224
225
226
227 /* std_IsDir:
228 * V�rifie si le chemin est un r�pertoire.
229 */
std_IsDir(const char filename[])230 int std_IsDir (const char filename[])
231 {
232 struct stat st;
233
234 return ((stat(filename, &st) == 0)
235 && (S_ISDIR(st.st_mode) != 0)) ? TRUE : FALSE;
236 }
237
238
239
240 /* std_FileSize:
241 * Retourne la taille d'un fichier.
242 */
std_FileSize(const char filename[])243 size_t std_FileSize (const char filename[])
244 {
245 struct stat st;
246
247 return (stat(filename, &st) == 0) ? (size_t)st.st_size : 0;
248 }
249
250
251
252 /* std_rtrim:
253 * Elimine les caract�res de contr�le en fin de cha�ne.
254 */
std_rtrim(char * s)255 void std_rtrim (char *s)
256 {
257 if (s != NULL)
258 {
259 while ((unsigned char)*s >= 0x20)
260 s++;
261 *s ='\0';
262 }
263 }
264
265
266
267 /* std_skpspc:
268 * Passe les espaces dans une cha�ne.
269 */
std_skpspc(char * p)270 char *std_skpspc(char *p)
271 {
272 if (p != NULL)
273 while (((unsigned int)*p <= 0x20) && (*p!=0))
274 p++;
275 return p;
276 }
277
278
279
280 /* std_strdup_printf:
281 * Strings concatenation.
282 */
std_strdup_printf(char * fmt,...)283 char *std_strdup_printf (char *fmt, ...)
284 {
285 char *ptr = NULL;
286 va_list ap;
287
288 va_start (ap, fmt);
289 ptr = std_strdup_printf_run ((char *)fmt, ap);
290 return ptr;
291 }
292
293
294
295 /* std_snprintf:
296 * Strings concatenation.
297 */
std_snprintf(char * dest,size_t size,const char * fmt,...)298 size_t std_snprintf (char *dest, size_t size, const char *fmt, ...)
299 {
300 char *ptr = NULL;
301 va_list ap;
302
303 va_start (ap, fmt);
304 ptr = std_strdup_printf_run ((char *)fmt, ap);
305 if (ptr != NULL)
306 {
307 *dest = '\0';
308 strncat (dest, ptr, size);
309 ptr = std_free (ptr);
310 }
311 return strlen (dest);
312 }
313
314
315
316 /* std_StringListIndex:
317 * Renvoit l'index de l'�l�ment de la stringlist.
318 */
std_StringListIndex(struct STRING_LIST * p,char * str)319 int std_StringListIndex (struct STRING_LIST *p, char *str)
320 {
321 int index;
322
323 for (index=0; p!=NULL; p=p->next,index++)
324 if (p->str!=NULL)
325 if (strcmp (p->str, str) == 0)
326 break;
327 return (p==NULL)?-1:index;
328 }
329
330
331
332 /* std_StringListLength:
333 * Renvoit le nombre d'�l�ments de la stringlist.
334 */
std_StringListLength(struct STRING_LIST * p)335 int std_StringListLength (struct STRING_LIST *p)
336 {
337 int i = 0;
338
339 while (p!=NULL)
340 {
341 i++;
342 p=p->next;
343 }
344
345 return i;
346 }
347
348
349
std_ApplicationPath(const char dirname[],const char filename[])350 char *std_ApplicationPath (const char dirname[], const char filename[])
351 {
352 static char *fname = NULL;
353
354 fname = NULL;
355 #ifdef DEBIAN_BUILD
356 /* create private directory if necessary */
357 fname = std_strdup_printf ("%s/.config/%s", getenv("HOME"), dirname);
358 if (access (fname, F_OK) < 0)
359 {
360 (void)mkdir (fname, S_IRWXU);
361 }
362 /* set file path */
363 fname = std_free (fname);
364 fname = std_strdup_printf ("%s/.config/%s/%s", getenv("HOME"), dirname, filename);
365 #else
366 /* set file path */
367 fname = std_strdup_printf ("%s", filename);
368 dirname = dirname;
369 #endif
370 return fname;
371 }
372
373
374
375
376 /* std_StringListText:
377 * Renvoit le pointeur du texte de l'�l�ment de la stringlist.
378 */
std_StringListText(struct STRING_LIST * p,int index)379 char *std_StringListText (struct STRING_LIST *p, int index)
380 {
381 for (;index>0;index--)
382 if (p!=NULL)
383 p=p->next;
384 return (p!=NULL)?p->str:NULL;
385 }
386
387
388
389 /* std_StringListAppend:
390 * Ajoute un �l�ment � la stringlist.
391 */
std_StringListAppend(struct STRING_LIST * p,char * str)392 struct STRING_LIST *std_StringListAppend (struct STRING_LIST *p, char *str)
393 {
394 struct STRING_LIST *last_str = std_StringListLast (p);
395 struct STRING_LIST *new_str = NULL;
396
397 if (str != NULL)
398 {
399 new_str = calloc (1, sizeof (struct STRING_LIST));
400
401 if (new_str!=NULL)
402 new_str->str = std_strdup_printf ("%s", str);
403
404 if ((last_str!=NULL) && (last_str->str!=NULL))
405 last_str->next=new_str;
406 }
407 return (p==NULL)?new_str:p;
408 }
409
410
411
412 /* std_StringListFree:
413 * Lib�re la m�moire de la stringlist.
414 */
std_StringListFree(struct STRING_LIST * p)415 void std_StringListFree (struct STRING_LIST *p)
416 {
417 struct STRING_LIST *next;
418
419 while (p!=NULL)
420 {
421 next=p->next;
422 if (p->str!=NULL)
423 free (p->str);
424 free (p);
425 p=next;
426 }
427 }
428
429
430
431 /* std_BaseName:
432 * Retourne le nom du fichier � partir du chemin complet.
433 */
std_BaseName(char * fullname)434 char* std_BaseName(char *fullname)
435 {
436 int len = strlen(fullname);
437
438 while (--len > 0)
439 if ((fullname[len] == '\\') || (fullname[len] == '/'))
440 return fullname + len + 1;
441
442 return fullname;
443 }
444
445
446
447 /* std_LastDir:
448 * Retourne le nom du dernier r�pertoire � partir du chemin complet.
449 */
std_LastDir(char * fullname)450 char* std_LastDir(char *fullname)
451 {
452 int len = strlen(fullname);
453
454 while ((len > 0) && ((fullname[len-1] == '\\') || (fullname[len-1] == '/')))
455 fullname[--len] = '\0';
456
457 while (--len > 0)
458 if ((fullname[len] == '\\') || (fullname[len] == '/'))
459 return fullname + len + 1;
460
461 return fullname;
462 }
463
464
465
466 /* std_CleanPath:
467 * Efface le nom de fichier du chemin de fichier.
468 */
std_CleanPath(char * fname)469 void std_CleanPath (char *fname)
470 {
471 char *p;
472
473 if (fname != NULL)
474 {
475 if ((p = strrchr (fname, '\\')) == NULL)
476 p = strrchr (fname, '/');
477
478 if (p != NULL)
479 *p = '\0';
480 }
481 }
482
483