• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

thoni56 / c-xrefactory / 1792

05 May 2026 08:07PM UTC coverage: 84.921% (-0.2%) from 85.157%
1792

push

travis-ci

thoni56
[docs][memory-as-truth] Document Memory As Truth and the disk-read tripwire

Add a Principles section that articulates memory-as-truth as the
current stance (rather than a future direction), and documents the
tripwire — the assert in scanCxFile() guarded by snapshotLoadComplete
— as how the principle is enforced.

Trim the now-stale NOTE in "Reference Database and Parsing" that
spoke of memory-as-truth as a roadmap item; the new section carries
that content.

Update the assert message in cxfile.c to point at the docs section
rather than a private memory note.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

16366 of 19272 relevant lines covered (84.92%)

15892633.29 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

83.16
src/characterreader.c
1
#include "characterreader.h"
2

3
#include <stdlib.h>
4
#include <string.h>
5

6
#include "head.h"
7
#include "fileio.h"
8

9
#include "log.h"
10

11

12
#define MAX_UNGET_CHARS 20
13

14

15
void fillCharacterBuffer(CharacterBuffer *characterBuffer,
2,306,956✔
16
                         char *next,
17
                         char *end,
18
                         FILE *file,
19
                         unsigned filePos,
20
                         int fileNumber,
21
                         char *lineBegin
22
) {
23
    characterBuffer->nextUnread = next;
2,306,956✔
24
    characterBuffer->end = end;
2,306,956✔
25
    characterBuffer->file = file;
2,306,956✔
26
    characterBuffer->filePos = filePos;
2,306,956✔
27
    characterBuffer->fileNumber = fileNumber;
2,306,956✔
28
    characterBuffer->lineNumber = 0;
2,306,956✔
29
    characterBuffer->lineBegin = lineBegin;
2,306,956✔
30
    characterBuffer->columnOffset = 0;
2,306,956✔
31
    characterBuffer->isAtEOF = false;
2,306,956✔
32
}
2,306,956✔
33

34
void initCharacterBufferFromFile(CharacterBuffer *characterbuffer, FILE *file) {
1,153,553✔
35
    fillCharacterBuffer(characterbuffer, characterbuffer->chars, characterbuffer->chars,
1,153,553✔
36
                        file, 0, -1, characterbuffer->chars);
1,153,553✔
37
}
1,153,553✔
38

39
void initCharacterBufferFromString(CharacterBuffer *characterbuffer, char *string) {
11✔
40
    strcpy(characterbuffer->chars, string);
11✔
41
    fillCharacterBuffer(characterbuffer, characterbuffer->chars, characterbuffer->chars,
11✔
42
                        NULL, 0, 0, characterbuffer->chars);
43
    characterbuffer->end = &characterbuffer->chars[strlen(string)];
11✔
44
}
11✔
45

46

47
int fileNumberFrom(CharacterBuffer *cb) {
491,863,440✔
48
    return cb->fileNumber;
491,863,440✔
49
}
50

51
int lineNumberFrom(CharacterBuffer *cb) {
722,597,856✔
52
    return cb->lineNumber;
722,597,856✔
53
}
54

55
/* ***************************************************************** */
56
/*                        Character reading                          */
57
/* ***************************************************************** */
58

59

60
static int readFromFileToBuffer(CharacterBuffer  *buffer, char *outBuffer, int max_size) {
1,150,159✔
61
    if (buffer->file == NULL)
1,150,159✔
62
        return 0;
63
    else
64
        return readFile(buffer->file, outBuffer, 1, max_size);
667✔
65
}
66

67
void closeCharacterBuffer(CharacterBuffer *buffer) {
1,013,018✔
68
    ENTER();
1,013,018✔
69
    if (buffer->file != NULL)
1,013,018✔
70
        closeFile(buffer->file);
×
71
    LEAVE();
1,013,018✔
72
}
1,013,018✔
73

