source: git/src/str.h @ 147847c

stereo-2025warn-only-for-hanging-survey
Last change on this file since 147847c was 0532954, checked in by Olly Betts <olly@…>, 16 months ago

Rework str.h

The previous implementation was O(n²) for a loop appending n characters
to the string. In practice the strings are typically very short for
.svx format, but for other formats they may be longer so it seems silly
to have this known inefficiency.

  • Property mode set to 100644
File size: 2.8 KB
RevLine 
[0532954]1/* dynamic string handling */
2/* Copyright (c) Olly Betts 1999, 2001, 2012, 2014, 2024
[9286525]3 *
[89231c4]4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
[846746e]8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
[89231c4]11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 * GNU General Public License for more details.
[846746e]13 *
[89231c4]14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
[ecbc6c18]16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
[846746e]17 */
[30d80d2]18
[0532954]19#ifndef SURVEX_INCLUDED_STR_H
20#define SURVEX_INCLUDED_STR_H
21
[30d80d2]22#include "osalloc.h"
[0532954]23#include <string.h>
24
25typedef struct {
26    char *s;
27    int len;
28    int capacity; /* One less than the allocated size! */
29} string;
30
31// string foo = S_INIT;
32#define S_INIT { NULL, 0, 0 }
33
34void s_expand_(string *pstr, int addition);
35
36/* Append a block of text with given length. */
37void s_catlen(string *pstr, const char *s, int s_len);
38
39/* Append a C string. */
40inline void s_cat(string *pstr, const char *s) {
41    s_catlen(pstr, s, strlen(s));
42}
43
44/* Append a character */
45inline void s_catchar(string *pstr, char c) {
46    if (pstr->capacity == pstr->len) s_expand_(pstr, 1);
47    pstr->s[pstr->len++] = c;
48    pstr->s[pstr->len] = '\0';
49}
50
51/* Truncate string to zero length (and ensure it isn't NULL). */
52inline void s_clear(string *pstr) {
53    if (pstr->s == NULL) s_expand_(pstr, 0);
54    pstr->len = 0;
55    pstr->s[0] = '\0';
56}
57
58/* Truncate string */
59inline void s_truncate(string *pstr, int new_len) {
60    if (new_len < pstr->len) {
61        pstr->len = new_len;
62        pstr->s[new_len] = '\0';
63    }
64}
65
66/* Release allocated memory. */
67inline void s_free(string *pstr) {
68    osfree(pstr->s);
69    pstr->s = NULL;
70    pstr->len = 0;
71    pstr->capacity = 0;
72}
73
74/* Steal the C string. */
75inline char *s_steal(string *pstr) {
76    char *s = pstr->s;
77    pstr->s = NULL;
78    pstr->len = 0;
79    pstr->capacity = 0;
80    return s;
81}
82
83/* Donate a malloc-ed C string. */
84inline void s_donate(string *pstr, char *s) {
85    osfree(pstr->s);
86    pstr->s = s;
87    pstr->capacity = pstr->len = strlen(s);
88}
89
90inline int s_len(const string *pstr) { return pstr->len; }
91
92inline bool s_empty(const string *pstr) { return pstr->len == 0; }
[30d80d2]93
[0532954]94inline const char *s_str(string *pstr) { return pstr->s; }
[99d5754]95
[0532954]96inline bool s_eqlen(const string *pstr, const char *s, int s_len) {
97    return pstr->len == s_len && memcmp(pstr->s, s, s_len) == 0;
98}
[bd2e33a]99
[0532954]100inline bool s_eq(const string *pstr, const char *s) {
101    return strcmp(pstr->s, s) == 0;
102}
[99d5754]103
[0532954]104#define S_EQ(PSTR, LITERAL) s_eqlen((PSTR), LITERAL, sizeof(LITERAL "") - 1)
[99d5754]105
[0532954]106#endif // SURVEX_INCLUDED_STR_H
Note: See TracBrowser for help on using the repository browser.