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

Tehreer / SheenBidi / 28885974711

07 Jul 2026 05:31PM UTC coverage: 96.293% (-0.1%) from 96.404%
28885974711

push

github

mta452
[lib] Fix memory leaks

17 of 17 new or added lines in 4 files covered. (100.0%)

34 existing lines in 5 files now uncovered.

4000 of 4154 relevant lines covered (96.29%)

450834.3 hits per line

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

96.97
/Source/API/SBLine.c
1
/*
2
 * Copyright (C) 2014-2026 Muhammad Tayyab Akram
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *      http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16

17
#include <stddef.h>
18

19
#include <API/SBAllocator.h>
20
#include <API/SBAssert.h>
21
#include <API/SBBase.h>
22
#include <Core/Memory.h>
23
#include <Core/Object.h>
24

25
#include "SBLine.h"
26

27
typedef SBLine *SBMutableLineRef;
28

29
typedef struct _LineContext {
30
    const SBBidiType *refTypes;
31
    SBLevel *fixedLevels;
32
    SBUInteger runCount;
33
    SBLevel maxLevel;
34
} LineContext, *LineContextRef;
35

36
static SBLevel CopyLevels(SBLevel *destination,
37
    const SBLevel *source, SBUInteger length, SBUInteger *runCount);
38
static void ResetLevels(LineContextRef context, SBLevel baseLevel, SBUInteger charCount);
39

40
#define LEVELS       0
41
#define COUNT        1
42

43
static SBBoolean InitializeLineContext(LineContextRef context, MemoryRef memory,
861,963✔
44
    const SBBidiType *types, const SBLevel *levels, SBUInteger length, SBLevel baseLevel)
45
{
46
    SBBoolean isInitialized = SBFalse;
861,963✔
47
    void *pointers[COUNT] = { NULL };
861,963✔
48
    SBUInteger sizes[COUNT];
861,963✔
49

50
    sizes[LEVELS] = sizeof(SBLevel) * length;
861,963✔
51

52
    if (MemoryAllocateChunks(memory, MemoryTypeScratch, sizes, COUNT, pointers)) {
861,963✔
53
        SBLevel *fixedLevels = pointers[LEVELS];
861,963✔
54

55
        context->refTypes = types;
861,963✔
56
        context->fixedLevels = fixedLevels;
861,963✔
57
        context->maxLevel = CopyLevels(fixedLevels, levels, length, &context->runCount);
861,963✔
58

59
        ResetLevels(context, baseLevel, length);
861,963✔
60

61
        isInitialized = SBTrue;
861,963✔
62
    }
63

64
    return isInitialized;
861,963✔
65
}
66

67
#undef LEVELS
68
#undef COUNT
69

70
#define LINE  0
71
#define RUNS  1
72
#define COUNT 2
73

74
static SBMutableLineRef AllocateLine(SBUInteger runCount)
861,963✔
75
{
76
    SBMutableLineRef line = NULL;
861,963✔
77

78
    if (runCount > 0) {
861,963✔
79
        void *pointers[COUNT] = { NULL };
861,963✔
80
        SBUInteger sizes[COUNT] = { 0 };
861,963✔
81

82
        sizes[LINE] = sizeof(SBLine);
861,963✔
83
        sizes[RUNS] = sizeof(SBRun) * runCount;
861,963✔
84

85
        line = ObjectCreate(sizes, COUNT, pointers, NULL);
861,963✔
86

87
        if (line) {
861,963✔
88
            line->fixedRuns = pointers[RUNS];
861,963✔
89
        }
90
    }
91

92
    return line;
861,963✔
93
}
94

95
#undef LINE
96
#undef RUNS
97
#undef COUNT
98

99
static SBLevel CopyLevels(SBLevel *destination,
861,963✔
100
    const SBLevel *source, SBUInteger length, SBUInteger *runCount)
101
{
102
    SBLevel lastLevel = SBLevelInvalid;
861,963✔
103
    SBLevel maxLevel = 0;
861,963✔
104
    SBUInteger totalRuns = 0;
861,963✔
105
    SBUInteger index;
106

107
    for (index = 0; index < length; index++) {
4,629,132✔
108
        SBLevel level = source[index];
3,767,169✔
109
        destination[index] = level;
3,767,169✔
110

111
        if (level != lastLevel) {
3,767,169✔
112
            totalRuns += 1;
3,767,169✔
113

114
            if (level > maxLevel) {
3,767,169✔
115
                maxLevel = level;
1,100,445✔
116
            }
117
        }
118
    }
119

120
    *runCount = totalRuns;
861,963✔
121

122
    return maxLevel;
861,963✔
123
}
124

125
static void SetNewLevel(SBLevel *levels, SBUInteger length, SBLevel newLevel)
528,970✔
126
{
127
    SBUInteger index;
128

129
    for (index = 0; index < length; index++) {
1,202,372✔
130
        levels[index] = newLevel;
673,402✔
131
    }
132
}
528,970✔
133

134
static void ResetLevels(LineContextRef context, SBLevel baseLevel, SBUInteger charCount)
861,963✔
135
{
136
    const SBBidiType *types = context->refTypes;
861,963✔
137
    SBLevel *levels = context->fixedLevels;
861,963✔
138
    SBUInteger index;
139
    SBUInteger length;
140
    SBBoolean reset;
141

142
    index = charCount;
861,963✔
143
    length = 0;
861,963✔
144
    reset = SBTrue;
861,963✔
145

146
    while (index--) {
4,629,132✔
147
        SBBidiType type = types[index];
3,767,169✔
148

149
        switch (type) {
3,767,169✔
150
        case SBBidiTypeB:
170,239✔
151
        case SBBidiTypeS:
152
            SetNewLevel(levels + index, length + 1, baseLevel);
170,239✔
153
            length = 0;
170,239✔
154
            reset = SBTrue;
170,239✔
155
            context->runCount += 1;
170,239✔
156
            break;
170,239✔
157

158
        case SBBidiTypeLRE:
823,193✔
159
        case SBBidiTypeRLE:
160
        case SBBidiTypeLRO:
161
        case SBBidiTypeRLO:
162
        case SBBidiTypePDF:
163
        case SBBidiTypeBN:
164
            length += 1;
823,193✔
165
            break;
823,193✔
166

167
        case SBBidiTypeWS:
685,546✔
168
        case SBBidiTypeLRI:
169
        case SBBidiTypeRLI:
170
        case SBBidiTypeFSI:
171
        case SBBidiTypePDI:
172
            if (reset) {
685,546✔
173
                SetNewLevel(levels + index, length + 1, baseLevel);
358,731✔
174
                length = 0;
358,731✔
175

176
                context->runCount += 1;
358,731✔
177
            }
178
            break;
685,546✔
179

180
        default:
2,088,191✔
181
            length = 0;
2,088,191✔
182
            reset = SBFalse;
2,088,191✔
183
            break;
2,088,191✔
184
        }
185
    }
186
}
861,963✔
187

188
static SBUInteger InitializeRuns(SBRun *runs,
861,963✔
189
    const SBLevel *levels, SBUInteger length, SBUInteger lineOffset)
190
{
191
    SBUInteger runIndex = 0;
861,963✔
192
    SBUInteger index;
193

194
    runs[runIndex].offset = lineOffset;
861,963✔
195
    runs[runIndex].level = levels[0];
861,963✔
196

197
    for (index = 0; index < length; index++) {
4,629,132✔
198
        SBLevel level = levels[index];
3,767,169✔
199

200
        if (level != runs[runIndex].level) {
3,767,169✔
201
            runs[runIndex].length = index + lineOffset - runs[runIndex].offset;
910,812✔
202

203
            runIndex += 1;
910,812✔
204
            runs[runIndex].offset = lineOffset + index;
910,812✔
205
            runs[runIndex].level = level;
910,812✔
206
        }
207
    }
208

209
    runs[runIndex].length = index + lineOffset - runs[runIndex].offset;
861,963✔
210

211
    return runIndex + 1;
861,963✔
212
}
213

214
static void ReverseRunSequence(SBRun *runs, SBUInteger runCount)
1,481,588✔
215
{
216
    SBUInteger halfCount = runCount / 2;
1,481,588✔
217
    SBUInteger finalIndex = runCount - 1;
1,481,588✔
218
    SBUInteger index;
219

220
    for (index = 0; index < halfCount; index++) {
1,913,205✔
221
        SBUInteger tieIndex;
222
        SBRun tempRun;
223

224
        tieIndex = finalIndex - index;
431,617✔
225

226
        tempRun = runs[index];
431,617✔
227
        runs[index] = runs[tieIndex];
431,617✔
228
        runs[tieIndex] = tempRun;
431,617✔
229
    }
230
}
1,481,588✔
231

232
static void ReorderRuns(SBRun *runs, SBUInteger runCount, SBLevel maxLevel)
861,963✔
233
{
234
    SBLevel newLevel;
235

236
    for (newLevel = maxLevel; newLevel; newLevel--) {
2,481,968✔
237
        SBUInteger start = runCount;
1,620,005✔
238

239
        while (start--) {
6,452,491✔
240
            if (runs[start].level >= newLevel) {
3,212,481✔
241
                SBUInteger count = 1;
1,481,588✔
242

243
                for (; start && runs[start - 1].level >= newLevel; start--) {
2,060,309✔
244
                    count += 1;
578,721✔
245
                }
246

247
                ReverseRunSequence(runs + start, count);
1,481,588✔
248
            }
249
        }
250
    }
251
}
861,963✔
252

253
SB_INTERNAL SBLineRef SBLineCreate(const SBBidiType *bidiTypes, const SBLevel *bidiLevels,
861,963✔
254
    SBLevel baseLevel, SBStringEncoding encoding, SBUInteger lineOffset, SBUInteger lineLength)
255
{
256
    SBMutableLineRef line = NULL;
861,963✔
257
    Memory memory;
861,963✔
258
    LineContext context;
861,963✔
259

260
    /* Line range MUST be valid. */
