blob: 37981af362de185ed327afbc5c8b6b8dd035e307 [file] [log] [blame]
James Kuszmaul82f6c042021-01-17 11:30:16 -08001/**
2 * @file fmt/str.c String format functions
3 *
4 * Copyright (C) 2010 Creytiv.com
5 */
6#undef __STRICT_ANSI__ /* for mingw32 */
7#include <string.h>
8#ifdef HAVE_STRINGS_H
9#include <strings.h>
10#endif
11#include <re_types.h>
12#include <re_mem.h>
13#include <re_fmt.h>
14
15
16/**
17 * Convert a ascii hex string to binary format
18 *
19 * @param hex Destinatin binary buffer
20 * @param len Length of binary buffer
21 * @param str Source ascii string
22 *
23 * @return 0 if success, otherwise errorcode
24 */
25int str_hex(uint8_t *hex, size_t len, const char *str)
26{
27 size_t i;
28
29 if (!hex || !str || (strlen(str) != (2 * len)))
30 return EINVAL;
31
32 for (i=0; i<len*2; i+=2) {
33 hex[i/2] = ch_hex(str[i]) << 4;
34 hex[i/2] += ch_hex(str[i+1]);
35 }
36
37 return 0;
38}
39
40
41/**
42 * Copy a 0-terminated string with maximum length
43 *
44 * @param dst Destinatin string
45 * @param src Source string
46 * @param n Maximum size of destination, including 0-terminator
47 */
48void str_ncpy(char *dst, const char *src, size_t n)
49{
50 if (!dst || !src || !n)
51 return;
52
53 (void)strncpy(dst, src, n-1);
54 dst[n-1] = '\0'; /* strncpy does not null terminate if overflow */
55}
56
57
58/**
59 * Duplicate a 0-terminated string
60 *
61 * @param dst Pointer to destination string (set on return)
62 * @param src Source string
63 *
64 * @return 0 if success, otherwise errorcode
65 */
66int str_dup(char **dst, const char *src)
67{
68 char *p;
69 size_t sz;
70
71 if (!dst || !src)
72 return EINVAL;
73
74 sz = strlen(src) + 1;
75
76 p = mem_alloc(sz, NULL);
77 if (!p)
78 return ENOMEM;
79
80 memcpy(p, src, sz);
81
82 *dst = p;
83
84 return 0;
85}
86
87
88/**
89 * Compare two 0-terminated strings
90 *
91 * @param s1 First string
92 * @param s2 Second string
93 *
94 * @return an integer less than, equal to, or greater than zero if s1 is found
95 * respectively, to be less than, to match, or be greater than s2
96 */
97int str_cmp(const char *s1, const char *s2)
98{
99 if (!s1 || !s2)
100 return 1;
101
102 return strcmp(s1, s2);
103}
104
105
106/**
107 * Compare two 0-terminated strings, ignoring case
108 *
109 * @param s1 First string
110 * @param s2 Second string
111 *
112 * @return an integer less than, equal to, or greater than zero if s1 is found
113 * respectively, to be less than, to match, or be greater than s2
114 */
115int str_casecmp(const char *s1, const char *s2)
116{
117 /* Same strings -> equal */
118 if (s1 == s2)
119 return 0;
120
121 if (!s1 || !s2)
122 return 1;
123
124#ifdef WIN32
125 return _stricmp(s1, s2);
126#else
127 return strcasecmp(s1, s2);
128#endif
129}
130
131
132/**
133 * Calculate the length of a string, safe version.
134 *
135 * @param s String
136 *
137 * @return Length of the string
138 */
139size_t str_len(const char *s)
140{
141 return s ? strlen(s) : 0;
142}