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