viernes, noviembre 13, 2009

Harbour VS xHarbour, Las diferencias verdaderas (Parte 1)

Esta semana, charlando con Ignacio Ortiz de Zúñiga por el tema de Xailer 2.0, me recomendó la lectura de un documento publicado por Przemyslaw Czerpak sobre las diferencias mas notables entre Harbor y xHarbour.

Mucho tiempo ha pasado desde que Harbour y xHarbour separaron sus caminos, mientras la idea alrededor de Harbour era hacer un compilador compatible con CA-Clipper y nada mas, la idea alrededor de xHarbour era hacer un compilador de CA-Clipper con eXtenciones (de ahí la "X" de xHarbour = eXtended Harbour) y crear sobre un proyecto Opensource una empresa para crear distribuciones del compilador ofreciendo "algo mas", como sucede con muchos productos OpenSource.

xHarbour ofrecía varias ventajas contra Harbour, tenía mas instrucciones, estructuras como las del lenguaje "C", soporte nativo a OLE y otras florituras que a simple vista justificaban mas el uso de xHarbour contra el uso de Harbour y por ello MUCHOS usuarios nos decantamos por usar xHarbour en vez de usar Harbour.

Hoy por hoy, las cosas han cambiado MUCHO, hace mas de un año, Przemyslaw Czerpak tomó las riendas del proyecto Harbour y decidió implementar TODAS las extensiones con las que contaba xHarbour, pero hacerlo de manera personal, es decir, sin que nadie, ningún otro programador, le metiera mano al código de Harbour. El resultado es IMPRESIONANTE, al día de hoy, Harbour es un compilador mas completo, mas rápido y mas estable de xHarbour, y con las mismas extensiones.

Entre muchas cosas, hay 2 en las que la versión actual de Harbour supera a xHarbour: La compilación a 64 bits, y los multihilos (Multithreating), ya que xHarbour no genera EXEs de 64 bits, ni tiene implementada de manera confiable la programación multihilo.

En esta serie de artículos iré traduciendo el documento de Przemyslaw por partes para hacer mas entendible a todos las diferencias entre Harbour y xHarobur, lo haré en varios post ya que son mas de 3,000 líneas del documento y no tengo tiempo de hacer todo de un solo post, si no quieres esperar a la traducción, la versión completa en inglés del documento puede consultarse haciendo click aquí

Comencemos:

Soporte en tiempo de compilación para unir múltiples modulos .PRG

Clipper permite compilar muchos modulos .PRG usando @.clp y/o SET PROCEDURE TO... / DO ... [WITH ...] en un solo archivo de salida .OBJ. En tales compilaciones, soporta para cada archivo .PRG, declaraciones que afectan a todo el archivo cuando se utiliza la opción -n la cual permite usar mas de una función STATIC con el mismo nombre si dicha función es declarada en diferentes módulos PRG. Este código ilustra dicha situación:

/***** t1. prg *****/
      static s  := "t01:s"
static s1 := "t01:s1"
proc main()
? "===="
? s, s1
p1();p2();p3()
? "===="
do t2
? "===="
return
proc p1 ; ? "t01:p1"
static proc p2 ; ? "t01:p2"
static proc p3 ; ? "t01:p3"
init proc pi ; ? "init t01:pi"
exit proc pe ; ? "exit t01:pe"

/***** t2. prg *****/
static s := "t02:s"
static s2 := "t02:s2"
proc t2()
? s, s2
p1();p2();p3()
return
static proc p1 ; ? "t02:p1"
proc p2 ; ? "t02:p2"
static proc p3 ; ? "t02:p3"
init proc pi ; ? "init t02:pi"
exit proc pe ; ? "exit t02:pe"

Es necesario usar la opción -n para operaciones que afectan a todo el archivo y que usen funciones STATIC/INIT/EXIT con el mismo nombre, pero declaradas en distintos módulos. En Clipper y Harbour pueden ser compilados así:
      cl t1.prg /n/w/es2
ó
      hbmk2 t1.prg -n -w -es2

Y luego se puede ejecutar.

xHarbour no tiene esta funcionalidad y el código anterior tiene que ser adaptado para trabajar con este compilador. Adicionalmente no fuciona bien con sistemas de archivos sensitivos a las mayúsculas como Linux, lo cual se puede observar en los ejemplos anteriores, donde "t1" se cambia por "T1" y luego entonces xHarbour intentará incluir el archivo "T1.prg", el cual no existe.

Para usuarios que tienen código antiguo en Clipper escrito para sistemas de archivos DOS, con mezclas de letras en mayúsculas y minúsculas en los nombres de los archivos usados directa o indirectamente por nombre de procedimiento, Harbour tiene opciones en tiempo de compilación las cuales permiten conversiones automáticas de nombres de archivos para todos los archivos abiertos por el compilador:

