You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

95 lines
3.2 KiB

2 years ago
/**
* Prefix Match
*
* Match input value to a list of options, allowing non-ambiguous abbreviation and partial matching.
* This library was designed for command recognition in interactive consoles and command interfaces.
*
* Created on 2020/06/09 by Ondřej Hruška
*/
#ifndef _PREFIX_MATCH_H
#define _PREFIX_MATCH_H
#include <stdbool.h>
#include <stddef.h>
/** Use case-sensitive matching */
#define PREFIXMATCH_CASE_SENSITIVE 1
/** Forbid abbreviations */
#define PREFIXMATCH_NOABBREV 2
/** Allow matching fewer words, if unambiguous */
#define PREFIXMATCH_MULTI_PARTIAL 4
enum pm_test_result {
PM_TEST_NO_MATCH = 0,
PM_TEST_MATCH = 1,
PM_TEST_MATCH_MULTI_PARTIAL = 2,
};
/**
* Recognize (optionally abbreviated) input
*
* @param[in] value - tested value
* @param[in] options - options to match against
* @param[in] flags - matching options (bitmask) - accepts PREFIXMATCH_CASE_SENSITIVE and PREFIXMATCH_NOABBREV
* @return index of the matched option, -1 on mismatch or ambiguous match
*/
int prefix_match(const char *value, const char **options, int flags);
/**
* Recognize input consisting of one or more (optionally abbreviated) words
*
* @param[in] value - tested value
* @param[in] options - options to match against, multi-word options separated by the listed delimiters
* @param[in] delims - string with a list of possible delimiters (like for strtok)
* @param[in] flags - matching options (bitmask) - accepts all options
* @return index of the matched option, -1 on mismatch or ambiguous match
*/
int prefix_multipart_match(const char *restrict value, const char **options, const char* restrict delims, int flags);
// useful internal functions exported for possible re-use
/**
* Test if two word sentences match, with individual words optionally allowed to be abbreviated.
*
* @internal
* @param[in] tested - tested (optionally abbreviated) sentence
* @param[in] full - full sentence
* @param[in] delims - list of possible delimiters, same may be used for both sentences
* @param[in] flags - matching options (bitmask) - accepts all options
* @return 1-match; 0-no match; 2-partial (some words) match, if the PREFIXMATCH_MULTI_PARTIAL flag is set
*/
enum pm_test_result prefix_multipart_test(const char *restrict tested, const char* restrict full, const char *restrict delims, int flags);
/**
* Count words in a "sentence", delimited by any of the given set of delimiters.
*
* @internal
* @param[in] sentence - one or multi-word string
* @param[in] delims - delimiters accepted
* @return number of words
*/
size_t pm_count_words(const char * restrict sentence, const char * restrict delims);
/**
* Measure word length
*
* @internal
* @param[in] word - start of a word that ends with either one of the delimiters, or a null byte.
* @param[in] delims - delimiters accepted
* @return word length
*/
size_t pm_word_len(const char * restrict word, const char * restrict delims);
/**
* Skip N words in a sentence.
*
* @param[in] sentence - one or multi-word string
* @param[in] delims - delimiters accepted
* @param[in] skip - how many words to skip
* @return pointer to the first byte after the last skipped word
*/
const char *pm_skip_words(const char * restrict sentence, const char * restrict delims, size_t skip);
#endif //_PREFIX_MATCH_H