¿Cuál es el enfoque general para traducir glibc ctype.h a JavaScript? Creo que podría hacerlo, pero no encuentro las tablas y el bitshifting que los implementa en el código fuente de C. ¿Cuál es la técnica más óptima aquí?
isalnum(c) isalpha(c) iscntrl(c) isdigit(c) islower(c) isgraph(c) isprint(c) ispunct(c) isspace(c) isupper(c) isxdigit(c) isblank(c)Parece que están utilizando todo tipo de técnicas para generar estas funciones, tal vez dependiendo de la arquitectura. Pero, ¿cuál es la esencia de lo que se debe hacer para traducir esto manualmente a JavaScript? Parece que están usando tablas de algún tipo, pero tampoco puedo encontrarlas en la fuente.
Mirar la fuente openbsd ctype.h me acerca un poco más, pero aún me faltan las tablas, y no estoy seguro de si ese es el enfoque más optimizado para usar con JavaScript. Por ejemplo:
__only_inline int isdigit(int _c) { return (_c == -1 ? 0 : ((_ctype_ + 1)[(unsigned char)_c] & _N)); } No veo de dónde obtienen el & _N , y qué significa o proviene el (_ctype_ + 1)[index] .
Definen _ctype_ como:
extern const char *_ctype_; Pero al no ser tan experto en C, no estoy seguro de cómo interpretar la parte extern o dónde puedo encontrar la implementación de esta tabla. Tal vez sea ctype_.c , pero aún no estoy seguro de qué hacer con él.
Hablando sobre la implementación de OpenBSD:
Lo que ha encontrado es una tabla de búsqueda llena de máscaras de bits, con un tamaño que coincide con el rango de un unsigned char (0-255), que abarca la tabla ASCII (0-127).
El rango superior (128-255) se rellena con ceros.
Tenga en cuenta que hay un byte anterior, que le da a todo un desplazamiento de +1 .
Las máscaras individuales se definen en la parte superior de ctype.h :
#define _U 0x01 #define _L 0x02 #define _N 0x04 #define _S 0x08 #define _P 0x10 #define _C 0x20 #define _X 0x40 #define _B 0x80Tenga en cuenta que sus representaciones binarias son cada una un bit único y distinto.
Las funciones isXXX reciben su argumento como int , que, después de una prueba inicial de EOF ( -1 ), se sujeta a un unsigned char . Este valor decimal se usa para indexar la tabla de búsqueda, recuperando un valor que representa las cualidades de cada carácter ASCII.
Por ejemplo, los primeros 32 caracteres de la tabla ASCII son caracteres de control , indicados aquí con la máscara _C .
LF , o salto de línea , es tanto un carácter de control como de espacio . Su valor decimal es 10 ( 0xA ).
Al encontrar este índice en la tabla de búsqueda, vemos que la máscara está formada por un operador OR bit a bit de _C con _S , como en _C|_S .
Las funciones isXXX comprueban las cualidades con AND ( & ) a nivel de bits y la máscara de bits adecuada.
Por ejemplo, isalnum comprueba mayúsculas, minúsculas y valores numéricos con la máscara ( _U | _L (_U|_L|_N) .
El mismo enfoque se puede tomar en JavaScript. Apenas:
const _U = 0x01; const _L = 0x02; const _N = 0x04; /* ... */ const _X = 0x40; const lookup = { 'A': _U | _X, /* ... */ '0': _N, /* ... */ 'e': _L | _X, 'p': _L, }; const get = c => lookup[c] ?? 0; const isupper = c => get(c) & _U; const isxdigit = c => get(c) & (_N | _X); for (let letter of "Apple0") console.log(isupper(letter), isxdigit(letter)); Tenga en cuenta que todo aquí es más o menos con respecto a la configuración regional "C". Cambiar de lugar cambia el comportamiento de estas funciones ( man 7 locale ).