-fn[:[l|u]|-] establece mayusculas/minúsculas para nombres de archivos
(l = Minúscula u = Mayúscula)

-fd[:[l|u]|-] Establece mayúsculas/minúsculas para nombres de directorios
(l = Minúscula u= Mayúsucula)

-fp[:] establece el separador de rutas.

-fs[-] Activa o desactiva el quitado de espacios en los nombres de los archivos.


Esta funcionalidad es local a Harbour y no puede ser usada por xHarbour. Pienso que esto puede ser fácil de implementar en xHarbour en un futuro.

Ambos compiladores soportan opciones en tiempo de ejecución para conversión de nombres de archivos:

      SET FILECASE LOWER | UPPER | MIXED
SET DIRCASE LOWER | UPPER | MIXED
SET DIRSEPARATOR
set( _SET_TRIMFILENAME, )

Las cuales pueden ser usadas en programas que no pretendan trabajar con diferentes sistemas de archivos y con distintos sistemas operativos.

Continuará .....

9 comentarios:

Anónimo dijo...

Hola Rene, me da gusto que estes de nuevo por aqui posteando cosillas.

Solo quiero hacer una aclaracion que tal vez este en el error pero segun tengo entendido xHarbour y Harbour no son compiladores.

Hasta donde se son masticadores de codigo prg clipper que es convertido a C++.

De ahi la necesidad de los compiladores C++ que son requeridos como el Borland, Pelles y otros.

Para mi clipper fue y pudiera decir uno de los mejores compiladores del mundo pero debemos aceptar la realidad de x)Harbour que no son compiladores y que lo unico que queda de nuestro amado Clipper es el Syntax y nada mas.

Saludos desde Guadalajara
Ramiro

Rene Flores dijo...

Ramiro:

Vamos a hecharnos para atrás a 6to semestre de la carrea de informática.

Si nos apegamos extrictamene a la teoría de compiladores y autómatas, tanto Harbour como xHarbour pueden ser llamados compiladores ya que cumplen con los requisitos que necesita un compilador:

Para empezar son automatas finitos, primer requisito para ser un compilador.

Segundo, contruyen su salida pasando por las 2 etapas de construcción de un compilador: Etapa de Scanner, constituida por un Analizador Léxico y Etapa de Parser implementada por un Analizador Sintáctico.

Sin importar la salida que genere, un automata que cumpla con estos 2 requisitos se le llama compilador.

Por otro lado, lo que hace el compilador de "C" asociado es exactamente lo mismo que hace el compilador de xHarbour, toma una entrada, en este caso un PCODE (no es codigo en C realmente), y el compilador de "C" lo unico que hace es "fundir" todo ese PCODE para luego pegarle un RUNTIME que está metido dentro de una librería de Harbour, si te fijas, el compilador de "C" nunca marca ningún error cuando "compila" el codigo generado por Harbour.

El resultado es un EXE similar al EXE de Clipper, un pcode con un runtime metido dentro.

Si te acuerdas, el descompilador Valkyrie para Clipper lo que hacia primero era extrer el PCODE del EXE, si tu ponias el PCODE de Valkyrie en pantalla parecía que era un código escrito en ensamblador, pero en realidad no lo es, es PCODE.

Luego en base a ese PCODE Valkyrie reconstruia el .PRG original, pero tenia problemas con los nombres de las variables porque estos nombres al ser "simbolos" al final de la compilación se vuelven elementos de una tabla en memoria, pierden su "nombre" original.

El tema de los compiladores es sumamente interesante, es relativamente sencillo hacer uno muy simple, me acuerdo que en la universidad hicimos un compilador de dBase que no generaba el EXE final por falta de Runtime, pero que scaneaba y parseaba perfectamente toda la sintaxis del lenguaje y lo hicimos con Prolog..... huy, de eso hace como 20 años.

msalas dijo...

Caray maestro, de los comentarios vertidos, me viene a la mente una pregunta: ¿porqué demonios se dejó de impartir las clases a nivel profesional de esa forma?. Y lo digo con conocimiento de causa estoy por a meses de graduarme en la licenciatura en informática y que gran descepción me he llevado, la gran mayoría de los profesores no se quieren meter en problemas, prefieren "caerle bien" a los alumnos, las exigencias son mínimas, si no estudias para un exámen no pasa nada, han salido frases como "es que no estudié", "no le entendí", "si me lo se pero no se como expresarlo", "no lo pude hacer" .... y las del maestro: "no hay problema", "no te preocupes", "no pasa nada"... ¡como mad... que no pasa nada!! que clase de profesionistas estan lanzando al mercado !! y lo mas patético: la mínima es 70... cuando hay gente que ni siquiera llega al 20... lo único que quieren es graduar gente para que les suga llegando presupuesto....ni hablar como tu dices que tiempos aquellos...