74
bool refillBuffer(CharacterBuffer *buffer) {
1,150,159✔
75
    char *next = buffer->nextUnread;
1,150,159✔
76
    char *end = buffer->end;
1,150,159✔
77

78
    char *cp;
1,150,159✔
79
    for (cp=buffer->chars+MAX_UNGET_CHARS; next<end; next++,cp++)
×
80
        *cp = *next;
81

1,150,159✔
82
    int max_size = CHARACTER_BUFFER_SIZE - (cp - buffer->chars);
83

1,150,159✔
84
    int charactersRead = readFromFileToBuffer(buffer, cp, max_size);
85

1,150,159✔
86
    if (charactersRead > 0) {
501✔
87
        buffer->filePos += charactersRead;
501✔
88
        buffer->end = cp+charactersRead;
501✔
89
        buffer->nextUnread = buffer->chars+MAX_UNGET_CHARS;
90
    }
91

1,150,660✔
92
    log_trace("refillBuffer: (%s) buffer->next=%p, buffer->end=%p", buffer->nextUnread == buffer->end?"equal":"not equal", buffer->nextUnread, buffer->end);
1,150,159✔
93
    return buffer->nextUnread != buffer->end;
94
}
95

96

5✔
97
void skipCharacters(CharacterBuffer *buffer, unsigned count) {
98

5✔
99
    if (buffer->nextUnread+count < buffer->end) {
5✔
100
        buffer->nextUnread += count;
5✔
101
        return;
102
    }
103

×
104
    count -= buffer->end - buffer->nextUnread;        /* How many to skip after refilling? */
105

×
106
    char *dd;
×
107
    int n;
×
108
    int max_size;
109

×
110
    log_trace("seeking over %d chars", count);
×
111
    fseek(buffer->file, count, SEEK_CUR);
×
112
    buffer->filePos += count;
×
113
    dd = buffer->chars + MAX_UNGET_CHARS;
×
114
    max_size = CHARACTER_BUFFER_SIZE - (dd - buffer->chars);
×
115
    if (buffer->file == NULL)
116
        n = 0;
117
    else
×
118
        n = readFile(buffer->file, dd, 1, max_size);
×
119
    buffer->filePos += n;
×
120
    buffer->end = dd + n;
×
121
    buffer->nextUnread = buffer->chars + MAX_UNGET_CHARS;
122
}
123

124

2,147,483,647✔
125
int columnPosition(CharacterBuffer *cb) {
2,147,483,647✔
126
    return cb->nextUnread - cb->lineBegin + cb->columnOffset - 1;
127
}
128

129

1,551,312,311✔
130
int fileOffsetFor(CharacterBuffer *cb) {
1,551,312,311✔
131
    return cb->filePos - (cb->end - cb->nextUnread) - 1;
132
}
133

134

941,608,761✔
135
int skipBlanks(CharacterBuffer *cb, int ch) {
1,505,996,583✔
136
    while (ch==' '|| ch=='\t' || ch=='\004') { /* EOT? */
564,387,822✔
137
        ch = getChar(cb);
138
    }
941,608,761✔
139
    return ch;
140
}
141

142

83,808✔
143
int skipWhiteSpace(CharacterBuffer *cb, int ch) {
106,233✔
144
    while (ch==' ' || ch=='\n' || ch=='\t') {
22,425✔
145
        ch = getChar(cb);
146
    }
147

83,808✔
148
    return ch;
149
}
150

151
/* Return next unread character from CharacterBuffer and advance */
2,147,483,647✔
152
int getChar(CharacterBuffer *cb) {
2,147,483,647✔
153
        if (cb->nextUnread >= cb->end &&
2,300,655✔
154
            (cb->isAtEOF || refillBuffer(cb) == 0)) {
2,300,154✔
155
                cb->isAtEOF = true;
2,300,154✔
156
                return EOF;
157
        } else {
2,147,483,647✔
158
            return *cb->nextUnread++;
159
        }
160
}
161

162

7,016✔
163
void getString(CharacterBuffer *cb, char *string, int length) {
7,016✔
164
    char ch;
165

124,992✔
166
    for (int i=0; i<length; i++) {
117,976✔
167
        ch = getChar(cb);
117,976✔
168
        string[i] = ch;
169
    }
7,016✔
170
    string[length] = 0;
7,016✔
171
}
172

43,170,739✔
173
void ungetChar(CharacterBuffer *cb, int ch) {
43,170,739✔
174
    if (ch == '\n')
2,440,174✔
175
        log_trace("Ungetting ('\\n')");
176
    else
40,730,565✔
177
        log_trace("Ungetting ('%c'=%d)", ch, ch);
43,170,739✔
178
    *--(cb->nextUnread) = ch;
43,170,739✔
179
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc