SDDSlib
Loading...
Searching...
No Matches
match_string.c
Go to the documentation of this file.
1/**
2 * @file match_string.c
3 * @brief Provides functions for matching strings with various matching modes.
4 *
5 * @copyright
6 * - (c) 2002 The University of Chicago, as Operator of Argonne National Laboratory.
7 * - (c) 2002 The Regents of the University of California, as Operator of Los Alamos National Laboratory.
8 *
9 * @license
10 * This file is distributed under the terms of the Software License Agreement
11 * found in the file LICENSE included with this distribution.
12 *
13 * @author M. Borland, C. Saunders, R. Soliday
14 */
15
16#include "match_string.h"
17#include "mdb.h"
18#include <ctype.h>
19
20/**
21 * @brief Matches a given string against an array of option strings based on specified modes.
22 *
23 * This function searches for a match of the input string within the provided array of option strings.
24 * It supports different matching modes such as wildcard matching, case sensitivity, and whole string matching.
25 * Depending on the mode flags, it can return the first match or indicate ambiguity.
26 *
27 * @param string The string to find a match for.
28 * @param option The array of strings to match against.
29 * @param n_options The number of option strings in the array.
30 * @param mode Flags that determine the matching behavior (e.g., WILDCARD_MATCH, MATCH_WHOLE_STRING, CASE_SENSITIVE, RETURN_FIRST_MATCH).
31 *
32 * @return The index of the matching string in the options array, or -1 if no match is found or if multiple matches exist when ambiguity is not allowed.
33 */
35 char *string, /* string to find match for */
36 char **option, /* strings to match with */
37 long n_options, /* number of strings to match with */
38 long mode /* matching mode flags */
39) {
40 register long i, i_match, l;
41
42 if (string == NULL)
43 return (-1);
44
45 if (mode & WILDCARD_MATCH) {
46 for (i = 0; i < n_options; i++)
47 if (wild_match(string, option[i]))
48 return i;
49 return -1;
50 }
51
52 if (!(mode & MATCH_WHOLE_STRING)) {
53 l = strlen(string);
54 i_match = -1;
55 if (mode & CASE_SENSITIVE) {
56 for (i = 0; i < n_options; i++) {
57 if (strncmp(string, option[i], l) == 0) {
58 if (mode & RETURN_FIRST_MATCH)
59 return (i);
60 if (i_match != -1)
61 return (-1);
62 i_match = i;
63 }
64 }
65 return (i_match);
66 } else {
67 for (i = 0; i < n_options; i++) {
68 if (strncmp_case_insensitive(string, option[i], MIN(l, (long)strlen(option[i]))) == 0) {
69 if (mode & RETURN_FIRST_MATCH)
70 return (i);
71 if (i_match != -1)
72 return (-1);
73 i_match = i;
74 }
75 }
76 return (i_match);
77 }
78 }
79
80 if (mode & MATCH_WHOLE_STRING) {
81 i_match = -1;
82 if (mode & CASE_SENSITIVE) {
83 for (i = 0; i < n_options; i++) {
84 if (strcmp(string, option[i]) == 0) {
85 if (mode & RETURN_FIRST_MATCH)
86 return (i);
87 if (i_match != -1)
88 return (-1);
89 i_match = i;
90 }
91 }
92 return (i_match);
93 } else {
94 for (i = 0; i < n_options; i++) {
95 if (strcmp_case_insensitive(string, option[i]) == 0) {
96 if (mode & RETURN_FIRST_MATCH)
97 return (i);
98 if (i_match != -1)
99 return (-1);
100 i_match = i;
101 }
102 }
103 return (i_match);
104 }
105 }
106
107 /* unknown set of flags */
108 puts("error: unknown flag combination in match_string()");
109 puts(" contact programmer!");
110 exit(1);
111}
112
113/**
114 * @brief Compares two strings in a case-insensitive manner.
115 *
116 * This function compares two null-terminated strings without considering the case of the characters.
117 * It returns an integer less than, equal to, or greater than zero if the first string is found,
118 * respectively, to be less than, to match, or be greater than the second string.
119 *
120 * @param s1 The first string to compare.
121 * @param s2 The second string to compare.
122 *
123 * @return An integer indicating the relationship between the strings:
124 * - Less than zero if s1 is less than s2.
125 * - Zero if s1 is equal to s2.
126 * - Greater than zero if s1 is greater than s2.
127 */
128int strcmp_case_insensitive(char *s1, char *s2) {
129 register char *ptr1, *ptr2;
130
131 ptr1 = s1;
132 ptr2 = s2;
133 while (*ptr1 && *ptr2 && tolower(*ptr1) == tolower(*ptr2)) {
134 ptr1++;
135 ptr2++;
136 }
137 return ((int)(*ptr1 - *ptr2));
138}
139
140/**
141 * @brief Compares up to a specified number of characters of two strings in a case-insensitive manner.
142 *
143 * This function compares the first n characters of two null-terminated strings without considering
144 * the case of the characters. It returns an integer less than, equal to, or greater than zero
145 * if the first n characters of the first string are found, respectively, to be less than, to match,
146 * or be greater than the second string.
147 *
148 * @param s1 The first string to compare.
149 * @param s2 The second string to compare.
150 * @param n The maximum number of characters to compare.
151 *
152 * @return An integer indicating the relationship between the strings up to n characters:
153 * - Less than zero if s1 is less than s2.
154 * - Zero if the first n characters of s1 are equal to s2.
155 * - Greater than zero if s1 is greater than s2.
156 */
157int strncmp_case_insensitive(char *s1, char *s2, long n) {
158 register char *ptr1, *ptr2;
159 register long i;
160
161 ptr1 = s1;
162 ptr2 = s2;
163 i = 0;
164 while (i < n && *ptr1 && *ptr2 && tolower(*ptr1) == tolower(*ptr2)) {
165 ptr1++;
166 ptr2++;
167 i++;
168 }
169
170 if (i == n)
171 return (0);
172
173 return ((int)(*ptr1 - *ptr2));
174}
long match_string(char *string, char **option, long n_options, long mode)
Matches a given string against an array of option strings based on specified modes.
int strncmp_case_insensitive(char *s1, char *s2, long n)
Compares up to a specified number of characters of two strings in a case-insensitive manner.
int strcmp_case_insensitive(char *s1, char *s2)
Compares two strings in a case-insensitive manner.
int wild_match(char *string, char *template)
Determine whether one string is a wildcard match for another.
Definition wild_match.c:49