]>
Commit | Line | Data |
---|---|---|
66297844 CP |
1 | #define COMPILING_SSTRING |
2 | #include "sstring.h" | |
3 | ||
4 | #include "../core/hooks.h" | |
5 | #include "../core/nsmalloc.h" | |
6 | #include "../core/error.h" | |
7 | ||
8 | #include <stdio.h> | |
9 | ||
10 | #include <assert.h> | |
11 | #include <stdlib.h> | |
12 | #define __USE_GNU | |
13 | #include <string.h> | |
14 | ||
c5ec4806 CP |
15 | typedef struct sstringlist { |
16 | struct sstringlist *prev; | |
17 | struct sstringlist *next; | |
18 | sstring s[]; | |
19 | } sstringlist; | |
20 | ||
21 | static sstringlist *head; | |
22 | ||
66297844 CP |
23 | void initsstring() { |
24 | } | |
25 | ||
26 | void finisstring() { | |
27 | sstringlist *s, *sn; | |
28 | ||
29 | /* here we deliberately don't free the pointers so valgrind can tell us where they were allocated, in theory */ | |
30 | ||
31 | for(s=head;s;s=sn) { | |
32 | sn = s->next; | |
33 | s->next = NULL; | |
34 | s->prev = NULL; | |
35 | ||
36 | Error("sstring", ERR_WARNING, "sstring of length %d still allocated: %s", s->s->u.l.length, s->s->content); | |
37 | } | |
38 | ||
39 | head = NULL; | |
40 | } | |
41 | ||
42 | sstring *getsstring(const char *inputstr, int maxlen) { | |
43 | sstringlist *s; | |
44 | size_t len; | |
45 | char *p; | |
46 | ||
47 | if(!inputstr) | |
48 | return NULL; | |
49 | ||
50 | for(p=(char *)inputstr;*p&&maxlen;maxlen--,p++) | |
51 | ; /* empty */ | |
52 | ||
53 | len = p - inputstr; | |
54 | s=(sstringlist *)malloc(sizeof(sstringlist) + sizeof(sstring)); | |
55 | ||
56 | s->s->u.l.length = len; | |
57 | s->s->content=(char *)malloc(len + 1); | |
58 | ||
59 | memcpy(s->s->content, inputstr, len); | |
60 | s->s->content[len] = '\0'; | |
61 | ||
62 | s->next = head; | |
63 | s->prev = NULL; | |
64 | if(head) | |
65 | head->prev = s; | |
66 | head = s; | |
67 | ||
68 | return s->s; | |
69 | } | |
70 | ||
71 | void freesstring(sstring *inval) { | |
72 | sstringlist *s; | |
73 | if(!inval) | |
74 | return; | |
75 | ||
76 | s = (sstringlist *)inval - 1; | |
77 | ||
78 | if(s->prev) { | |
79 | s->prev->next = s->next; | |
80 | if(s->next) | |
81 | s->next->prev = s->prev; | |
82 | } else { | |
83 | head = s->next; | |
84 | if(head) | |
85 | head->prev = NULL; | |
86 | } | |
87 | ||
88 | free(inval->content); | |
89 | free(s); | |
90 | } |