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

Tehreer / SheenBidi / 15192346582

22 May 2025 04:13PM UTC coverage: 79.545% (+1.0%) from 78.546%
15192346582

push

github

mta452
[make] Set C++ standard version to 14

1400 of 1760 relevant lines covered (79.55%)

868008.5 hits per line

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

93.75
/Source/SBScriptLocator.c
1
/*
2
 * Copyright (C) 2018-2025 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 "GeneralCategoryLookup.h"
20
#include "Object.h"
21
#include "PairingLookup.h"
22
#include "SBBase.h"
23
#include "SBCodepoint.h"
24
#include "SBCodepointSequence.h"
25
#include "ScriptLookup.h"
26
#include "ScriptStack.h"
27
#include "SBScriptLocator.h"
28

29
static SBBoolean IsSimilarScript(SBScript lhs, SBScript rhs)
162✔
30
{
31
    return SBScriptIsCommonOrInherited(lhs)
32
        || SBScriptIsCommonOrInherited(rhs)
144✔
33
        || lhs == rhs;
306✔
34
}
35

36
SBScriptLocatorRef SBScriptLocatorCreate(void)
9✔
37
{
38
    const SBUInteger size = sizeof(SBScriptLocator);
9✔
39
    void *pointer = NULL;
9✔
40

41
    if (ObjectCreate(&size, 1, &pointer)) {
9✔
42
        SBScriptLocatorRef locator = pointer;
9✔
43
        locator->_codepointSequence.stringEncoding = SBStringEncodingUTF8;
9✔
44
        locator->_codepointSequence.stringBuffer = NULL;
9✔
45
        locator->_codepointSequence.stringLength = 0;
9✔
46
        locator->retainCount = 1;
9✔
47

48
        SBScriptLocatorReset(locator);
9✔
49
    }
50

51
    return pointer;
9✔
52
}
53

54
void SBScriptLocatorLoadCodepoints(SBScriptLocatorRef locator, const SBCodepointSequence *codepointSequence)
9✔
55
{
56
    locator->_codepointSequence = *codepointSequence;
9✔
57
    SBScriptLocatorReset(locator);
9✔
58
}
9✔
59

60
const SBScriptAgent *SBScriptLocatorGetAgent(SBScriptLocatorRef locator)
9✔
61
{
62
    return &locator->agent;
9✔
63
}
64

65
static void ResolveScriptRun(SBScriptLocatorRef locator, SBUInteger offset)
17✔
66
{
67
    const SBCodepointSequence *sequence = &locator->_codepointSequence;
17✔
68
    ScriptStackRef stack = &locator->_scriptStack;
17✔
69
    SBScript result = SBScriptZYYY;
17✔
70
    SBUInteger current = offset;
17✔
71
    SBUInteger next = offset;
17✔
72
    SBCodepoint codepoint;
73

74
    /* Iterate over the code points of specified string buffer. */
75
    while ((codepoint = SBCodepointSequenceGetCodepointAt(sequence, &next)) != SBCodepointInvalid) {
170✔
76
        SBBoolean isStacked = SBFalse;
162✔
77
        SBScript script;
78

79
        script = LookupScript(codepoint);
162✔
80

81
        /* Handle paired punctuations in case of a common script. */
82
        if (script == SBScriptZYYY) {
162✔
83
            SBGeneralCategory generalCategory = LookupGeneralCategory(codepoint);
35✔
84

85
            /* Check if current code point is an open punctuation. */
86
            if (generalCategory == SBGeneralCategoryPS) {
35✔
87
                SBCodepoint mirror = LookupMirror(codepoint);
4✔
88
                if (mirror) {
4✔
89
                    /* A closing pair exists for this punctuation, so push it onto the stack. */
90
                    ScriptStackPush(stack, result, mirror);
4✔
91
                }
92
            }
93
            /* Check if current code point is a close punctuation. */
94
            else if (generalCategory == SBGeneralCategoryPE) {
31✔
95
                SBBoolean isMirrored = (LookupMirror(codepoint) != 0);
7✔
96
                if (isMirrored) {
7✔
97
                    /* Find the matching entry in the stack, while popping the unmatched ones. */
98
                    while (!ScriptStackIsEmpty(stack)) {
7✔
99
                        SBCodepoint mirror = ScriptStackGetMirror(stack);
7✔
100
                        if (mirror != codepoint) {
7✔
101
                            ScriptStackPop(stack);
×
102
                        } else {
103
                            break;
7✔
104
                        }
105
                    }
106

107
                    if (!ScriptStackIsEmpty(stack)) {
7✔
108
                        isStacked = SBTrue;
7✔
109
                        /* Paired punctuation match the script of enclosing text. */
110
                        script = ScriptStackGetScript(stack);
7✔
111
                    }
112
                }
113
            }
114
        }
115

116
        if (IsSimilarScript(result, script)) {
162✔
117
            if (SBScriptIsCommonOrInherited(result) && !SBScriptIsCommonOrInherited(script)) {
153✔
118
                /* Set the concrete script of this code point as the result. */
119
                result = script;
17✔
120
                /* Seal the pending punctuations with the result. */
121
                ScriptStackSealPairs(stack, result);
17✔
122
            }
123

124
            if (isStacked) {
153✔
125
                /* Pop the paired punctuation from the stack. */
126
                ScriptStackPop(stack);
4✔
127
            }
128
        } else {
129
            /* The current code point has a different script, so finish the run. */
130
            break;
9✔
131
        }
132

133
        current = next;
153✔
134
    }
135

136
    ScriptStackLeavePairs(stack);
17✔
137

138
    /* Set the run info in agent. */
139
    locator->agent.offset = offset;
17✔
140
    locator->agent.length = current - offset;
17✔
141
    locator->agent.script = result;
17✔
142
}
17✔
143

144
SBBoolean SBScriptLocatorMoveNext(SBScriptLocatorRef locator)
26✔
145
{
146
    SBUInteger offset = locator->agent.offset + locator->agent.length;
26✔
147

148
    if (offset < locator->_codepointSequence.stringLength) {
26✔
149
        ResolveScriptRun(locator, offset);
17✔
150
        return SBTrue;
17✔
151
    }
152

153
    SBScriptLocatorReset(locator);
9✔
154
    return SBFalse;
9✔
155
}
156

157
void SBScriptLocatorReset(SBScriptLocatorRef locator)
27✔
158
{
159
    ScriptStackReset(&locator->_scriptStack);
27✔
160
    locator->agent.offset = 0;
27✔
161
    locator->agent.length = 0;
27✔
162
    locator->agent.script = SBScriptNil;
27✔
163
}
27✔
164

165
SBScriptLocatorRef SBScriptLocatorRetain(SBScriptLocatorRef locator)
×
166
{
167
    if (locator) {
×
168
        locator->retainCount += 1;
×
169
    }
170

171
    return locator;
×
172
}
173

174
void SBScriptLocatorRelease(SBScriptLocatorRef locator)
9✔
175
{
176
    if (locator && --locator->retainCount == 0) {
9✔
177
        ObjectDispose(&locator->_object);
9✔
178
    }
179
}
9✔
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