Criterios que conviene sostener al tocar esta biblioteca. Los tres primeros
salieron de errores reales que costaron encontrar.

1. No terminar el proceso. Ninguna funcion debe llamar a exit(): es una
   biblioteca y no sabe en que contexto la usan. Los errores se informan
   con el valor de retorno, con los codigos de src/table.h, y el llamador
   decide. Cero es exito y los negativos son error: esa es la unica
   convencion, ninguna funcion devuelve 1 para decir que anduvo.

2. Limpiar lo que se reserva. add_memory() de mem_util usa malloc y
   realloc, que no inicializan. Toda estructura recien reservada hay que
   ponerla en cero, y los huecos de un arreglo que crece, en NULL. Sin eso
   los punteros no asignados tienen basura del heap y cualquier recorrido
   o liberacion posterior revienta.

3. Un solo dueño por cada cadena. create_cell() y create_table() hacen
   strdup de lo que reciben: quien las llama no debe duplicar antes, y si
   la cadena venia de asprintf o de sscanf con %m, tiene que liberarla
   despues. Asi se perdian mas de mil bloques por carga.

4. No escribir en la salida del programa que usa la biblioteca. Las
   trazas van a stderr y detras de verbose; ninguna funcion imprime sola.
   La excepcion son las funciones de volcado --print_table,
   print_list_tables, print_index_table, print_views, print_cell y
   get_view_info--: ahi el llamador pidio la salida, y por eso van a
   stdout sin condicion. Si una funcion no se llama print_algo, no
   imprime.

   Cuidado con la forma en que se rompio esto antes: hay lineas
   "if (verbose>10) {}" con el cuerpo vacio y el printf suelto en la
   linea siguiente. Se ve como si estuviera protegido y no lo esta.

5. Mirar lo que devuelve el accesor. get_table_pointer y get_view_pointer
   comprueban el rango, avisan por *error y devuelven NULL. Eso no sirve de
   nada si quien las llama desreferencia de una, que es lo que pasaba en 38
   de los 39 lugares: 18 de 20 funciones publicas se caian con un numero de
   tabla que no existe. Despues de cada llamada va la comprobacion de NULL,
   y lo que se devuelve depende del tipo: NULL las que devuelven puntero,
   el codigo de error las que devuelven int, y cero las que devuelven
   unsigned int, que avisan solo por *error. Adentro de un for, continue.

6. Ojo con los contadores. occupy no siempre significa lo mismo:
   tablelist.occupy es el indice de la ultima tabla, no la cantidad;
   cell_occupy y view_occupy si son cantidades; line_occupy lo pisa
   set_line_occupy con el numero de linea en curso. Antes de recorrer un
   arreglo, verificar cual de los tres casos es.

7. X repetido no es un error. Dos filas con la misma coordenada X
   representan un salto, y esa semantica hay que conservarla: no
   deduplicar ni rechazar. Lo que si falta comprobar es que X sea no
   decreciente, y eso si se comprueba ahora en create_search_view_num.

Lo que podria crecer el formato del archivo de datos
----------------------------------------------------

En viejos/flex hay un experimento de abril de 2024, de cuando se probaron
tres formas de leer una tabla: una gramatica con flex y bison (flex.l y
calc.y), un lexer escrito a mano (lexeralt.c) y expresiones regulares con
PCRE2 (pcre2demo.c). Gano el escrito a mano, y de ahi salio manual_lexer.c.
La gramatica, flex.l y calc.y, esta ahora en viejos/ejemplo-01 y compila
contra la biblioteca de hoy, aunque no se sabe que entrada espera; su LEAME
lo cuenta. El Makefile de viejos/flex ya no la nombra: el lexer1 que la
usaba se fue con el main.c que le servia de programa, y no se construia desde
antes de 2021 por razones ajenas. Lo que sigue
sirviendo de ahi no es el codigo sino la lista de lo que aquel formato
entendia y el de hoy no, con lo que costaria traer cada cosa.

El riesgo que atraviesa todo: cada caracter que se vuelve especial se lo
saca a los datos. Una tabla es texto arbitrario. Hoy solo son especiales
el #, la coma en los .csv y los separadores. Antes de agregar uno, ver si
puede aparecer adentro de un dato.

  * Comentarios /* */ de varias lineas. Barato, un estado mas en el bucle
    de manual_lexer.c que se traga todo hasta el */. Encaja con lo que ya
    hay: una linea que es solo comentario no cuenta como linea de la tabla.

  * Barra invertida al final de la linea para continuarla en la siguiente.
    Barato, suprimir el tratamiento del \n que sigue.

  * Punto y coma como fin de linea logica, y // como comentario. Baratos de
    escribir y caros de verdad: hoy los dos son dato normal. Comprobado, una
    celda x;y se lee <x;y> y p//q se lee <p//q>. Si se vuelven especiales,
    cualquier tabla con un punto y coma o una URL adentro se parte al medio.
    Habria que hacerlos opcionales, y eso es mas trabajo que la
    funcionalidad.

  * \include(archivo), con una pila de archivos. Es la mas grande y la que
    mas rinde, y esta a medio hacer: la tabla ya guarda varios archivos
    fuente (files_pointers, files_occupy) y ya existe new_source() para
    registrarlos, o sea que la estructura se penso para esto. Falta que el
    lexer lea de una pila y no de un solo FILE*: hoy hay un unico
    getc(fplt) y la rama de EOF termina el analisis entero, y habria que
    cambiarla por "si hay archivo padre, volver a el; si no, terminar", mas
    la guarda de recursion y resolver la ruta relativa al archivo que
    incluye. Unas cincuenta lineas y un par de pruebas. Media jornada.

  * Comandos \nombre(...). Esto ya no es el lexer, es inventar un lenguaje:
    hay que decidir que comandos hay y que hacen. No se estima hasta saber
    para que se quieren.

A favor de meterse: hay 219 comprobaciones en tests/, asi que romper algo se
nota enseguida.


Los ejemplos no entran en SUBDIRS, se arman a mano con make -C examples, pero
enlazan contra el arbol de fuentes: los encabezados de ../src y la biblioteca
estatica que deja libtool, y siempre le preguntan a src/ si hay algo que
recompilar. Un cambio en src/ llega solo. Las banderas estan en un solo lugar,
examples/comun.mk. Son dos, el 02 y el 04, y los dos corren con "make -C
examples prueba". El que era el 01 esta en viejos/ejemplo-01: compila contra
el arbol de fuentes, pero no se sabe que entrada espera su analizador, que
define un lenguaje propio con \table(...) e \include(...); lo que se averiguo
de el esta en su LEAME.

Para construir desde el repositorio: autoreconf --install && ./configure && make
Para medir fugas:  valgrind --leak-check=full ./programa
