IMPROVES-i5 full fix on sequal_full()

This commit is contained in:
2026-05-22 20:28:13 -03:00
parent aabab06352
commit d2e5dfce38
3 changed files with 34 additions and 24 deletions

View File

@@ -89,7 +89,8 @@ cmp11sht v20251221.0718 (C) 2025 by Ruben C. Benante (MIT Lic)\n\n"
{ {
if(opt==3) printf("cmp11sht: string\n"); if(opt==3) printf("cmp11sht: string\n");
errno = 0; errno = 0;
res = sequal_full(argv[1], argv[2], delta, &ratio, s1, s2); res = sequal_full(argv[1], argv[2], delta, &ratio,
s1, LEVN_SBUFF, s2, LEVN_SBUFF);
if(errno == EINVAL) if(errno == EINVAL)
res = 3; /* error → CLI exit 3 */ res = 3; /* error → CLI exit 3 */
else if(res > 0) else if(res > 0)

View File

@@ -42,44 +42,48 @@ int sequal(char *a, char *b, float shold)
{ {
float ratio; float ratio;
char s1[LEVN_SBUFF], s2[LEVN_SBUFF]; char s1[LEVN_SBUFF], s2[LEVN_SBUFF];
return sequal_full(a, b, shold, &ratio, s1, s2); return sequal_full(a, b, shold, &ratio, s1, LEVN_SBUFF, s2, LEVN_SBUFF);
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
int sequal_full(char *a, char *b, float shold, float *ratio, char *s1, char *s2) int sequal_full(char *a, char *b, float shold, float *ratio,
char *s1, size_t s1_size,
char *s2, size_t s2_size)
{ {
int i; size_t i;
if(!a || !b || !s1 || !s2 || !ratio) if(!a || !b || !s1 || !s2 || !ratio || s1_size == 0 || s2_size == 0)
{ {
errno = EINVAL; errno = EINVAL;
return 0; return 0;
} }
/* remove accents */ /* remove accents (asciify NUL-terminates within s1_size / s2_size) */
asciify(a, s1, LEVN_SBUFF); asciify(a, s1, s1_size);
asciify(b, s2, LEVN_SBUFF); asciify(b, s2, s2_size);
/* trim spaces (leading, trailing, and internal collapse) */ /* trim spaces (leading, trailing, and internal collapse) */
trim(s1); trim(s1);
trim(s2); trim(s2);
/* lowercase */ /* lowercase, bounded by each buffer's actual size */
for(i=0; i<LEVN_SBUFF && s1[i]; i++) for(i=0; i<s1_size && s1[i]; i++)
s1[i] = (char)tolower((unsigned char)s1[i]); s1[i] = (char)tolower((unsigned char)s1[i]);
for(i=0; i<LEVN_SBUFF && s2[i]; i++) for(i=0; i<s2_size && s2[i]; i++)
s2[i] = (char)tolower((unsigned char)s2[i]); s2[i] = (char)tolower((unsigned char)s2[i]);
i=strcmp(s1, s2);
if(!i)
{ {
*ratio=1.0; int cmp = strcmp(s1, s2);
return 0; if(cmp == 0)
{
*ratio = 1.0;
return 0;
}
*ratio = shit11(s1, s2);
if(*ratio > shold)
return 0;
return (cmp < 0) ? -1 : 1;
} }
*ratio = shit11(s1, s2);
if(*ratio > shold)
return 0;
return (i < 0)? -1 : 1;
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */

View File

@@ -9,7 +9,9 @@
#ifndef LIB11SHT_H #ifndef LIB11SHT_H
#define LIB11SHT_H #define LIB11SHT_H
#define LEVN_SBUFF 256 /* min size for s1/s2 buffers and bounded input */ #include <stddef.h> /* size_t */
#define LEVN_SBUFF 256 /* recommended size for s1/s2 buffers */
/* Compare similarity between two strings (after asciify + trim + lowercase). /* Compare similarity between two strings (after asciify + trim + lowercase).
* Symmetric in shape with fequal(a, b, delta). * Symmetric in shape with fequal(a, b, delta).
@@ -31,11 +33,14 @@ int sequal(char *a, char *b, float shold);
* (e.g. cmp11sht CLI's -o / -n flags). * (e.g. cmp11sht CLI's -o / -n flags).
* *
* Extra parameters: * Extra parameters:
* ratio out: Levenshtein similarity 0.0..1.0 (1.0 on exact-after-normalize) * ratio out: Levenshtein similarity 0.0..1.0 (1.0 on exact-after-normalize)
* s1, s2 out: caller-provided buffers (>= LEVN_SBUFF) filled with the * s1, s2 out: caller-provided buffers filled with the normalized inputs
* normalized inputs * s1_size size of s1 in bytes (writes capped at s1_size-1 + final NUL)
* s2_size size of s2 in bytes (writes capped at s2_size-1 + final NUL)
*/ */
int sequal_full(char *a, char *b, float shold, float *ratio, char *s1, char *s2); int sequal_full(char *a, char *b, float shold, float *ratio,
char *s1, size_t s1_size,
char *s2, size_t s2_size);
/* Compare two floats within ±delta. /* Compare two floats within ±delta.
* Returns: * Returns: