1 // (C) Copyright Vesa Karvonen 2004.
3 // Distributed under the Boost Software License, Version 1.0.
4 // (See accompanying file LICENSE.)
6 #include "checked_malloc.h"
16 str_type
str_intern(str_type str
) {
19 // We use a simple linked list to store the interned strings. This
20 // isn't meant to be an industry strength implementation!
21 typedef struct str_entry
{
22 struct str_entry
* next
;
26 static str_entry entries
= 0;
28 str_entry entry
= entries
;
29 while (entry
&& strcmp(entry
->datum
, str
))
35 entry
= checked_malloc(sizeof(struct str_entry
));
36 entry
->next
= entries
;
43 str_type
str_substr(str_type first
, str_type beyond
) {
47 const ptrdiff_t len
= beyond
- first
;
49 char* result
= checked_malloc(len
+ 1);
50 memcpy(result
, first
, len
);
53 return str_intern(result
);
56 str_type
str_cat(str_type str0
, ...) {
59 ptrdiff_t tot_len
= 0;
66 tot_len
+= strlen(stri
);
67 stri
= va_arg(args
, str_type
);
68 } while (str_end
!= stri
);
73 char* const result
= checked_malloc(tot_len
+ 1);
81 ptrdiff_t len
= strlen(stri
);
82 memcpy(dst
, stri
, len
);
84 stri
= va_arg(args
, str_type
);
85 } while (str_end
!= stri
);
91 return str_intern(result
);
94 void str_skip_spaces(str_type
*pstr
) {
104 _Bool
str_match_prefix(str_type
*pstr
, str_type maybe_prefix
) {
107 assert(maybe_prefix
);
109 str_type str
= *pstr
;
111 while ('\0' != *maybe_prefix
&& *maybe_prefix
== *str
) {
116 if ('\0' == *maybe_prefix
) {
124 str_type
uint_to_str(unsigned int n
) {
125 const int result_size
= (sizeof(n
)*CHAR_BIT
+ 2)/3 + 1;
126 char* result
= checked_malloc(result_size
);
127 int required_size
= snprintf(result
, result_size
, "%u", n
);
128 // We do not expect errors, because the result buffer can hold the
129 // base 10 representation of any unsigned integer.
130 assert(0 <= required_size
&& required_size
<= result_size
);
131 return str_intern(result
);