Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
64479dc
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 11, 2025
048645a
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 13, 2025
3f6710a
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 13, 2025
662566e
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 13, 2025
057dbf8
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 13, 2025
22a6a30
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 14, 2025
f577617
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 16, 2025
ce35399
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 16, 2025
c40183f
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 17, 2025
428cdac
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 17, 2025
c77b2d1
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 17, 2025
ba551d0
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 17, 2025
c4dd1ed
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 17, 2025
5270ab8
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 17, 2025
5ea1271
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 17, 2025
de54ae6
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 19, 2025
0c36239
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 20, 2025
e4a9887
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 20, 2025
d5c0719
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 20, 2025
2c15657
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 20, 2025
bf830f8
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 11, 2025
f4df92d
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 13, 2025
35afe0f
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 13, 2025
c3ecf80
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 13, 2025
1e918e4
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 13, 2025
d52f1bd
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 14, 2025
d9bd557
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 16, 2025
fb047a6
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 16, 2025
2851ea9
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 17, 2025
f5c27e0
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 17, 2025
0465564
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 17, 2025
52f5496
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 17, 2025
84ff0e7
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 17, 2025
a48d071
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 17, 2025
2c508aa
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 17, 2025
2d931de
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 19, 2025
4c11480
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 20, 2025
8fde6f5
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 20, 2025
1835d8c
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 20, 2025
809a8a4
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 20, 2025
d0f4e3e
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 21, 2025
f9cc20c
Merge branch 'topic/RDK-59221' of https://github.com/rdkcentral/telem…
Oct 21, 2025
4b9f9e9
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 21, 2025
8121226
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 21, 2025
9dd963f
Merge branch 'develop' into topic/RDK-59221
yogeswaransky Oct 23, 2025
a76b842
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 23, 2025
ffd9ba9
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 23, 2025
f3019c8
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 23, 2025
349cd40
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 24, 2025
deb8000
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 24, 2025
aaf2dc7
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 24, 2025
07a00e3
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 26, 2025
ba345af
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 26, 2025
6553740
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 26, 2025
f49bc24
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 27, 2025
2af8435
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 27, 2025
d4e9dce
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 27, 2025
bf1048c
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 27, 2025
c0cf119
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 27, 2025
baab429
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 27, 2025
8ce7f79
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 27, 2025
8c5c787
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 27, 2025
b012896
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 28, 2025
f514792
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 28, 2025
7216b7e
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 28, 2025
d922624
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 28, 2025
db36d61
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 28, 2025
a344cbb
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 28, 2025
9b4ec46
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 28, 2025
b99a192
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 28, 2025
23bfc19
RDK-59221: Enable Accumulate Support For Grep Markers in Telemetry Pr…
Oct 28, 2025
a49db01
Merge branch 'develop' into topic/RDK-59221
shibu-kv Oct 28, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 112 additions & 3 deletions source/dcautil/dca.c
Original file line number Diff line number Diff line change
Expand Up @@ -547,7 +547,109 @@ static char* getAbsolutePatternMatch(FileDescriptor* fileDescriptor, const char*
return result;
}

static int processPatternWithOptimizedFunction(const GrepMarker* marker, Vector* out_grepResultList, FileDescriptor* filedescriptor)
static int getAccumulatePatternMatch(FileDescriptor* fileDescriptor, GrepMarker* marker, Vector* out_grepResultList)
{
T2Info("%s ++in\n", __FUNCTION__);
if (!fileDescriptor || !fileDescriptor->cfaddr || fileDescriptor->cf_file_size <= 0 || !marker || !marker->searchString || !*marker->searchString || !out_grepResultList)
{
T2Error("Invalid file descriptor arguments accumulate\n");
return -1;
}

const char* pattern = marker->searchString;
const char* buffer;
size_t buflen = 0;
size_t patlen = strlen(pattern);

// Use the existing accumulatedValues Vector from marker's union
Vector* accumulatedValues = marker->u.accumulatedValues;
if (!accumulatedValues)
{
T2Error("accumulatedValues vector is NULL in marker\n");
return -1;
}

for (int i = 0; i < 2; i++)
{
T2Info("%s %d \n", __FUNCTION__, __LINE__);
if (i == 0)
{
buffer = fileDescriptor->cfaddr;
buflen = (size_t)fileDescriptor->cf_file_size;
}
else
{
buffer = fileDescriptor->rfaddr;
buflen = (size_t)fileDescriptor->rf_file_size;
}

if (buffer == NULL)
{
T2Info("Invalid file descriptor arguments accumulate match\n");
continue;
}

const char *cur = buffer;
size_t bytes_left = buflen;

while (bytes_left >= patlen)
{
T2Info("%s %d \n", __FUNCTION__, __LINE__);
const char *found = strnstr(cur, pattern, bytes_left);
if (!found)
{
break;
}

// Move pointer just after the pattern
const char *start = found + patlen;
size_t chars_left = buflen - (start - buffer);

// Find next newline or end of buffer
const char *end = memchr(start, '\n', chars_left);
size_t length = end ? (size_t)(end - start) : chars_left;

// Create result string for this occurrence
char *result = (char*)malloc(length + 1);
if (result)
{
memcpy(result, start, length);
result[length] = '\0';
T2Info("%s %d : result = %s\n", __FUNCTION__, __LINE__, result);
Vector_PushBack(accumulatedValues, result);
}

size_t advance = (size_t)(found - cur) + patlen;
cur = found + patlen;
if (bytes_left < advance)
{
break;
}
bytes_left -= advance;
}
T2Info("%s %d --out\n", __FUNCTION__, __LINE__);
}

// Create individual GrepResult objects for each accumulated value
size_t accumulatedCount = Vector_Size(accumulatedValues);
for (size_t j = 0; j < accumulatedCount; j++)
{
char* value = (char*)Vector_At(accumulatedValues, j);
if (value)
{
GrepResult* result = createGrepResultObj(marker->markerName, value, marker->trimParam, marker->regexParam);
if (result)
{
Vector_PushBack(out_grepResultList, result);
}
}
}

T2Debug("%s --out\n", __FUNCTION__);
return 0;
}