261
    SBAssert(lineOffset < (lineOffset + lineLength));
861,963✔
262

263
    MemoryInitialize(&memory);
861,963✔
264

265
    if (InitializeLineContext(&context, &memory, bidiTypes, bidiLevels, lineLength, baseLevel)) {
861,963✔
266
        line = AllocateLine(context.runCount);
861,963✔
267

268
        if (line) {
861,963✔
269
            line->runCount = InitializeRuns(line->fixedRuns, context.fixedLevels, lineLength, lineOffset);
861,963✔
270
            ReorderRuns(line->fixedRuns, line->runCount, context.maxLevel);
861,963✔
271

272
            line->stringEncoding = encoding;
861,963✔
273
            line->offset = lineOffset;
861,963✔
274
            line->length = lineLength;
861,963✔
275
        }
276
    }
277

278
    MemoryFinalize(&memory);
861,963✔
279
    SBAllocatorResetScratch(NULL);
861,963✔
280

281
    return line;
861,963✔
282
}
283

UNCOV
284
SBUInteger SBLineGetOffset(SBLineRef line)
×
285
{
UNCOV
286
    return line->offset;
×
287
}
288

UNCOV
289
SBUInteger SBLineGetLength(SBLineRef line)
×
290
{
291
    return line->length;
×
292
}
293

294
SBUInteger SBLineGetRunCount(SBLineRef line)
1,723,896✔
295
{
296
    return line->runCount;
1,723,896✔
297
}
298

299
const SBRun *SBLineGetRunsPtr(SBLineRef line)
1,723,896✔
300
{
301
    return line->fixedRuns;
1,723,896✔
302
}
303

304
SBLineRef SBLineRetain(SBLineRef line)
861,948✔
305
{
306
    return ObjectRetain((ObjectRef)line);
861,948✔
307
}
308

309
void SBLineRelease(SBLineRef line)
1,723,911✔
310
{
311
    ObjectRelease((ObjectRef)line);
1,723,911✔
312
}
1,723,911✔
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