Anónimo dijo...

Solo estaba probando que no te hubiera afectado el accidente.

Tienes toda la razon desde el punto de vista que expones. Pero x)Harbour genera codigo .C y Clipper genera .Obj mientras que el archivo .C puede ser editado desde cualquier programa C++ el .Obj lo mas que podias hacer con el es Linkearlo.

Y esa es la diferencia por la que digo que xHarbour no es un compilador pero le podemos agregar no es un compilador como Clipper.

En aquel entonces tenias codigo fuente en .PRG Clipper Compilado .OBJ Linkeado = .EXE

Ahora codigo fuente .PRG xHarbour compilado resultado codigo fuente .C compilado de nuevo ahora con un C++ igual a un .EXE

Como puedes ver tengo 2 juegos de codigo fuente contra 1 de la version Clippera.

Saludos y que sigas mejor, te llamo en la semana para que me actualices la info de xailer.

Ramiro

Anónimo dijo...

Ramiro:

Por esa regla de 3 que planteas, entonces Java tampoco es un compilador, el resultado de compilar un programa en Java son ficheros .JAR, no existe un EXE como tal y requieres del Runtime para ejecutar el programa.

Ahora, dile a Sun que Java no es un compilador y no veas la que se puede montar.

Walter Negro dijo...

Ramiro,
Ya te expuso Rene todas las razones por las que Harbour y xHarbour son compiladores.
Harbour y xHarbour generan un .c como código intermedio.
.NET también hace algo similar, generando un .ils como código intermedio.
Y Clipper genera un .obj.
En defensa de que no son compiladores indicas que el .obj no se puede editar y el .c si.
Pero eso es simplemente porque no eran masivos y de hecho es posible con algunos programas, revisar la estructura interna del .obj y cambiarla.
Claro que era muy poco útil ya que para cambiar una función embebida en un .obj debías conocer lenguaje ensamblador y para inyectar código se debía tener ese código en binario cosa que terminaba siendo tan engorrosa que era más simple generar el código nuevamente.
Por lo que el hecho de que no hubiera editores masivos de .obj era porque no tenía mucho sentido más que por otra causa.

Walter Negro dijo...

Un comentario más sobre si Harbour y xHarbour son compiladores.
Si usas el modificador /gh en lugar de un .c obtendrás un .hrb
Ese archivo es similar en cuanto a utilidad a un .jar.
Si asocias el .hrb al programa hbrun.exe, podrás hacer que haciendo doble-click sobre un .hrb se ejecute el programa.
Eso es algo similar a hacer doble-click sobre un .jar.

La diferencia en código entre un .hrb y un .c es que el primero es una versión binaria del segundo.
Luego hay muchas otras diferencias de funcionamiento que podemos seguir discutiendo, pero para no salirnos del tema de si el harbour.exe es o no un compilador, lo dejo ahí.

La principal razón de generar código .c en lugar de .obj es por la portabilidad.
El .c se compila con el compilador de C de la plataforma que quieras, en cambio habría que tener una salida específica para generar el .obj o .o según la plataforma.
Y además habría que elegir que formato de .obj utilizar, ya que si bien no necesitarás el compilador de C, necesitarás el enlazador, los cuales están muy relacionados con el compilador de C. (Borland y PellesC generan distintos formatos de .obj, solo para poner un ejemplo dentro de Win32 y ni hablar si pensamos en 64bits)

En definitiva, evitar el uso del compilador de C llevaría una tarea muy ardua y un mantenimiento muy alto dedicado exclusivamente a generar ese archivo correctamente según la plataforma y el o los enlazadores disponibles.
Sería un gasto de recursos de investigación y desarrollo muy alto.

Y para terminar, solo decir que es posible configurar el archivo harbour.cfg y junto con el modificador /go, el harbour.exe ejecutará el compilador de C y generará automáticamente el .obj

Walter Negro dijo...

Tomemos el 4to parrafo que comienza con "Hoy por hoy...".
Es muy cierto lo que dice, lo que me lleva a pensar que pasaría con Harbour si Przemyslaw dejara el proyecto, cuantos podrían entender las cosas que hizo a "su manera personal" con un código que es solamente para muy entendidos?.

Anónimo dijo...

Hola llegué a estos comentarios buscando en google.

Lo que trato de hacer es generar un .jar programando en Harbour que es lo que domino.

Quiero obtener algo que se pueda correr en un celular que soporte java

Agradezco cualquier comentario

Fermín Barboza
clippero@gmail.com