Principal Clipper P-Code Sitios favoritos

    El año 2000 ya está aquí. Y los sistemas que utilicen el reconocimiento de fechas mediante 2 dígitos para el año y no tengan el SET EPOCH, detectarán el año 2000 como 1900. Con las concecuencias que esto acaree segun la importancia del sistema en cuestión.

Pensando que la solución para esos sistemas era tan simple como agregar el SET EPOCH, me puse a investigar en el P-Code del Clipper como era la solución. La instrucción SET EPOCH TO 1980 es traducida por el pre-procesador a SET(5,1980). La cual es traducida a P-Code por el Clipper en las siguientes instrucciones:

0000 13 __ __ SYMF[SET]
0003 3b 05 00 PUSHW 5
0006 3b bc 07 PUSHW 1980
0009 27 02 00 DO(2)

Como se puede ver, la solución esta a 12 bytes de distancia. Pero ¿cómo insertamos estos 12 bytes dentro de un programa?. Primero pensé que era una cuestión de analizar programa por programa para ver donde se podían sacar ciertas instrucciones o reemplazarlas por otras para poder ocupar menos espacio y lograr introducir estos 12 bytes.
Luego de comparar unos cuantos programas, descubri que hay ciertas funciones que existen en todos los programas y pueden ser utilizadas para ingresar estas instrucciones. A partir de la version 5.2, se ejecutan las siguientes funciones antes de comenzar con el programa: CLIPINIT, __SETHELPK.

El CLIPINIT, declara la variable GetList y ejecuta el ErrorSys para declarar el manejador de errores.

INIT PROCEDURE CLIPINIT()
PUBLIC GetList:={}
ERRORSYS()
RETURN

El __SETHELPK, declara la tecla F1 para que llame a la funcion __XHELP, que seguramente llama la funcion HELP, si es que existe. En el manual está especificado y en las NG, en el apartado dedicado a SET KEY.

INIT FUNCTION __SETHELPK()
SET KEY K_F1 TO __XHELP
RETURN NIL

Yo pregunto, ¿cuántos de ustedes han utilizado esta declaración de la variable F1 hacia la función HELP? Muy pocos. En todo caso seguramente han declarado nuevamente el SET KEY K_F1 TO xxx.

Mi primera versión del arreglo, fue modificar la funcion __SETHELPK, para que declarara el SET EPOCH en lugar del SET KEY. Pero al menos en mis pruebas bajo 5.2 y 5.3, no funcionaron, es como si el __SETHELPK no fuera ejecutado, y por tanto el SET EPOCH no ejecutado. En la segunda versión, modifique el CLIPINIT, para que llame al __SETHELPK. Asi que la segunda versión modifica los procedimientos para que queden de la siguiente forma:

INIT PROCEDURE CLIPINIT()
PUBLIC GetList:={}
__SETHELPK()
RETURN

INIT FUNCTION __SETHELPK()
SET EPOCH TO 1980
ERRORSYS()
RETURN NIL

Luego, y gracias a la colaboración de Fernando Jacinto Alvarez, descubrí que en la versión 5.01, no existe el CLIPINIT, sino que existe __APPINIT, que es algo parecido, pero que solamente declara la variable GetList, ya que el ERRORSYS es llamado automáticamente. Tambien esta la funcion __SETHELPK, y en las primeras pruebas, descubrí que tampoco se ejecuta cuando se inicia. Entonces la modificación fué la siguiente. Renombrar las funciones, con lo que en lugar de ejecutarse el codigo de __APPTINIT, se ejecuta el de __SETHELPK. En este lugar reemplazo el código por el siguiente:

FUNCTION __SETHELPK()
SET EPOCH TO 1980
PUBLIC GETSYS:={}
RETURN NIL

Novedad: Gracias a la colaboración de Lucas Guardino Irazoqui, he revisado el programa y ahora aparentemente funciona también para reparar los .PLL, al menos, fue probado con BASE52.PLL y el programa ha funcionado y reconocido el año 2000. Aunque los .PLL tienen un control de checksum, posiblemente no sea sobre todo el archivo y la modificación realizada sobre el código no ha producido el error de checksum sobre el .PLL modificado. Sin embargo esto no quiere decir que sobre otros sistemas no pueda dar error.

Consideraciones a tener en cuenta para poder utilizar los programas de reparación.

El sistema no tiene ningun tipo de garantias y las acciones realizadas con el quedan bajo la responsabilidad del que las realiza. Esto es porque realizar modificaciones en programas con registros de propiedad (copyright), puede acarrear sus consecuencias.
No han sido vastamente probados, por lo cual pueden llegar a producir modificaciones no previstas.
No pueden reparar programas que hayan sido comprimidos (BLINKER con opción COMPRESS).
No reparan sistemas con .PLL ni los .PLL.
Ahora Si
No han sido probados con sistemas con overlays estáticos en archivos separados .OVL.
No controla si es necesario que la llamada al __SETHELPK, declare la tecla F1.
Si la función CLIPINIT, es redeclarada, el reparador quizas no pueda realizar la modificación.
Si no se utiliza el subsistema GET, puede que la función __SETHELPK no esté declarada, por lo tanto tampoco es posible realizar la modificación.

Y2Kfix para Clipper 5.2 y 5.3

Y2Kfix para Clipper 5.01

    comentarios, sugerencias y reportes de errores a: