Fix typo
[rofl0r-order-pp.git] / example / lambda / str.c
blob01c937024327e1ab9ec4194d2385b409c611b113
1 // (C) Copyright Vesa Karvonen 2004.
2 //
3 // Distributed under the Boost Software License, Version 1.0.
4 // (See accompanying file LICENSE.)
6 #include "checked_malloc.h"
7 #include "str.h"
8 #include <assert.h>
9 #include <ctype.h>
10 #include <limits.h>
11 #include <stdarg.h>
12 #include <stddef.h>
13 #include <stdio.h>
14 #include <string.h>
16 str_type str_intern(str_type str) {
17 assert(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;
23 str_type datum;
24 } *str_entry;
26 static str_entry entries = 0;
28 str_entry entry = entries;
29 while (entry && strcmp(entry->datum, str))
30 entry = entry->next;
32 if (entry)
33 return entry->datum;
35 entry = checked_malloc(sizeof(struct str_entry));
36 entry->next = entries;
37 entry->datum = str;
38 entries = entry;
40 return str;
43 str_type str_substr(str_type first, str_type beyond) {
44 assert(first);
45 assert(beyond);
47 const ptrdiff_t len = beyond - first;
49 char* result = checked_malloc(len + 1);
50 memcpy(result, first, len);
51 result[len] = '\0';
53 return str_intern(result);
56 str_type str_cat(str_type str0, ...) {
57 assert(str0);
59 ptrdiff_t tot_len = 0;
61 va_list args;
62 va_start(args, str0);
64 str_type stri = str0;
65 do {
66 tot_len += strlen(stri);
67 stri = va_arg(args, str_type);
68 } while (str_end != stri);
70 va_end(args);
73 char* const result = checked_malloc(tot_len + 1);
75 va_list args;
76 va_start(args, str0);
78 char* dst = result;
79 str_type stri = str0;
80 do {
81 ptrdiff_t len = strlen(stri);
82 memcpy(dst, stri, len);
83 dst += len;
84 stri = va_arg(args, str_type);
85 } while (str_end != stri);
87 dst[0] = '\0';
89 va_end(args);
91 return str_intern(result);
94 void str_skip_spaces(str_type *pstr) {
95 assert(pstr);
96 assert(*pstr);
98 str_type str = *pstr;
99 while (isspace(*str))
100 ++str;
101 *pstr = str;
104 _Bool str_match_prefix(str_type *pstr, str_type maybe_prefix) {
105 assert(pstr);
106 assert(*pstr);
107 assert(maybe_prefix);
109 str_type str = *pstr;
111 while ('\0' != *maybe_prefix && *maybe_prefix == *str) {
112 ++maybe_prefix;
113 ++str;
116 if ('\0' == *maybe_prefix) {
117 *pstr = str;
118 return 1;
119 } else {
120 return 0;
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);