1 /*
2  * marker-string.c
3  *
4  * Copyright (C) 2017 - 2018 Fabio Colacio
5  *
6  * Marker is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public License as
8  * published by the Free Software Foundation; either version 3 of the
9  * License, or (at your option) any later version.
10  *
11  * Marker 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 GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with Marker; see the file LICENSE.md. If not,
18  * see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #include <string.h>
23 #include <stdlib.h>
24 #include <stdio.h>
25 
26 #include "marker-string.h"
27 
28 int
marker_string_ends_with(const char * str,const char * sub_str)29 marker_string_ends_with(const char* str,
30                         const char* sub_str)
31 {
32   size_t str_len = strlen(str);
33   size_t sub_len = strlen(sub_str);
34   if (strcmp(sub_str, &str[str_len - sub_len]) == 0)
35   {
36     return 1;
37   }
38   return 0;
39 }
40 
41 int
marker_string_contains(const char * str,const char * sub_str)42 marker_string_contains(const char   *str,
43                        const char   *sub_str)
44 {
45   return strstr(str, sub_str) != NULL;
46 }
47 
48 char*
marker_string_alloc(const char * str)49 marker_string_alloc(const char* str)
50 {
51   size_t len = strlen(str) + 1;
52   char* new_str = (char*) malloc(len);
53   memcpy(new_str, str, len);
54   return new_str;
55 }
56 
57 char*
marker_string_prepend(const char * str,const char * addition,char * buffer,size_t buffer_size)58 marker_string_prepend(const char* str,
59                       const char* addition,
60                       char*       buffer,
61                       size_t      buffer_size)
62 {
63   size_t str_len = strlen(str);
64   size_t add_len = strlen(addition);
65   size_t len = str_len + add_len + 1;
66 
67 
68   if (buffer)
69   {
70     size_t bf = buffer_size;
71     memset(buffer, 0, buffer_size);
72 
73     if (add_len <= bf)
74     {
75       memcpy(buffer, addition, add_len);
76       bf -= add_len;
77 
78       if (str_len <= bf)
79       {
80         memcpy(&buffer[add_len], str, str_len + 1);
81       }
82       else
83       {
84         memcpy(&buffer[str_len], str, bf);
85         buffer[buffer_size - 1] = '\0';
86       }
87     }
88     else
89     {
90       memcpy(&buffer[str_len], str, bf);
91       buffer[buffer_size - 1] = '\0';
92     }
93     return NULL;
94   }
95 
96   char* new_str = malloc(len);
97   memset(new_str, 0, len);
98   strcat(new_str, addition);
99   strcat(new_str, str);
100   return new_str;
101 }
102 
103 char*
marker_string_append(const char * str,const char * addition,char * buffer,size_t buffer_size)104 marker_string_append(const char* str,
105                      const char* addition,
106                      char*       buffer,
107                      size_t      buffer_size)
108 {
109   return marker_string_prepend(addition, str, buffer, buffer_size);
110 }
111 
112 int
marker_string_buffer_set(const char * str,char * buffer,size_t buffer_size)113 marker_string_buffer_set(const char* str,
114                          char*       buffer,
115                          size_t      buffer_size)
116 {
117   size_t str_len = strlen(str);
118   if (str_len >= buffer_size)
119   {
120     memset(buffer, 0, buffer_size);
121     memcpy(buffer, str, buffer_size);
122     buffer[buffer_size - 1] = '\0';
123     return 1;
124   }
125   memcpy(buffer, str, str_len + 1);
126   return 0;
127 }
128 
129 char*
marker_string_escape(const char * str)130 marker_string_escape(const char* str)
131 {
132   size_t len = strlen(str);
133 
134   size_t tmplen = len * 2;
135   char* buffer = (char*) malloc(tmplen + 1);
136   memset(buffer, 0, tmplen + 1);
137 
138   for(int i = 0, j = 0; i < len; ++i)
139   {
140     char c = str[i];
141     if (c == ' ')
142     {
143       buffer[j++] = '\\';
144     }
145     buffer[j++] = c;
146   }
147 
148   size_t str_len = strlen(buffer);
149   if (str_len < tmplen)
150   {
151     buffer = (char*) realloc(buffer, str_len);
152   }
153 
154   return buffer;
155 }
156 
157 char*
marker_string_filename_get_name(const char * filename)158 marker_string_filename_get_name(const char* filename)
159 {
160   size_t len = strlen(filename);
161   const char* last_slash = filename;
162   for (int i = 0; i < len; ++i)
163   {
164     if (filename[i] == '/')
165     {
166       last_slash = &filename[i + 1];
167     }
168   }
169   len = &filename[len] - last_slash;
170   char* ret = (char*) malloc(len + 1);
171   memset(ret, 0, len + 1);
172   memcpy(ret, last_slash, len);
173   return ret;
174 }
175 
176 char*
marker_string_filename_get_name_noext(const char * filename)177 marker_string_filename_get_name_noext(const char* filename)
178 {
179   char* name = marker_string_filename_get_name(filename);
180   size_t len = strlen(name);
181   for (int i = len; i > 0; --i){
182     if (filename[i] == '.')
183     {
184       char *ret = (char*) malloc(i+1);
185       memset(ret, 0, i+1);
186       memcpy(ret, filename, i);
187       return ret;
188     }
189   }
190   return name;
191 }
192 
193 char*
marker_string_filename_get_path(const char * filename)194 marker_string_filename_get_path(const char* filename)
195 {
196   size_t len = strlen(filename);
197   const char* last_slash = filename;
198   for (int i = 0; i < len; ++i)
199   {
200     if (filename[i] == '/')
201     {
202       last_slash = &filename[i];
203     }
204   }
205   len = last_slash - filename;
206   char* ret = (char*) malloc(len + 1);
207   memset(ret, 0, len + 1);
208   memcpy(ret, filename, len);
209   return ret;
210 }
211 
212