static int processPatternWithOptimizedFunction(GrepMarker* marker, Vector* out_grepResultList, FileDescriptor* filedescriptor)
{
// Sanitize the input
const char* memmmapped_data_cf = filedescriptor->cfaddr;
Expand Down Expand Up @@ -583,7 +685,14 @@ static int processPatternWithOptimizedFunction(const GrepMarker* marker, Vector*
Vector_PushBack(out_grepResultList, result);
}
}
else
else if (mType == MTYPE_ACCUMULATE)
{
//Get MAX_ACCUMULATE number of occurrences of the pattern in the memory-mapped data
T2Info("%s %d : Accumulate is called\n", __FUNCTION__, __LINE__);
getAccumulatePatternMatch(filedescriptor, marker, out_grepResultList);
T2Info("%s %d : Accumulate is complete\n", __FUNCTION__, __LINE__);
}
else /* MTYPE_ABSOLUTE */
{
// Get the last occurrence of the pattern in the memory-mapped data
last_found = getAbsolutePatternMatch(filedescriptor, pattern);
Expand Down Expand Up @@ -655,7 +764,7 @@ static int getLogFileDescriptor(GrepSeekProfile* gsProfile, const char* logPath,
// Check if the file size matches the seek value from the map
if (sb.st_size == seek_value_from_map)
{
T2Debug("The logfile size matches the seek value (%ld) for %s\n", seek_value_from_map, logFile);
T2Info("The logfile size matches the seek value (%ld) for %s\n", seek_value_from_map, logFile);
close(fd);
return -1; // Consistent error return value
}
Expand Down
178 changes: 157 additions & 21 deletions source/reportgen/reportgen.c
Original file line number Diff line number Diff line change
Expand Up @@ -397,68 +397,204 @@ T2ERROR encodeGrepResultInJSON(cJSON *valArray, Vector *grepResult)
T2Error("Invalid or NULL Arguments\n");
return T2ERROR_INVALID_ARGS;
}
size_t index = 0;
cJSON *arrayItem = NULL;
for(; index < Vector_Size(grepResult); index++)

// Create a hash map to group values by marker name
size_t totalResults = Vector_Size(grepResult);
if (totalResults == 0) {
T2Debug("%s --Out (no results)\n", __FUNCTION__);
return T2ERROR_SUCCESS;
}

// Simple approach: scan through all results and group by marker name
for (size_t i = 0; i < totalResults; i++)
{
GrepResult* grep = (GrepResult *)Vector_At(grepResult, index);
if(grep)
GrepResult* grep = (GrepResult *)Vector_At(grepResult, i);
if(!grep || !grep->markerName || !grep->markerValue)
{
continue;
}

// Check if this marker name has already been processed
bool alreadyProcessed = false;
for (size_t j = 0; j < i; j++)
{
if(grep->markerName == NULL || grep->markerValue == NULL ) // Ignore null values
GrepResult* prevGrep = (GrepResult *)Vector_At(grepResult, j);
if (prevGrep && prevGrep->markerName && strcmp(grep->markerName, prevGrep->markerName) == 0)
{
continue ;
alreadyProcessed = true;
break;
}
arrayItem = cJSON_CreateObject();
}

if (alreadyProcessed)
{
continue; // Skip this one, it's already been processed as part of a group
}

// Count how many results have the same marker name
Vector* sameMarkerResults = NULL;
Vector_Create(&sameMarkerResults);

for (size_t k = i; k < totalResults; k++)
{
GrepResult* currentGrep = (GrepResult *)Vector_At(grepResult, k);
if (currentGrep && currentGrep->markerName && currentGrep->markerValue &&
strcmp(grep->markerName, currentGrep->markerName) == 0)
{
Vector_PushBack(sameMarkerResults, currentGrep);
}
}

size_t sameMarkerCount = Vector_Size(sameMarkerResults);

if (sameMarkerCount == 1)
{
// Single result - use the original logic
GrepResult* singleGrep = (GrepResult *)Vector_At(sameMarkerResults, 0);
cJSON *arrayItem = cJSON_CreateObject();
if(arrayItem == NULL)
{
T2Error("cJSON_CreateObject failed..arrayItem is NULL \n");
Vector_Destroy(sameMarkerResults, NULL);
return T2ERROR_FAILURE;
}
if(grep->trimParameter)

if(singleGrep->trimParameter)
{
trimLeadingAndTrailingws((char*)grep->markerValue);
trimLeadingAndTrailingws((char*)singleGrep->markerValue);
}
if(grep->regexParameter != NULL)

if(singleGrep->regexParameter != NULL)
{
regex_t regpattern;
int rc = 0;
size_t nmatch = 1;
regmatch_t pmatch[2];
char string[256] = {'\0'};
rc = regcomp(&regpattern, grep->regexParameter, REG_EXTENDED);
rc = regcomp(&regpattern, singleGrep->regexParameter, REG_EXTENDED);
if(rc != 0)
{
T2Warning("regcomp() failed, returning nonzero (%d)\n", rc);
}
else
{
T2Debug("regcomp() successful, returning value (%d)\n", rc);
rc = regexec(&regpattern, grep->markerValue, nmatch, pmatch, 0);
rc = regexec(&regpattern, singleGrep->markerValue, nmatch, pmatch, 0);
if(rc != 0)
{
T2Warning("regexec() failed, Failed to match '%s' with '%s',returning %d.\n", grep->markerValue, grep->regexParameter, rc);
free((char*)grep->markerValue);
grep->markerValue = strdup("");
T2Warning("regexec() failed, Failed to match '%s' with '%s',returning %d.\n", singleGrep->markerValue, singleGrep->regexParameter, rc);
free((char*)singleGrep->markerValue);
singleGrep->markerValue = strdup("");
}
else
{
T2Debug("regexec successful, Match is found %.*s\n", pmatch[0].rm_eo - pmatch[0].rm_so, &grep->markerValue[pmatch[0].rm_so]);
sprintf(string, "%.*s", pmatch[0].rm_eo - pmatch[0].rm_so, &grep->markerValue[pmatch[0].rm_so]);
free((char*)grep->markerValue);
grep->markerValue = strdup(string);
T2Debug("regexec successful, Match is found %.*s\n", pmatch[0].rm_eo - pmatch[0].rm_so, &singleGrep->markerValue[pmatch[0].rm_so]);
sprintf(string, "%.*s", pmatch[0].rm_eo - pmatch[0].rm_so, &singleGrep->markerValue[pmatch[0].rm_so]);
free((char*)singleGrep->markerValue);
singleGrep->markerValue = strdup(string);
}
regfree(&regpattern);
}
}
if(cJSON_AddStringToObject(arrayItem, grep->markerName, grep->markerValue) == NULL)

if(cJSON_AddStringToObject(arrayItem, singleGrep->markerName, singleGrep->markerValue) == NULL)
{
T2Error("cJSON_AddStringToObject failed.\n");
cJSON_Delete(arrayItem);
Vector_Destroy(sameMarkerResults, NULL);
return T2ERROR_FAILURE;
}
cJSON_AddItemToArray(valArray, arrayItem);
}
else if (sameMarkerCount > 1)
{
// Multiple results with same marker name - create JSON array
cJSON *arrayItem = cJSON_CreateObject();
if(arrayItem == NULL)
{
T2Error("cJSON_CreateObject failed..arrayItem is NULL \n");
Vector_Destroy(sameMarkerResults, NULL);
return T2ERROR_FAILURE;
}

cJSON *valuesArray = cJSON_CreateArray();
if(valuesArray == NULL)
{
T2Error("cJSON_CreateArray failed..valuesArray is NULL \n");
cJSON_Delete(arrayItem);
Vector_Destroy(sameMarkerResults, NULL);
return T2ERROR_FAILURE;
}

// Add all values to the array
for (size_t m = 0; m < sameMarkerCount; m++)
{
GrepResult* multiGrep = (GrepResult *)Vector_At(sameMarkerResults, m);
if (!multiGrep || !multiGrep->markerValue)
{
continue;
}

char* processedValue = strdup(multiGrep->markerValue);
if (!processedValue)
{
continue;
}

if(multiGrep->trimParameter)
{
trimLeadingAndTrailingws(processedValue);
}

if(multiGrep->regexParameter != NULL)
{
regex_t regpattern;
int rc = 0;
size_t nmatch = 1;
regmatch_t pmatch[2];
char string[256] = {'\0'};
rc = regcomp(&regpattern, multiGrep->regexParameter, REG_EXTENDED);
if(rc != 0)
{
T2Warning("regcomp() failed, returning nonzero (%d)\n", rc);
}
else
{
T2Debug("regcomp() successful, returning value (%d)\n", rc);
rc = regexec(&regpattern, processedValue, nmatch, pmatch, 0);
if(rc != 0)
{
T2Warning("regexec() failed, Failed to match '%s' with '%s',returning %d.\n", processedValue, multiGrep->regexParameter, rc);
free(processedValue);
processedValue = strdup("");
}
else
{
T2Debug("regexec successful, Match is found %.*s\n", pmatch[0].rm_eo - pmatch[0].rm_so, &processedValue[pmatch[0].rm_so]);
sprintf(string, "%.*s", pmatch[0].rm_eo - pmatch[0].rm_so, &processedValue[pmatch[0].rm_so]);
free(processedValue);
processedValue = strdup(string);
}
regfree(&regpattern);
}
}

cJSON *stringItem = cJSON_CreateString(processedValue);
if (stringItem != NULL)
{
cJSON_AddItemToArray(valuesArray, stringItem);
}
free(processedValue);
}

// Add the array to the main object
cJSON_AddItemToObject(arrayItem, grep->markerName, valuesArray);
cJSON_AddItemToArray(valArray, arrayItem);
}

Vector_Destroy(sameMarkerResults, NULL);
}

T2Debug("%s --Out \n", __FUNCTION__);
return T2ERROR_SUCCESS;
}
Expand Down
10 changes: 10 additions & 0 deletions source/t2parser/t2parser.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* If not stated otherwise in this file or this component's LICENSE file the
* following copyright and licenses apply:

Check failure on line 3 in source/t2parser/t2parser.c

View workflow job for this annotation

GitHub Actions / call-fossid-workflow / Fossid Annotate PR

FossID License Issue Detected

Source code with 'Apache-2.0' license found in local file 'source/t2parser/t2parser.c' (Match: rdk/components/generic/telemetry/rdk/components/generic/telemetry/1, 2592 lines, url: https://code.rdkcentral.com/r/plugins/gitiles/rdk/components/generic/telemetry/+archive/RDKB-RELEASE-TEST-DUNFELL-1.tar.gz, file: source/t2parser/t2parser.c)
*
* Copyright 2019 RDK Management
*
Expand Down Expand Up @@ -346,6 +346,16 @@
gMarker->mType = MTYPE_COUNTER;
gMarker->u.count = 0;
}
else if (0 == strcmp(use, "accumulate"))
{
T2Info("marker type is Accumulate \n");
gMarker->mType = MTYPE_ACCUMULATE;
Vector_Create(&gMarker->u.accumulatedValues);
if(gMarker->reportTimestampParam == REPORTTIMESTAMP_UNIXEPOCH)
{
Vector_Create(&gMarker->accumulatedTimestamp);
}
}
else
{
T2Info("Unsupported marker type. Defaulting to absolute \n");
Expand Down
4 changes: 4 additions & 0 deletions source/utils/t2common.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* If not stated otherwise in this file or this component's LICENSE file the
* following copyright and licenses apply:

Check failure on line 3 in source/utils/t2common.h

View workflow job for this annotation

GitHub Actions / call-fossid-workflow / Fossid Annotate PR

FossID License Issue Detected

Source code with 'Apache-2.0' license found in local file 'source/utils/t2common.h' (Match: rdk/components/generic/telemetry/rdk/components/generic/telemetry/1, 70 lines, url: https://code.rdkcentral.com/r/plugins/gitiles/rdk/components/generic/telemetry/+archive/RDKB-RELEASE-TEST-DUNFELL-1.tar.gz, file: source/bulkdata/t2common.h)
*
* Copyright 2019 RDK Management
*
Expand Down Expand Up @@ -95,13 +95,17 @@
char* markerName;
char* searchString;
char* logFile;
reportTimestampFormat reportTimestampParam;
char* markerName_CT;
char* regexParam;
MarkerType mType;
union
{
unsigned int count;
char* markerValue;
Vector* accumulatedValues;
} u;
Vector* accumulatedTimestamp;
unsigned int skipFreq;
int firstSeekFromEOF;
} GrepMarker;
Expand Down
Loading