4 * Date: Fri Apr 9 19:45:00 2010
6 * GNU recutils - Miscellanea utilities
10 /* Copyright (C) 2010-2019 Jose E. Marchesi */
12 /* This program is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation, either version 3 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program. If not, see <http://www.gnu.org/licenses/>.
31 #define _(str) dgettext (PACKAGE, str)
35 #include <rec-utils.h>
38 rec_atoi (const char *str
,
48 li
= strtol (str
, &end
, base
);
49 if ((*str
!= '\0') && (*end
== '\0'))
51 /* The entire string is valid. */
60 rec_atod (const char *str
,
68 setlocale (LC_NUMERIC
, "C"); /* We want the dot to always be the
70 *number
= strtod (str
, &end
);
71 setlocale (LC_NUMERIC
, ""); /* Restore the locale from the
74 if ((*str
!= '\0') && (*end
== '\0'))
76 /* The entire string is valid. */
84 rec_extract_file (const char *str
)
88 char *rec_file
= NULL
;
89 size_t rec_file_length
= 0;
91 if (regcomp (®exp
, "[ \n\t]" REC_FILE_REGEXP
, REG_EXTENDED
) != 0)
93 fprintf (stderr
, _("internal error: rec_int_rec_extract_file: error compiling regexp.\n"));
97 if ((regexec (®exp
, str
, 1, &matches
, 0) == 0)
98 && (matches
.rm_so
!= -1))
101 rec_file_length
= matches
.rm_eo
- matches
.rm_so
;
102 rec_file
= malloc (rec_file_length
+ 1);
103 memcpy (rec_file
, str
+ matches
.rm_so
+ 1, rec_file_length
- 1);
104 rec_file
[rec_file_length
- 1] = '\0';
112 rec_extract_url (const char *str
)
116 char *rec_url
= NULL
;
117 size_t rec_url_length
= 0;
119 if (regcomp (®exp
, REC_URL_REGEXP
, REG_EXTENDED
) != 0)
121 fprintf (stderr
, _("internal error: rec_int_rec_extract_url: error compiling regexp.\n"));
125 if ((regexec (®exp
, str
, 1, &matches
, 0) == 0)
126 && (matches
.rm_so
!= -1))
129 rec_url_length
= matches
.rm_eo
- matches
.rm_so
;
130 rec_url
= malloc (rec_url_length
+ 1);
131 memcpy (rec_url
, str
+ matches
.rm_so
, rec_url_length
);
132 rec_url
[rec_url_length
] = '\0';
140 rec_extract_type (const char *str
)
144 char *rec_type
= NULL
;
145 size_t rec_type_length
= 0;
147 /* TODO: use a REC_TYPE_NAME_RE */
148 if (regcomp (®exp
, REC_FNAME_RE
, REG_EXTENDED
) != 0)
150 fprintf (stderr
, _("internal error: rec_int_rec_extract_url: error compiling regexp.\n"));
154 if ((regexec (®exp
, str
, 1, &matches
, 0) == 0)
155 && (matches
.rm_so
!= -1))
158 rec_type_length
= matches
.rm_eo
- matches
.rm_so
;
159 rec_type
= malloc (rec_type_length
+ 1);
160 memcpy (rec_type
, str
+ matches
.rm_so
, rec_type_length
);
161 rec_type
[rec_type_length
] = '\0';
169 rec_parse_int (const char **str
, int *num
)
179 while (rec_digit_p (*p
)
180 || ((p
== b
) && (*p
== '-'))
181 || ((*p
>= 'a') && (*p
<= 'f'))
182 || ((*p
>= 'A') && (*p
<= 'F'))
189 number
[p
- b
] = '\0';
191 if (!rec_atoi (number
, num
))
205 rec_parse_regexp (const char **str
, const char *re
, char **result
)
215 /* Compile the regexp. */
216 if (regcomp (®exp
, re
, REG_EXTENDED
) != 0)
223 /* Try to match the regexp. */
224 if (regexec (®exp
, p
, 1, &pm
, 0) == 0)
228 /* Get the match into 'result'. Note that
229 since the pattern starts with a ^ rm_so shall be 0 and we
230 can use rm_eo relative to *p. */
231 *result
= malloc (pm
.rm_eo
+ 1);
232 memcpy (*result
, p
, pm
.rm_eo
);
233 (*result
)[pm
.rm_eo
] = '\0';
260 rec_skip_blanks (const char **str
)
265 while (rec_blank_p (*p
))
284 return ((c
>= '0') && (c
<= '9'));
288 rec_letter_p (char c
)
290 return (((c
>= 'a') && (c
<= 'z'))
291 || ((c
>= 'A') && (c
<= 'Z')));
295 rec_match_int (const char *str
,
302 if (regcomp (®exp
, reg
, flags
) != 0)
304 fprintf (stderr
, _("internal error: rec_match: error compiling regexp.\n"));
308 ret
= (regexec (®exp
, str
, 0, NULL
, 0) == 0);
315 rec_match (const char *str
,
318 return rec_match_int (str
, reg
, REG_EXTENDED
);
322 rec_match_insensitive (const char *str
,
325 return rec_match_int (str
, reg
, REG_EXTENDED
| REG_ICASE
);
329 rec_extract_size (const char *str
)
335 if (!rec_match (str
, REC_INT_SIZE_RE
))
341 rec_skip_blanks (&p
);
342 rec_parse_regexp (&p
, "^[><]=?", &condition_str
);
343 rec_skip_blanks (&p
);
344 rec_parse_int (&p
, &res
);
349 enum rec_size_condition_e
350 rec_extract_size_condition (const char *str
)
353 char *condition_str
= NULL
;
354 enum rec_size_condition_e condition
;
356 if (!rec_match (str
, REC_INT_SIZE_RE
))
362 rec_skip_blanks (&p
);
363 rec_parse_regexp (&p
, "^[><]=?", &condition_str
);
367 if (strcmp (condition_str
, ">") == 0)
369 condition
= SIZE_COND_G
;
371 else if (strcmp (condition_str
, ">=") == 0)
373 condition
= SIZE_COND_GE
;
375 else if (strcmp (condition_str
, "<") == 0)
377 condition
= SIZE_COND_L
;
379 else if (strcmp (condition_str
, "<=") == 0)
381 condition
= SIZE_COND_LE
;
385 fprintf (stderr
, "internal error: rec_extract_size_condition: invalid condition.\n");
389 free (condition_str
);
393 condition
= SIZE_COND_E
;
400 rec_timespec_subtract (struct timespec
*result
,
404 result
->tv_sec
= x
->tv_sec
- y
->tv_sec
;
405 result
->tv_nsec
= x
->tv_nsec
- y
->tv_nsec
;
406 if (result
->tv_nsec
< 0)
408 /* Overflow. Subtract one second. */
410 result
->tv_nsec
+= 1000000000;
413 /* Return whether there is an overflow in the 'tv_sec' field. */
414 return (result
->tv_sec
< 0);
418 rec_endian_swap (uint32_t number
)
423 | ((number
<< 8) & 0x00FF0000)
424 | ((number
>> 8) & 0x0000FF00)
431 rec_concat_strings (const char *str1
,
435 char *res
= malloc (strlen (str1
) + strlen (str2
) + strlen (str3
) + 1);
439 memcpy (res
, str1
, strlen (str1
));
440 memcpy (res
+ strlen (str1
), str2
, strlen (str2
));
441 memcpy (res
+ strlen (str1
) + strlen (str2
), str3
, strlen (str3
) + 1);
447 /* End of rec-utils.c */