00001 /**********************************************************/ 00002 /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ 00003 /* 00004 Copyright: 1993 - Grupo de Voz (DAET) ETSII/IT-Bilbao 00005 00006 Nombre fuente................ uti_misc.c 00007 Nombre paquete............... uti.h 00008 Lenguaje fuente.............. C (BC31,GCC) 00009 Estado....................... Utilizable 00010 Dependencia Hard/OS.......... - 00011 Codigo condicional........... - 00012 00013 Codificacion................. Borja Etxebarria 00014 00015 Version dd/mm/aa Autor Comentario 00016 ------- -------- -------- ---------- 00017 2.1.0 22/07/97 Borja show_srcpos 00018 2.0.1 01/07/97 Borja fround() pasa a otro modulo 00019 2.0.0 01/05/97 Borja mix de xfiles, syst, xsyst, fname, vstr... 00020 1.2.2 28/04/97 Borja bug en fgetlns() 00021 1.2.1 08/04/97 Borja retoques en documentacion 00022 1.2.0 31/07/96 Borja die 00023 1.1.0 30/07/96 Borja ftrunc, fmoven, finsn, fdeln. 00024 1.0.0 11/01/93 Borja Codificacion inicial. 00025 00026 ======================== Contenido ======================== 00027 Funciones diversas. 00028 Gestion y busqueda de etiquetas en arrays de cadenas. 00029 =========================================================== 00030 */ 00031 /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ 00032 /**********************************************************/ 00033 00034 #include <stdio.h> 00035 #include <stdlib.h> 00036 #include <string.h> 00037 #include <stdarg.h> 00038 #include <math.h> 00039 00040 #include "uti.h" 00041 00042 /**********************************************************/ 00043 /* busca {str} en el array de {nstrs} cadenas {strarr}. Si lo encuentra, 00044 {devuelve} el indice en el array. Si no lo encuentra, {devuelve} -1. 00045 Si se encuentra con una etiqueta ambigua, {devuelve} -2. 00046 Codigo para las longitudes, {lcode} = 00047 -2 como -1, pero si hay un match exacto se admite aunque sea ambiguo 00048 -1 si se permite strlen(strarr{})<strlen(str) 00049 0 si strlen(strarr{})==strlen(str) 00050 1 si se permite strlen(strarr{})>strlen(str) 00051 2 como 1, pero si hay un match exacto se admite aunque sea ambiguo 00052 Si {case_sensitive}==0 no distingue mayusculas de minusculas */ 00053 00054 int str_match( const char * const *strarr, int nstrs, 00055 const char * str, int lcode, int case_sensitive ) 00056 { 00057 int i, mtch, l1l2match, code; 00058 size_t l, l1, l2; 00059 00060 mtch = -1; 00061 l1l2match = -1; 00062 l=l1=l2=0; 00063 00064 if (lcode>0) 00065 l= l1 = strlen(str); 00066 for ( i=0; i<nstrs; i++ ) { 00067 if (lcode!=0) { 00068 l2=strlen(strarr[i]); 00069 if (lcode<0) l=l2; 00070 code = ( case_sensitive ? strncmp(str,strarr[i],l) : 00071 strnicmp(str,strarr[i],l) ); 00072 } 00073 else 00074 code = ( case_sensitive ? strcmp(str,strarr[i]) : 00075 stricmp(str,strarr[i]) ); 00076 00077 if (!code) { 00078 if ((lcode!=0) && (l1==l2)) l1l2match=i; 00079 if (mtch!=-1) 00080 mtch = -2; 00081 else 00082 mtch = i; 00083 } 00084 } 00085 00086 if ((mtch==-2)&&(l1l2match!=-1)&&((lcode>1)||(lcode<-1))) 00087 return l1l2match; 00088 00089 return(mtch); 00090 } 00091 00092 /**********************************************************/ 00093 /* Como str_match(), pero si no encuentra {str} en {strarr} o 00094 hay ambiguedad, imprime error y termina el programa. */ 00095 00096 int xstr_match( const char * const *strarr, int nstrs, const char * str, 00097 int lcode, int case_sensitive ) 00098 { 00099 int i; 00100 i = str_match(strarr,nstrs,str,lcode,case_sensitive); 00101 if (i<0) { 00102 cdie_beep(i==-2,"error: ambiguous label (%s)",str); 00103 die_beep("error: unknown label (%s)",str); 00104 } 00105 return(i); 00106 } 00107 00108 /**********************************************************/ 00109 /* busca {label} en el array de etiquetas {labelarr} de {nlabels} 00110 elementos. 00111 {devuelve} un indice a la etiqueta que encaje dentro del array. 00112 Si no encaja ninguna {devuelve} -1, y si hay ambiguedad -2. 00113 Si {allow_partial} es distinto de cero, {label} puede ser mas corta que 00114 las etiquetas de {labelarr} (abreviada). 00115 Ademas se elimina el '=valor' de {label} (label=valor) para comparar. 00116 Si {case_sensitive}==0 no distingue mayusculas de minusculas */ 00117 00118 int label_match( const char * const *labelarr, int nlabels, 00119 const char * label, int case_sensitive, 00120 int allow_partial ) 00121 { 00122 int i; 00123 char c, *cp; 00124 00125 c = (*(cp=str_assignptr(label))); 00126 *cp = 0; 00127 i = str_match(labelarr,nlabels,label,(allow_partial?2:0),case_sensitive); 00128 *cp = c; 00129 00130 return(i); 00131 } 00132 00133 /**********************************************************/ 00134 /* Como label_match(), pero si no encuentra {label} en {labelarr} o 00135 hay ambiguedad, imprime error y termina el programa. */ 00136 00137 int xlabel_match( const char * const *labelarr, int nlabels, 00138 const char * label, int case_sensitive, int allow_partial ) 00139 { 00140 int i; 00141 i = label_match(labelarr,nlabels,label,case_sensitive,allow_partial); 00142 if (i<0) { 00143 cdie_beep(i==-2,"error: ambiguous label (%s)",label); 00144 die_beep("error: unknown label (%s)",label); 00145 } 00146 return(i); 00147 } 00148 00149 /**********************************************************/ 00150 /* Similar a xlabel_match(), pero si str=="" {devuelve} {deval} */ 00151 00152 int str2k( const char * str, const char * const *labels, 00153 int defval, int case_sensitive, int allow_partial ) 00154 { 00155 if ((strlen(str)==0)&&(defval>=0)) 00156 return(defval); 00157 return xlabel_match( labels,nptrs((const void * const *)labels),str, 00158 case_sensitive,allow_partial); 00159 } 00160 00161 /**********************************************************/ 00162 /* {devuelve} el numero de punteros de un array de punteros, terminado 00163 con puntero a NULL. Si {ptrarray}==NULL {devuelve} 0 */ 00164 00165 int nptrs( const void * const *ptrarray ) 00166 { 00167 int i = 0; 00168 00169 if (ptrarray!=NULL) { 00170 while (ptrarray[i]!=NULL) 00171 i++; 00172 } 00173 00174 return(i); 00175 } 00176 00177 /**********************************************************/ 00178 /* imprime nombre fichero y posicion. Usado para mensajes 00179 de error, utilizando normalmente los macros del preprocesador 00180 __FILE__ y __LINE__ (usar show_srcpos()). */ 00181 00182 void __show_srcpos( const char *file, int line ) 00183 { 00184 fprintf(stderr,"[%s:%d] ",file,line); 00185 } 00186 00187 /**********************************************************/