Aggiunto include di stdlib.h

git-svn-id: svn://10.65.10.50/trunk@5637 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
augusto 1997-11-18 15:38:59 +00:00
parent b0fbe67860
commit 8b659731f8

View File

@ -1,6 +1,7 @@
#ifndef __REGEXP_H #ifndef __REGEXP_H
#include <regexp.h> #include <regexp.h>
#endif #endif
#include <stdlib.h>
// codici di ritorno della matche() // codici di ritorno della matche()
#define regexp_MATCH_PATTERN (6) // pattern non valido #define regexp_MATCH_PATTERN (6) // pattern non valido
@ -24,173 +25,173 @@ HIDDEN bool is_pattern(const char *pat); // ritorna TRUE se la stringa
HIDDEN bool is_valid_pattern(const char *pat, int *err= NULL); // ritorna TRUE se la stringa è un pattern valido, indica un codice di ritorno della classe regexp_PATTERN nel secondo parametro HIDDEN bool is_valid_pattern(const char *pat, int *err= NULL); // ritorna TRUE se la stringa è un pattern valido, indica un codice di ritorno della classe regexp_PATTERN nel secondo parametro
HIDDEN bool is_pattern(const char *p) { HIDDEN bool is_pattern(const char *p) {
while (*p) { while (*p) {
switch (*p++) { switch (*p++) {
case '?': case '?':
case '*': case '*':
case '[': case '[':
case '\\': case '\\':
return TRUE; return TRUE;
} }
} }
return FALSE; return FALSE;
} }
HIDDEN bool is_valid_pattern(const char *p, int *error_type) { HIDDEN bool is_valid_pattern(const char *p, int *error_type) {
if (error_type != NULL) *error_type= regexp_PATTERN_VALID; // inizializzazione del tipo d'errore if (error_type != NULL) *error_type= regexp_PATTERN_VALID; // inizializzazione del tipo d'errore
while (*p) { // ciclo all'interno del pattern fino a fine stringa while (*p) { // ciclo all'interno del pattern fino a fine stringa
switch(*p) { // determinazione del tipo di wild card nel pattern switch(*p) { // determinazione del tipo di wild card nel pattern
case '\\': // controllo dell'escape, non può essere a fine pattern case '\\': // controllo dell'escape, non può essere a fine pattern
if (!*++p) { if (!*++p) {
if (error_type != NULL) *error_type= regexp_PATTERN_ESC; if (error_type != NULL) *error_type= regexp_PATTERN_ESC;
return FALSE; return FALSE;
} }
p++; p++;
break; break;
case '[': // controllo della costruzione del costrutto [..] case '[': // controllo della costruzione del costrutto [..]
p++; p++;
if (*p == ']') { // se il prossimo carattere è ']' il costrutto è vuoto if (*p == ']') { // se il prossimo carattere è ']' il costrutto è vuoto
if (error_type != NULL) *error_type= regexp_PATTERN_EMPTY; if (error_type != NULL) *error_type= regexp_PATTERN_EMPTY;
return FALSE; return FALSE;
} }
if (!*p) { // se si è a fine stringa il costrutto non è chiuso if (!*p) { // se si è a fine stringa il costrutto non è chiuso
if (error_type != NULL) *error_type= regexp_PATTERN_CLOSE; if (error_type != NULL) *error_type= regexp_PATTERN_CLOSE;
return FALSE; return FALSE;
} }
while (*p != ']') { // ciclo fino a fine costrutto [..] while (*p != ']') { // ciclo fino a fine costrutto [..]
if (*p == '\\') { // controllo per gli escape if (*p == '\\') { // controllo per gli escape
p++; p++;
if (!*p++) { // controllo che l'escape non sia a fine pattern if (!*p++) { // controllo che l'escape non sia a fine pattern
if (error_type != NULL) *error_type= regexp_PATTERN_ESC; if (error_type != NULL) *error_type= regexp_PATTERN_ESC;
return FALSE; return FALSE;
} }
} else p++; } else p++;
if (!*p) { // se si è a fine stringa il costrutto non è chiuso if (!*p) { // se si è a fine stringa il costrutto non è chiuso
if (error_type != NULL) *error_type= regexp_PATTERN_CLOSE; if (error_type != NULL) *error_type= regexp_PATTERN_CLOSE;
return FALSE; return FALSE;
} }
if (*p == '-') { // controllo di un eventuale range if (*p == '-') { // controllo di un eventuale range
if (!*++p || *p == ']') { // deve esistere una fine del range if (!*++p || *p == ']') { // deve esistere una fine del range
if (error_type != NULL) *error_type= regexp_PATTERN_RANGE; if (error_type != NULL) *error_type= regexp_PATTERN_RANGE;
return FALSE; return FALSE;
} else { } else {
if (*p == '\\') p++; // controllo degli escape if (*p == '\\') p++; // controllo degli escape
if (!*p++) { // controllo che l'escape non sia a fine pattern if (!*p++) { // controllo che l'escape non sia a fine pattern
if (error_type != NULL) *error_type= regexp_PATTERN_ESC; if (error_type != NULL) *error_type= regexp_PATTERN_ESC;
return FALSE; return FALSE;
} }
} }
} }
} }
break; break;
case '*': // tutti gli altri caratteri sono elementi validi del pattern case '*': // tutti gli altri caratteri sono elementi validi del pattern
case '?': case '?':
default: default:
p++; // caratteri normali p++; // caratteri normali
break; break;
} }
} }
return TRUE; return TRUE;
} }
HIDDEN int matche_after_star(const char *p, const char *t) { HIDDEN int matche_after_star(const char *p, const char *t) {
int match= 0; int match= 0;
while (*p == '?' || *p == '*') { // salto degli eventuali '*' e '?' while (*p == '?' || *p == '*') { // salto degli eventuali '*' e '?'
if (*p == '?') // salto di un carattere per ciascun '?' if (*p == '?') // salto di un carattere per ciascun '?'
if (!*t++) return regexp_MATCH_ABORT; // se la stringa termina qui non c'è coincidenza if (!*t++) return regexp_MATCH_ABORT; // se la stringa termina qui non c'è coincidenza
p++; // posizionamento sul prossimo carattere del pattern p++; // posizionamento sul prossimo carattere del pattern
} }
if (!*p) return regexp_MATCH_VALID; //se il pattern è concluso c'è coincidenza if (!*p) return regexp_MATCH_VALID; //se il pattern è concluso c'è coincidenza
int nextp= *p; // prelevamento del prossimo carattere, normale o '[' int nextp= *p; // prelevamento del prossimo carattere, normale o '['
if (nextp == '\\') { if (nextp == '\\') {
nextp= p[1]; nextp= p[1];
if (!nextp) return regexp_MATCH_PATTERN; // se il pattern termina qui non è valido if (!nextp) return regexp_MATCH_PATTERN; // se il pattern termina qui non è valido
} }
do { // ciclo fino a conclusione di stringa o pattern do { // ciclo fino a conclusione di stringa o pattern
if (nextp == *t || nextp == '[') match= matche(p, t); // è necessario che il carattere corrente del testo coincida con il carattere corrente del pattern, oppure che il pattern abbia un inizio di costrutto [..] if (nextp == *t || nextp == '[') match= matche(p, t); // è necessario che il carattere corrente del testo coincida con il carattere corrente del pattern, oppure che il pattern abbia un inizio di costrutto [..]
if (!*t++) match= regexp_MATCH_ABORT; // se la stringa termina qui non c'è coincidenza if (!*t++) match= regexp_MATCH_ABORT; // se la stringa termina qui non c'è coincidenza
} while (match != regexp_MATCH_VALID && match != regexp_MATCH_ABORT && match != regexp_MATCH_PATTERN); } while (match != regexp_MATCH_VALID && match != regexp_MATCH_ABORT && match != regexp_MATCH_PATTERN);
return match; // ritorno del risultato return match; // ritorno del risultato
} }
HIDDEN int matche(const char *p, const char *t) { HIDDEN int matche(const char *p, const char *t) {
for (; *p; p++, t++) { for (; *p; p++, t++) {
if (!*t) // se si è alla fine della stringa, il confronto è concluso if (!*t) // se si è alla fine della stringa, il confronto è concluso
return (*p == '*' && *++p == '\0') ? regexp_MATCH_VALID : regexp_MATCH_ABORT; return (*p == '*' && *++p == '\0') ? regexp_MATCH_VALID : regexp_MATCH_ABORT;
switch (*p) { // determina il tipo di wild card del pattern switch (*p) { // determina il tipo di wild card del pattern
case '?': // carattere singolo, qualunque carattere coincide case '?': // carattere singolo, qualunque carattere coincide
break; break;
case '*': // sottostringa, coincide qualunque sequenza di caratteri case '*': // sottostringa, coincide qualunque sequenza di caratteri
return matche_after_star (p, t); return matche_after_star (p, t);
case '[': { // costrutto [..], controllo di coincidenza per inclusione o esclusione su un solo carattere case '[': { // costrutto [..], controllo di coincidenza per inclusione o esclusione su un solo carattere
p++; // posizionamento all'inizio del range p++; // posizionamento all'inizio del range
bool invert= FALSE; // controllo di inclusione o esclusione del costrutto bool invert= FALSE; // controllo di inclusione o esclusione del costrutto
if (*p == '!' || *p == '^') { if (*p == '!' || *p == '^') {
invert= TRUE; invert= TRUE;
p++; p++;
} }
if (*p == ']') // se si è su una chiusura di costrutto il pattern non è valido if (*p == ']') // se si è su una chiusura di costrutto il pattern non è valido
return regexp_MATCH_PATTERN; return regexp_MATCH_PATTERN;
bool member_match= FALSE; bool member_match= FALSE;
bool loop= TRUE; bool loop= TRUE;
while (loop) { while (loop) {
char range_start, range_end; // inizio e fine del range corrente char range_start, range_end; // inizio e fine del range corrente
if (*p == ']') { // se si è alla fine del costrutto il ciclo si conclude if (*p == ']') { // se si è alla fine del costrutto il ciclo si conclude
loop= FALSE; loop= FALSE;
continue; continue;
} }
if (*p == '\\') // controllo di coincidenza su un metacarattere, dopo un escape if (*p == '\\') // controllo di coincidenza su un metacarattere, dopo un escape
range_start= range_end= *++p; range_start= range_end= *++p;
else else
range_start= range_end= *p; range_start= range_end= *p;
if (!*p) return regexp_MATCH_PATTERN; // se il pattern termina non è valido if (!*p) return regexp_MATCH_PATTERN; // se il pattern termina non è valido
if (*++p == '-') { // controllo del segno di sottoinsieme if (*++p == '-') { // controllo del segno di sottoinsieme
range_end= *++p; // impostazione della fine del range range_end= *++p; // impostazione della fine del range
if (range_end == '\0' || range_end == ']') return regexp_MATCH_PATTERN; // se il costrutto [..] o il pattern terminano qui allora il pattern non è valido if (range_end == '\0' || range_end == ']') return regexp_MATCH_PATTERN; // se il costrutto [..] o il pattern terminano qui allora il pattern non è valido
if (range_end == '\\') { // la fine del range è un metacarattere if (range_end == '\\') { // la fine del range è un metacarattere
range_end= *++p; range_end= *++p;
if (!range_end) return regexp_MATCH_PATTERN; // se il pattern termina non è valido if (!range_end) return regexp_MATCH_PATTERN; // se il pattern termina non è valido
} }
p++; // posizionamento oltre il range p++; // posizionamento oltre il range
} }
if (range_start < range_end) { // confronto del carattere corrente con il costrutto, controllo della sequenzialità degli estremi del range if (range_start < range_end) { // confronto del carattere corrente con il costrutto, controllo della sequenzialità degli estremi del range
if (*t >= range_start && *t <= range_end) { if (*t >= range_start && *t <= range_end) {
member_match= TRUE; member_match= TRUE;
loop= FALSE; loop= FALSE;
} }
} else { } else {
if (*t >= range_end && *t <= range_start) { if (*t >= range_end && *t <= range_start) {
member_match= TRUE; member_match= TRUE;
loop= FALSE; loop= FALSE;
} }
} }
} }
if ((invert && member_match) || !(invert || member_match)) // controllo del risultato dell'ultimo confronto nel costrutto [..] if ((invert && member_match) || !(invert || member_match)) // controllo del risultato dell'ultimo confronto nel costrutto [..]
return regexp_MATCH_RANGE; return regexp_MATCH_RANGE;
if (member_match) { // salto del resto del costrutto se non è esclusivo if (member_match) { // salto del resto del costrutto se non è esclusivo
while (*p != ']') { while (*p != ']') {
if (!*p) return regexp_MATCH_PATTERN; // se si è a fine pattern il costrutto non è valido if (!*p) return regexp_MATCH_PATTERN; // se si è a fine pattern il costrutto non è valido
if (*p == '\\') { // salto di un confronto con un metacarattere if (*p == '\\') { // salto di un confronto con un metacarattere
p++; p++;
if (!*p) return regexp_MATCH_PATTERN; // se il pattern termina qui non è valido if (!*p) return regexp_MATCH_PATTERN; // se il pattern termina qui non è valido
} }
p++; // posizionamento sul prossimo carattere del pattern p++; // posizionamento sul prossimo carattere del pattern
} }
} }
break; break;
} }
case '\\': // confronto con un metacarattere case '\\': // confronto con un metacarattere
p++; // posizionamento sul carattere da confrontare p++; // posizionamento sul carattere da confrontare
if (!*p) return regexp_MATCH_PATTERN; // se il pattern termina qui non è valido if (!*p) return regexp_MATCH_PATTERN; // se il pattern termina qui non è valido
default: // confronto con un carattere normale default: // confronto con un carattere normale
if (*p != *t) return regexp_MATCH_LITERAL; if (*p != *t) return regexp_MATCH_LITERAL;
} }
} }
if (*t) return regexp_MATCH_END; // se la stringa non è conclusa non c'è coincidenza if (*t) return regexp_MATCH_END; // se la stringa non è conclusa non c'è coincidenza
else return regexp_MATCH_VALID; else return regexp_MATCH_VALID;
} }
bool match(const char *pat, const char *str) { bool match(const char *pat, const char *str) {
int err= matche(pat, str); int err= matche(pat, str);
return (err == regexp_MATCH_VALID); // ritorna TRUE se il pattern e la stringa coincidono return (err == regexp_MATCH_VALID); // ritorna TRUE se il pattern e la stringa coincidono
} }