CharGraph-FW/include/WordFinder.h
2026-02-10 19:51:57 +01:00

135 lines
3.7 KiB
C

/**
* CharGraph - Unified Word Finder
*
* Central component for finding words in patterns
* Handles both PROGMEM patterns (for validation) and regular strings (for display)
* Shared between CharGraphTimeLogic and rgbPanel
*/
#ifndef WORD_FINDER_H
#define WORD_FINDER_H
#include <Arduino.h>
// ============================================================================
// PROGMEM WORD SEARCH (for validation)
// ============================================================================
/**
* Find word in PROGMEM pattern starting from position
* Both pattern and word are in PROGMEM
*
* @param pattern_progmem Pattern string in PROGMEM
* @param word_progmem Word pointer in PROGMEM
* @param searchStart Start position for search (default 0)
* @return Position of word, or -1 if not found
*/
inline int16_t findWordProgmem(const char* pattern_progmem, const char* word_progmem, uint16_t searchStart = 0) {
if (!pattern_progmem || !word_progmem) return -1;
// Load word from PROGMEM into buffer (max 11 chars: DREIVIERTEL)
char wordBuf[12]; // 11 chars + null terminator
strcpy_P(wordBuf, word_progmem);
uint8_t wordLen = strlen(wordBuf);
// Search through pattern_progmem byte by byte
uint16_t pos = searchStart;
while (true) {
char patByte = pgm_read_byte(pattern_progmem + pos);
if (patByte == '\0') break; // End of pattern
// Check if word matches at this position
bool match = true;
for (uint8_t i = 0; i < wordLen; i++) {
char p = pgm_read_byte(pattern_progmem + pos + i);
if (p != wordBuf[i]) {
match = false;
break;
}
}
if (match) return pos;
pos++;
}
return -1;
}
// ============================================================================
// STRING WORD SEARCH (for display)
// ============================================================================
/**
* Find word in regular string with occurrence support
*
* @param text String to search in
* @param word Word to find
* @param occurrence Which occurrence to find (0 = first, 1 = second, etc.)
* @param searchBackward Search backward from end
* @return Position of word, or -1 if not found
*/
inline int findWordString(const char* text, const char* word, int occurrence = 0, bool searchBackward = false) {
if (!text || !word) return -1;
const int wordLen = strlen(word);
const int textLen = strlen(text);
if (searchBackward) {
// Backward search: from end to beginning
int foundCount = 0;
for (int pos = textLen - wordLen; pos >= 0; --pos) {
bool match = true;
for (int j = 0; j < wordLen; ++j) {
unsigned char c1 = text[pos + j];
unsigned char c2 = word[j];
// Lowercase comparison (case-insensitive)
if (c1 >= 'A' && c1 <= 'Z') c1 += ('a' - 'A');
if (c2 >= 'A' && c2 <= 'Z') c2 += ('a' - 'A');
if (c1 != c2) {
match = false;
break;
}
}
if (match) {
if (foundCount == occurrence) {
return pos;
}
foundCount++;
}
}
} else {
// Forward search: from beginning to end
int foundCount = 0;
for (int pos = 0; pos <= textLen - wordLen; ++pos) {
bool match = true;
for (int j = 0; j < wordLen; ++j) {
unsigned char c1 = text[pos + j];
unsigned char c2 = word[j];
// Lowercase comparison (case-insensitive)
if (c1 >= 'A' && c1 <= 'Z') c1 += ('a' - 'A');
if (c2 >= 'A' && c2 <= 'Z') c2 += ('a' - 'A');
if (c1 != c2) {
match = false;
break;
}
}
if (match) {
if (foundCount == occurrence) {
return pos;
}
foundCount++;
}
}
}
return -1;
}
#endif // WORD_FINDER_H