tag:blogger.com,1999:blog-87741631554583910912024-03-19T04:25:14.083+01:00A una indecisión pegadoUn blog acerca de REXX, OS/2, eComStation, software libre y otras cosas fundamentalmente inútiles en la vida real.Salvador Parra Camachohttp://www.blogger.com/profile/06043187618736820735noreply@blogger.comBlogger28125tag:blogger.com,1999:blog-8774163155458391091.post-51665438239334390342011-05-22T10:41:00.000+02:002011-05-22T10:42:35.751+02:00Air and RodTu pequeño padawan te echaba de menos.Salvador Parra Camachohttp://www.blogger.com/profile/06043187618736820735noreply@blogger.com2tag:blogger.com,1999:blog-8774163155458391091.post-25786243253298748852011-03-02T23:19:00.002+01:002011-03-02T23:40:13.389+01:00IlusionesMe parece enormemente curiosa la manera en que la vida da giros inesperados y te sorprende con cosas que jamás hubieses esperado. Cosas que solamente unos meses atrás hubiesen parecido situaciones imposibles si en algún momento las hubiesen planteado.<br /><br />A mí, al menos, me parecían imposibles.<br /><br />Pero esos imposibles se han convertido en hechos y últimamente duermo mejor, me despierto con una sonrisa en la cara y hago aquellas cosas que hago con más ilusión y con más ganas.<br /><br />Y la responsable directa de todo eso es una persona, probablemente la única persona que lea esta entrada (espero que esbozando esa dulce sonrisa que tanto me gusta en su cara).<br /><br />Todo esto que está sucediendo me hace recordar esa hermosa obra maestra que es <span style="font-style:italic;">Blankets</span> de Craig Thompson cuando el autor dice: <span style="font-style:italic;">Qué satisfacción produce dejar una marca en una superficie en blanco. El dibujar el mapa de mis movimientos... ...sin que importe que no sea para siempre</span>.<br /><br />No importará si esto que sucede no es para siempre, porque mientras tanto el viaje está siendo maravilloso.<br /><br />Gracias, pequeña.Salvador Parra Camachohttp://www.blogger.com/profile/06043187618736820735noreply@blogger.com1tag:blogger.com,1999:blog-8774163155458391091.post-6052865315392815412011-02-03T19:51:00.003+01:002011-02-03T19:54:39.135+01:00qtDbf 0.9.3 en eComStation<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzmuoCDdsj4KDXh04t6N0D3RsbCDe9nA0E_f0qRYnVI_hSigxmnE9YEXpBvoZCM62ZdanZ-hzMwBRdV3OQBHl8JstVRsftrVrFUbRe_Zv-waf9bcCTyYftAKyaSjUGFeDmRJ-PeW549Lik/s1600/qtDbf093-os2.png"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 211px; height: 320px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzmuoCDdsj4KDXh04t6N0D3RsbCDe9nA0E_f0qRYnVI_hSigxmnE9YEXpBvoZCM62ZdanZ-hzMwBRdV3OQBHl8JstVRsftrVrFUbRe_Zv-waf9bcCTyYftAKyaSjUGFeDmRJ-PeW549Lik/s320/qtDbf093-os2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5569538472643745538" /></a><br />Ahora he compilado <a href="http://qt-apps.org/content/show.php/qtDbf?content=137863">qtDbf 0.9.3</a> en OS/2 y está disponible en <a href="http://hobbes.nmsu.edu/download/pub/incoming/qtDbf093-os2.zip">Hobbes</a>. Es la segunda aplicación QT4 que consigo compilar sin problemas.Salvador Parra Camachohttp://www.blogger.com/profile/06043187618736820735noreply@blogger.com2tag:blogger.com,1999:blog-8774163155458391091.post-32676908780449928992011-02-03T19:06:00.005+01:002011-02-03T19:55:29.438+01:00ehm 0.2 en eComStation: una pequeña calculadora en QT4<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEin3ddZMBYecNcasWH8nXfCkiTx9pZQI7hR5Lx3_JFkOJKkxZ0s1JqLCOYH85chLPVhI9w6KsIOyN53cFT-cXUcgMUCPr5cMah5chJECN3tkwaoo-WGiuhf-tDRudvbFIAVHymlcVAFZ24t/s1600/ehm02-os2-small.png"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 198px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEin3ddZMBYecNcasWH8nXfCkiTx9pZQI7hR5Lx3_JFkOJKkxZ0s1JqLCOYH85chLPVhI9w6KsIOyN53cFT-cXUcgMUCPr5cMah5chJECN3tkwaoo-WGiuhf-tDRudvbFIAVHymlcVAFZ24t/s320/ehm02-os2-small.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5569527613430130642" /></a><br />Mi primer "port" para OS/2 de una calculadora muy simple llamada <a href="http://qt-apps.org/content/show.php?content=138137">ehm</a> ya está en <a href="http://hobbes.nmsu.edu/download/pub/incoming/ehm02-os2.zip">Hobbes</a>.<br /><br />Compilarlo ha sido absolutamente trivial.Salvador Parra Camachohttp://www.blogger.com/profile/06043187618736820735noreply@blogger.com0tag:blogger.com,1999:blog-8774163155458391091.post-82971617933240959382011-01-31T13:09:00.004+01:002011-02-12T13:03:53.436+01:00Adiós, BarryJohn Barry (3 de noviembre de 1933 - 30 de enero de 2011).<br /><iframe title="YouTube video player" class="youtube-player" type="text/html" width="400" height="333" src="http://www.youtube.com/embed/KHvKviaeulg?rel=0" frameborder="0" allowFullScreen></iframe><br /><iframe title="YouTube video player" class="youtube-player" type="text/html" width="400" height="255" src="http://www.youtube.com/embed/gljHVCBY8kQ?rel=0" frameborder="0" allowFullScreen></iframe>Salvador Parra Camachohttp://www.blogger.com/profile/06043187618736820735noreply@blogger.com0tag:blogger.com,1999:blog-8774163155458391091.post-50021332752152616512011-01-20T00:00:00.002+01:002011-01-20T00:18:40.702+01:00Un instalador de gnuplot para Windows<div style="text-align: right;"><span style="font-size:85%;"><span style="font-style: italic;">Esta entrada va dedicada a una amiga que no para de burlarse del abandono de mi blog (aunque también se quejará de lo técnica que es la entrada). Va por ti, pequeña.</span><br /></span></div><br />Hace unos escasos minutos he terminado un instalador de gnuplot para Windows para mi amigo José Joaquín y se lo he mandado por correo.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggpSh3T4VOtbtog7zgCMewzJdDGlMC_qOSKGS1TfCcDhsyxT1rvscJfsJmLry7UzwvyCfnkqFBtO8u2vcJXI4_ShhHvCHhj1eKlNKn-wW58B4y0airq0ydceBZdpAcATE58ef21Uuh3nKG/s1600/instalador_gnuplot.png"><img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 320px; height: 249px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggpSh3T4VOtbtog7zgCMewzJdDGlMC_qOSKGS1TfCcDhsyxT1rvscJfsJmLry7UzwvyCfnkqFBtO8u2vcJXI4_ShhHvCHhj1eKlNKn-wW58B4y0airq0ydceBZdpAcATE58ef21Uuh3nKG/s320/instalador_gnuplot.png" alt="" id="BLOGGER_PHOTO_ID_5564040210399248578" border="0" /></a><br /><br />Hacía bastante tiempo que no tocaba sistemas de creación de instaladores para Windows tales como Inno Setup, NSIS y MakeMSI. Últimamente había creado algún que otro paquete instalable WarpIN para OS/2 y algún que otro paquete deb para distribuciones Linux basadas en Debian y podría decir que había olvidado el barroquismo y la insuficiencia de la documentación de esas herramientas para Windows, pero mentiría.<br /><br />Y es que con la influencia recibida por OS/2 por un lado y por Linux por el otro, ciertos detalles de los instaladores de Windows le hacen a uno pensar que Windows está mal diseñado (tal vez algún día explique por qué tengo esa impresión, pero hoy no).<br /><br />A pesar de todo, ha sido estimulante.Salvador Parra Camachohttp://www.blogger.com/profile/06043187618736820735noreply@blogger.com2tag:blogger.com,1999:blog-8774163155458391091.post-61925648962869740612010-05-31T19:01:00.003+02:002010-05-31T19:12:17.904+02:00newLISP 10.2.8 en eComStationEstos días he conseguido compilar la última versión del intérprete newLISP (la 10.2.8) para OS/2. He subido a Hobbes el resultado, si bien sé que al menos tiene un fallo (el servidor web que incluye solamente funciona con páginas estáticas).<br /><br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEip7xsqJoSFl6ALb8dbc6WWeLzW-2e83fi5a_n5KSPFCSdaFcpIV_cZZedAragDJmjxBQia1I0Y9tXJFDOi3PGLAxDQghG82wcl-1dT_OleTKlwf-AMGuShU6RIH1Xoych6BdEhyphenhyphenHIE-X1i/s1600/newlisp_os2.jpg"><img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 320px; height: 224px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEip7xsqJoSFl6ALb8dbc6WWeLzW-2e83fi5a_n5KSPFCSdaFcpIV_cZZedAragDJmjxBQia1I0Y9tXJFDOi3PGLAxDQghG82wcl-1dT_OleTKlwf-AMGuShU6RIH1Xoych6BdEhyphenhyphenHIE-X1i/s320/newlisp_os2.jpg" alt="" id="BLOGGER_PHOTO_ID_5477482824906759298" border="0" /></a>Todo el mérito de mi compilación lo tiene Norman Deppenbroek. Me he limitado a ejecutar:<br /><br /><code>make -f makefile_os2</code><br /><br />y a añadir un icono.Salvador Parra Camachohttp://www.blogger.com/profile/06043187618736820735noreply@blogger.com0tag:blogger.com,1999:blog-8774163155458391091.post-21592654260547483802010-05-30T22:39:00.002+02:002010-05-30T23:20:05.353+02:00QT 4.6.2 en eComStationNo deja de resultarme sorprendente la vitalidad de un sistema operativo que lleva "muerto" desde hace diez años.<br /><br />Gracias a las donaciones de usuarios de este viejo sistema operativo, <a href="http://www.netlabs.org/en/site/index.xml">netlabs</a> ha conseguido pagar el trabajo de Dmitry A. Kuminov que ha terminado con una versión de <a href="http://svn.netlabs.org/qt4">QT 4.6.2 para eComStation</a>. Esto ha abierto la posibilidad de que docenas de aplicaciones basadas en la célebre librería gráfica de Nokia estén disponibles para el sistema operativo.<br /><br />El australiano Paul Smedley ha actualizado los <span style="font-style: italic;">ports</span> de <a href="http://www.lyx.org/">LyX</a> y <a href="http://www.scribus.net/">Scribus</a>; Silvan Scherrer ha actualizado los de <a href="http://kdiff3.sourceforge.net/">KDiff3</a>, <a href="http://smplayer.sourceforge.net/">SMPlayer</a>, <a href="http://qbittorrent.sourceforge.net/">QBitTorrent</a> y Blubbels; el coreano KO Myung-Hun ha actualizado su beta de <a href="http://www.videolan.org/vlc/">VLC</a>... E imagino que eventualmente el holandés Elbert Pol actualizará algunos de sus <span style="font-style: italic;">ports</span> como el editor <a href="http://ste.sintegrial.com/">S.T.E</a> (entre muchos otros) y el japonés que ha hecho el de <a href="http://code.google.com/p/qwit/">Qwit</a> también lo actualizará.<br /><br />Espero ver algunos programas más en eComStation funcionando en breve gracias a QT 4.6.2:<br /><br />- <a href="http://code.google.com/p/yacreader/">YACReader</a>: es un lector de cómics. Visualiza cómics en formatos CBR y CBZ.<br />- <a href="http://kid3.sourceforge.net/">Kid3</a>: es un editor de etiquetas para ficheros de audio.<br />- <a href="http://code.google.com/p/arora/">Arora</a>: es un navegador web basado en WebKit.<br /><br />Es cierto que yo mismo he sugerido como característica para nuevas versiones de Lucide un nuevo plugin que permita abrir cómics en formato digital. También es cierto que ya existen dos programas de edición de etiquetas en OS/2 basados en QT4. Y es muy cierto que hay versiones de Firefox y SeaMonkey para OS/2...<br /><br />...pero me gustan las alternativas.<br /><br />Aquellos usuarios de Windows, Linux, Mac OS X o cualquier otra plataforma que tenga su versión de QT deberían echarle un vistazo a todos estos programas. Son alternativas interesantes.Salvador Parra Camachohttp://www.blogger.com/profile/06043187618736820735noreply@blogger.com0tag:blogger.com,1999:blog-8774163155458391091.post-46415107375550496162010-05-25T00:00:00.000+02:002010-05-25T00:19:28.271+02:00NO SE ASUSTE: 25 de mayoFeliz día...<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOVBYP_ZQ7C58ePiq1YM3-YsQZwdZT5saP6iiUjoAmeICg_vEw4anrfdBZxluGRvVTA0j9BYBJlSvANTJJ7pUlrwwkB73zucmMuLm_WEwLyyLzuCZhjCIUXZSN9VD40hnLxYtmlF3-l67B/s1600/Towel+day.jpg"><img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 320px; height: 240px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOVBYP_ZQ7C58ePiq1YM3-YsQZwdZT5saP6iiUjoAmeICg_vEw4anrfdBZxluGRvVTA0j9BYBJlSvANTJJ7pUlrwwkB73zucmMuLm_WEwLyyLzuCZhjCIUXZSN9VD40hnLxYtmlF3-l67B/s320/Towel+day.jpg" alt="" id="BLOGGER_PHOTO_ID_5474957310021727698" border="0" /></a><br />...<a href="http://es.wikipedia.org/wiki/Douglas_Adams#El_d.C3.ADa_de_la_toalla">de la toalla</a>.Salvador Parra Camachohttp://www.blogger.com/profile/06043187618736820735noreply@blogger.com0tag:blogger.com,1999:blog-8774163155458391091.post-2094110109386869212010-05-24T18:03:00.000+02:002010-05-24T18:26:46.411+02:00muStringConverter 0.2.0Acabo de subir a <a href="http://hobbes.nmsu.edu/">Hobbes</a> la nueva versión de la pequeña utilidad muStringConverter.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdFyL-AFn8eQFN3jj264RFc_RhygoDbk_jbzWp3NAWbIarkMR0fZF-Yznl24kUUGA6D29BN8s4KH65wRZbC5WyBR7H0CEuUKR6_bV-ZWdcrVD6HIK2UkTWO6LuAbAB_UeTOOw-_-eFfNDl/s1600/muStringConverter020.jpg"><img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 320px; height: 246px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdFyL-AFn8eQFN3jj264RFc_RhygoDbk_jbzWp3NAWbIarkMR0fZF-Yznl24kUUGA6D29BN8s4KH65wRZbC5WyBR7H0CEuUKR6_bV-ZWdcrVD6HIK2UkTWO6LuAbAB_UeTOOw-_-eFfNDl/s320/muStringConverter020.jpg" alt="" id="BLOGGER_PHOTO_ID_5474868688878649570" border="0" /></a><br />Una de las cosas que añade es el menú que copia al portapapeles lo que se encuentra en cada uno de los campos (binario, decimal, hexadecimal, octal y ASCII) tal como puede verse en la captura de pantalla.<br /><br />Otra de las cosas es menos evidente: he añadido el control externo del programa a través de una tubería con nombre (<span style="font-style: italic;">named pipe</span> en inglés).<br /><br />Aquellos usuarios de OS/2 o eComStation están habituados a ellas (cuando menos a que se las mencione); numerosos programas las utilizan. El reproductor de audio <a href="http://dink.org/z/">Z!</a> permite controlar el reproductor a través de una de estas tuberías: pausar la reproducción, salir del programa, preguntar al programa la información sobre el fichero que está reproduciendo, añadir un fichero a la lista de reproducción... El editor de texto <a href="http://hobbes.nmsu.edu/download/pub/os2/apps/editors/fed0231s.zip">Fed</a> permite usar una tubería con nombre para cambiar la posición del cursor... El visualizador de documentos PDF <a href="http://svn.netlabs.org/lucide">Lucide</a> permite avanzar o retroceder páginas, pasar a modo de presentación y más cosas a través de una tubería con nombre...<br /><br />En el caso de muStringConverter si en la consola se teclea:<br /><pre>echo *quit > \PIPE\MUSTRINGCONVERTER<br /></pre>el programa se cierra.<br /><br />Desde un <span style="font-style: italic;">script</span> REXX podríamos hacer lo siguiente:<br /><pre>/**/<br /><br />pipeName = '\PIPE\MUSTRINGCONVERTER'<br /><br />call lineout pipeName, '*putbin 1010'<br />call lineout pipeName<br />call SysSleep 0.1<br /><br />call charout pipeName, '*getdec'<br />say 'Decimal: ' linein(pipeName)<br />call charout pipeName<br />call SysSleep 1<br /><br />exit<br /></pre>Este <span style="font-style: italic;">script</span> simplemente pone la cadena 1010 en el campo de entrada, la convierte como si fuese una cadena binaria y después extrae el valor decimal resultante.<br /><br />Para aquellos usuarios de Linux y sistemas UNIX acostumbrados a usar tuberías con nombre en sus sistemas operativos: efectivamente, las tuberías con nombre de OS/2 (y de Windows) funcionan de un modo diferente a las de Linux.Salvador Parra Camachohttp://www.blogger.com/profile/06043187618736820735noreply@blogger.com0tag:blogger.com,1999:blog-8774163155458391091.post-29932081812356506142010-05-23T19:31:00.000+02:002010-05-23T20:01:32.842+02:00Adiós a Martin GardnerMartin Gardner, columnista de las revistas <span class="citation web"><span style="font-style: italic;">Scientific American</span><span class="printonly"> y <span style="font-style: italic;">Skeptical Inquirer</span>, falleció ayer sábado a la edad de 95 años.<br /><br />Hace unas semanas pude ver la mal llamada <span style="font-style: italic;">Alicia en el país de las maravillas</span></span><span class="reference-accessdate"></span></span><span style="font-style: italic;"><span style="font-style: italic;"> </span></span>de Tim Burton. Eso me trajo a la memoria una nota anecdótica de <span style="font-style: italic;">The League of Extraordinary Gentlemen</span> (el segundo volumen) de Alan Moore y Kevin O'Neill respecto al personaje de Alicia tras los sucesos de <span style="font-style: italic;">A través del espejo</span>. A su vez eso me hizo recordar quién fue la primera persona que me <span style="font-style: italic;">habló</span> de la homoquiralidad biológica en la literatura: Martin Gardner en <span style="font-style: italic;">El universo ambidiestro</span>.<span style="font-style: italic;"><span style="font-style: italic;"><br /><br /></span></span>(Acerca de este tema llevo tiempo queriendo añadir una entrada en el blog.)<span style="font-style: italic;"><span style="font-style: italic;"><br /><br /></span></span>Desde entonces he retomado la lectura de algunos de los pasajes de la obra de Gardner (tanto de sus juegos matemáticos como de sus artículos contra las pseudociencias) a lo largo de estos días. Y tras enterarme hoy mismo de la noticia, como ocurre con cada autor que me enseña tanto y me hace disfrutar en el proceso, no puedo evitar sentirme apenado por su muerte.<span style="font-style: italic;"><span style="font-style: italic;"><br /><br /></span></span>Si no habeis leído nada de él, hoy es un buen día para hacerlo. Es lo yo que haré esta noche.<span style="font-style: italic;"><span style="font-style: italic;"><br /></span></span>Salvador Parra Camachohttp://www.blogger.com/profile/06043187618736820735noreply@blogger.com1tag:blogger.com,1999:blog-8774163155458391091.post-18831523360984917882010-05-21T18:25:00.000+02:002010-05-21T18:48:04.323+02:00eComStation 2.0 ya está aquíAl entrar hoy en <a href="http://www.os2world.com">OS2 World.Com</a> me he encontrado con el <a href="http://www.ecomstation.com/images/ecs20/banner_650.jpg"><span style="font-style: italic;">banner</span></a> publicitario que anuncia la salida al mercado de la nueva versión de <a href="http://www.ecomstation.com">eComStation</a>.<br /><br />El <span style="font-style: italic;">banner</span> muestra a un hombre y a una mujer en blanco y negro sacados de los años cincuenta de los Estados Unidos dándose la noticia por teléfono: <span style="font-style: italic;">Hey listen up! Version 2 is here!</span> (¡Ey, escucha! ¡La versión 2 está aquí!). Se ven las dos versiones del mismo, la <span style="font-style: italic;">Home and Student</span> y la <span style="font-style: italic;">Business Edition</span>, el logotipo del sistema operativo y las palabras <span style="font-style: italic;">secure, versatile, powerfull, reliable</span> (seguro, versátil, poderoso y fiable).<br /><br />Confieso que he encontrado el anuncio tan encantadoramente pasado de moda e ingenuo que me ha hecho sonreír.Salvador Parra Camachohttp://www.blogger.com/profile/06043187618736820735noreply@blogger.com0tag:blogger.com,1999:blog-8774163155458391091.post-84629196594678294522010-05-15T12:58:00.000+02:002010-05-15T18:21:23.086+02:00muStringConverterHace un par de semanas subí a <a href="http://hobbes.nmsu.edu/">Hobbes</a> (el <span style="font-style: italic;">repositorio</span> de aplicaciones de OS/2 por excelencia) una pequeña aplicación que programé allá por el 2004: muStringConverter.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8cb7Gm7aAKGh1T_v9BFej5CTdenYWXuXmwBdkl84lMWvT5FQ3w8Dm_K0PdcxHavmCY0EAEKUG9trQflVgJ6CfQLu6WVM_Z9sW9n6dhh_mPSSOT3164DqKj9nTQplgrYNudjWkTWyLmh8e/s1600/muStringConverter.jpg"><img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 320px; height: 246px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8cb7Gm7aAKGh1T_v9BFej5CTdenYWXuXmwBdkl84lMWvT5FQ3w8Dm_K0PdcxHavmCY0EAEKUG9trQflVgJ6CfQLu6WVM_Z9sW9n6dhh_mPSSOT3164DqKj9nTQplgrYNudjWkTWyLmh8e/s320/muStringConverter.jpg" alt="" id="BLOGGER_PHOTO_ID_5471531900068046578" border="0" /></a><p>Creo que queda claro por la imagen que es un pequeño programa que se limita a convertir una cadena entre distintos <span style="font-style: italic;">formatos</span> (binario, decimal, hexadecimal, octal y ASCII). Creo recordar que la interfaz fue una imitación de un pequeño programa que me enseñó mi amigo Manolo Pavón por aquel entonces.</p><p>En su momento este programa me resultó útil como ayuda para el juego de deducir el funcionamiento del formato MSG. Los ficheros MSG en OS/2 se utilizan como ficheros de mensajes de aplicaciones y son de tipo binario. A golpe de editor hexadecimal y con esta pequeña utilidad, conseguí crear un pequeño <span style="font-style: italic;">decompilador</span> de ficheros MSG escrito en REXX.</p><p>Probablemente el hecho de que las cadenas resultantes de la conversión estén en campos de entrada no editables sea un fallo de diseño, pero lo escogí así para que el usuario pueda moverse entre los campos de entrada fácilmente con el teclado.</p><p>Tengo una nueva versión lista que añade unos atajos de teclado para copiar los campos de entrada directamente al portapapeles y que además puede controlarse desde una tubería con nombre.</p><p>La versión en <a href="http://hobbes.nmsu.edu/">Hobbes</a> puede encontrarse <a href="http://hobbes.nmsu.edu/h-search.php?key=mustringconverter&pushbutton=Search">aquí</a>.</p>Salvador Parra Camachohttp://www.blogger.com/profile/06043187618736820735noreply@blogger.com0tag:blogger.com,1999:blog-8774163155458391091.post-19109725833012773232007-09-16T23:16:00.000+02:002007-09-16T23:21:28.090+02:00GBM 1.52 o de la timidez de SSIHeiko Nitzsche ha actualizado su versión mejorada de <a href="http://heikon.home.tlink.de/">GBM</a> (Generalised Bitmap Module) una librería y una serie de utilidades para trabajar con diversos formatos de imagen de mapa de bits (como los formatos JPEG, GIF o PNG). La última versión anterior al trabajo de Nitzsche de la dll (GBM.DLL) forma parte de eComStation 1.2; el procedimiento multimedia para ver ficheros JPEG (un reemplazo del original hecho por IBM, programado por Chris Wolgemuth) depende de esa biblioteca.<br /><br />El trabajo de Nitzsche no es moco de pavo: ha añadido nuevos formatos y mejorado el soporte de los formatos ya existentes, ha actualizado los visualizadores de imagen, ha añadido un <i>plugin</i> para Firefox (y familia) y otro para Lucide, así como un API que permite previsualizar las imágenes en los diálogos de apertura de ficheros y una extensión que permite acceder a todas estas funcionalidades desde REXX y además todo esto lo hace utilizando compiladores modernos (OpenWatcom 1.7).<br /><br />De hecho, el conjunto de procedimientos multimedia parte de eSchemes Deluxe denominado <i>Imagination</i> que añade nuevos formatos de imagen al sistema multimedia de OS/2 está basado en el trabajo de Nitzsche.<br /><br />Y ahora pasamos a Serenity Systems International, los responsables de eComStation y los listados de características de las betas de la próxima versión de su distribución de OS/2 (eComStation 2.0): en ningún lugar se habla de la inclusión de la versión de GBM mejorada por Nitzsche.<br /><br />Y eso me hace preguntarme por qué SSI realiza tan timidamente muchas modificaciones al sistema operativo (las referentes a ACPI, controladores de tarjetas de red y demás controladores podría decirse que son por necesidad). Hay docenas de programas que podrían ser incluidos y GBM es solamente un ejemplo: programas de grabación de CDs y DVDs (Audio/Data-CD-Creator, dvddao, cdrtools, All2Iso), clientes para compartir archivos (ctorrent -del que parece existir un <i>front-end</i>-), clientes de correo (está incluido Thunderbird, pero RexxMail ¡es tan WPS...!), gestores de descargas (las últimas versiones de wget y el maravilloso Auto WGet Daemon), utilidades varias (la utilidad para el portapapeles ClipView), extensiones REXX (rxu, por mencionar el ejemplo más notable)...<br /><br />Además, uno supone que no debería ser difícil para SSI sustituir el visor de imágenes incluido en OS/2 por algo más moderno (al estilo del de Windows XP), hacer un conversor de formatos de imagen, un editor de imágenes (al estilo del MS Paint) e incluir un capturador de imágenes sencillo (Gotcha es un punto de partida para hacer uno bien integrado con el sistema, el visor de GBM incluye otro capturador)... por mencionar solamente uno de los tipos de datos que puede manejar un sistema operativo.<br /><br />¿Por qué no lo hacen? ¿Miedo a que el sistema pierda estabilidad? ¿Falta de recursos económicos y humanos (invertidos en el corazón del sistema, que es esencial para que todo lo demás funcione)? ¿Implicaciones legales? ¿Falta de ideas?Salvador Parra Camachohttp://www.blogger.com/profile/06043187618736820735noreply@blogger.com4tag:blogger.com,1999:blog-8774163155458391091.post-77864740912574956712007-09-15T22:21:00.000+02:002007-09-15T22:38:43.784+02:00Como averiguar si un script está en una consolaEn un mundo en el que las interfaces gráficas de usuario en general y los entornos de escritorio son algo omnipresente no deja de resultar muy curioso el hecho de que cada sistema operativo ha optado por métodos muy diferentes a la hora de ejecutar sus <i>scripts</i> diseñados para la consola desde el entorno de escritorio. Es decir, cuando hacemos doble <i>click</i> sobre el icono correspondiente al <i>script</i>.<br /><br />Windows y OS/2, por ejemplo, abren una consola cada vez que se ejecuta un fichero bat o cmd (en el caso de OS/2, los ficheros cmd pueden ser programas escritos en REXX o incluso pueden ser programas escritos en Python o Perl no simples ficheros de proceso por lotes). Windows no ofrece muchas facilidades para ocultar la ventana de la consola. OS/2 ofrece bastantes alternativas para ocultarlo si es necesario y modos de ejecutar pequeños diálogos gráficos cuando la consola está oculta.<br /><br />BeOS nunca abre una consola cuando se ejecuta un script. Tradicionalmente en BeOS todo aquel <i>script</i> que estuviese pensado para el escritorio utilizaba el comando <code>alert</code> de BeOS que permitía mostrar al usuario pequeños diálogos con sus correspondientes mensajes y botones.<br /><br />Con los entornos de escritorio usuales en Linux (Gnome y KDE, aunque haya docenas más con muy buenas ideas, por cierto) lo habitual es que el comportamiento fuese el mismo que en BeOS. Actualmente lo usual en Gnome (por ejemplo) es que cuando un usuario hace doble <i>click</i> sobre un <i>script</i> aparezca un diálogo que le pide confirmar si quiere ejecutarlo, ejecutarlo abriendo una terminal, editarlo o cancelar la apertura.<br /><br />Ocasionalmente puede ser interesante que un <i>script</i> averigüe si se está ejecutando en una consola o no y para ello el comando <code>tty</code> nos puede servir muy bien puesto que la salida de ese comando nos indica el número de terminal en el primer caso o nos dice "not a tty" en caso contrario. Así podemos hacer de forma sencilla lo siguiente:<br /><pre><code> #!/bin/bash<br /><br /> if [ "$(tty)" = "not a tty" ]; then<br /> echo "No es una terminal"<br /> else<br /> echo "Sí es una terminal"<br /> fi<br /><br /> exit 0</code></pre><br />Lo que en REXX quedaría como:<br /><pre><code> /*bin/true;exec rexx "$0" "$@";exit # REXX */<br /><br /> 'tty | rxqueue'<br /> parse pull tty<br /><br /> if tty = 'not a tty' then<br /> say 'No es una terminal'<br /> else<br /> say 'Sí es una terminal'<br /><br /> exit 0</code></pre><br />El código de retorno del comando nos da la misma información:<br /><pre><code> #!/bin/bash<br /><br /> tty=$(tty)<br /><br /> if [ $? = 1 ]; then<br /> echo "No es una terminal"<br /> else<br /> echo "Sí es una terminal" # $? es igual a 0<br /> fi<br /><br /> exit 0</code></pre><br />En REXX:<br /><pre><code> /*bin/true;exec rexx "$0" "$@";exit # REXX */<br /><br /> 'tty > /dev/null'<br /><br /> if rc = 1 then<br /> say 'No es una terminal'<br /> else<br /> say 'Sí es una terminal' /* rc es igual a 0 */<br /><br /> exit 0</code></pre><br />Esto nos permite, por ejemplo, forzar la ejecución del programa en una terminal:<br /><pre><code> #!/bin/sh<br /> # Ejemplo para BeOS<br /> # Cada entorno de escritorio tiene su propio ejecutable<br /> # para la terminal.<br /> myself=$0<br /> if [ "$(tty)" = "not a tty" ]; then<br /> Terminal -t "Ejemplo" /bin/sh -c "$myself"<br /> else<br /> echo 'Sí una terminal'<br /> fi</code></pre><br />Con <code>kdialog</code>, <code>zenity</code> o <code>xdialog</code> podemos hacer pequeños <i>scripts</i> interactivos como en el siguiente caso:<br /><pre><code> /*bin/true;exec rexx "$0" "$@";exit # REXX */<br /><br /> current_date = date('S')<br /><br /> 'tty > /dev/null'<br /><br /> gui = rc<br /><br /> if gui = 1 then do<br /> 'zenity --title "Escoja su fecha de nacimiento"' ||,<br /> ' --calendar --date-format %Y%m%d | rxqueue'<br /> pull birthday_date<br /> if rc = 1 then<br /> exit 1 /* Pulsado el botón "Cancelar" */<br /> end<br /> else do<br /> say 'Introduzca su fecha de cumpleaños (19770223):'<br /> parse pull birthday_date<br /> end<br /><br /> age_in_days = say date('B', current_date, 'S'),<br /> - date('B', birthday_date, 'S')<br /><br /> if gui = 1 then do<br /> 'zenity --warning --text "Su edad en días es:',<br /> age_in_days '"'<br /> else do<br /> say 'Su edad en días es' age_in_days<br /><br /> exit 0</code></pre>Salvador Parra Camachohttp://www.blogger.com/profile/06043187618736820735noreply@blogger.com0tag:blogger.com,1999:blog-8774163155458391091.post-32385260228123439432007-09-13T22:10:00.000+02:002007-09-13T22:58:48.274+02:00La máquina expendedora de ooRexxDavid Ashley, uno de los líderes del desarrollo del intérprete <a href="http://www.oorexx.org/">Open Object REXX</a> (también conocido como ooRexx) anuncia hoy en comp.lang.rexx que el servidor de compilación de Open Object REXX está listo y la <a href="http://build.oorexx.org/">página asociada para acceder a él</a>, también lo está. Tal como estaba previsto hace ya bastantes meses y como al parecer se comentó en el simposio internacional de este año.
Básicamente ese servidor es una máquina con un Fedora Core 6 y un conjunto de sistemas operativos ejecutados como invitados a través de un VMware Server 1.0.3. Por ahora las elecciones no son muy variadas: Fedora 7, Ubuntu 7, Windows 2000 y Windows XP. Esto deja fuera otros sistemas para los que ya existen versiones oficiales del intérprete (AIX, Mac OS X y Solaris) y versiones no oficiales (FreeBSD).
Lo que más me llama la atención de esta iniciativa es la enorme conexión que establece entre un lenguaje que deriva de REXX y SmallTalk (y que por lo tanto tiene una tradición tan larga que hace que sea fácil tacharlo de antigüedad) y algo tan en boga y de moda como son las máquinas virtuales.
La máquinas virtuales no son el único punto de conexión de ooRexx con cosas que no están nada trasnochadas: gracias a Rony Flatscher y sus alumnos tenemos BSF4Rexx que permite ejecutar código Java desde REXX (desde Object REXX de forma completamente transparente) y código REXX desde Java; gracias también a Rony se puede acceder a OpenOffice y su sistema de componentes UNO desde Open Object REXX permitiendo el control externo de la aplicación, así como el escribir macros en ooRexx; gracias a David Ashley también disponemos de una mod_rexx apto para las últimas versiones del servidor Apache; René Vincent Jansen insinua en su blog que la integración entre ooRexx y el sistema de <i>scripting</i> de Mac OS X es cada vez mejor...
En definitiva, la comunidad de viejos dinosaurios se mueve aun y se moderniza. Que el equipo de desarrolladores pongan al servicio de la comunidad esta máquina <i>expendedora</i> que escupe la versión binaria más reciente correspondiente al código almacenado en los depósitos <i>Subversion</i> resulta (al menos desde el punto de vista intelectual) muy estimulante.Salvador Parra Camachohttp://www.blogger.com/profile/06043187618736820735noreply@blogger.com0tag:blogger.com,1999:blog-8774163155458391091.post-54006574790676108822007-09-11T23:10:00.000+02:002007-09-11T23:14:58.918+02:00Free Pascal Compiler 2.2.0 en OS/2 y eComStationAyer me enteré a través de <a href="http://barrapunto.com">Barrapunto</a> de la salida de la versión 2.2.0 de <a href="http://www.freepascal.org/download.var">Free Pascal Compiler</a>, un compilador de Pascal y Object Pascal de código abierto multiplataforma (OS/2, Linux -versiones de 32 y 64 así como para arm-, FreeBSD, Windows -incluidos Vista y CE-...) y me llama bastante la atención que no se haya mencionado nada todavía en ninguno de los portales dedicados a OS/2.<br /><br />Y me llama la atención porque Pascal, sus dialectos y sus derivados siempre han dado un buen puñado de programas populares y útiles para OS/2 (dejamos de lado el hecho de que en otros sistemas operativos uno de mis programas favoritos de todos los tiempos esté hecho en Delphi: Total Commander de Christian Ghisler).<br /><br />Por poner un ejemplo, en este mismo instante estas líneas las escribo en el editor de texto de eComStation, el AE de Aaron Lawrence, que está hecho en Sibyl (una especie de Delphi para OS/2), mientras tengo un cliente IRC hecho con Virtual Pascal (Virtual IRC) conectado y escucho esa deliciosa excentricidad de Mike Oldfield llamada <i>Amarok</i> con el reproductor Z! hecho con Virtual Pascal. Y hay cientos de ejemplos así:<br /><ul><li>En Virtual Pascal: el reproductor MP3 en modo texto Z! (también disponible para Windows), Web/2 (un estupendo servidor web, ligero y sencillo también disponible para Windows), Virtual IRC (un cliente IRC), Normal Player (un reproductor que usa el sistema multimedia de OS/2)...</li><li>En Sibyl o su variante GPL WDSibyl (disponible para Windows): NewView (el nuevo visor de ayuda que es componente de eComStation), AE (el editor de texto que es componente de eComStation), el USB Resource Manager, el programa de configuración de TCP/IP de Reinhard Berger...</li><li>En Modula, un lenguaje derivado de Pascal: FTPServer (un estupendo servidor FTP) y Weasel (un estupendo servidor de correo) ambos de Peter Moylan.</li><li>En Oberon, otro derivado de Pascal, DrDialog (una herramienta gratuita de desarrollo RAD en REXX).</li></ul><br />Viendo la tradición de Pascal en OS/2, me llama la atención que la comunidad en torno a este sistema operativo no se haya hecho hecho eco de la noticia de esta nueva versión del compilador FPC.<br /><br />Como nota curiosa, he descubierto que el cliente IRC está programado con Virtual Pascal cuando mi amiga Nerea ha intentado pasarme un fichero a través de DCC y el cliente ha dado un típico fallo en tiempo de ejecución de los que dan los programas hechos con ese compilador. Y el fallo era por una razón bastante peculiar: ¡me había quedado sin espacio en mi partición de OS/2!Salvador Parra Camachohttp://www.blogger.com/profile/06043187618736820735noreply@blogger.com0tag:blogger.com,1999:blog-8774163155458391091.post-51631292803859483632007-09-09T23:59:00.000+02:002008-12-11T12:06:45.590+01:00Macros REXX en IBM WorksMientras intento recuperarme de la impresión de ver <i>300</i>, la adaptación del cómic de Frank Miller al cine (Miller, aunque algunos no le perdonemos aun el guion de <i>Robocop 2</i>, parece tener bastante más suerte en esto que el pobre de Alan Moore), me gustaría hablar de cómo estaban implementadas las macros en una aplicación que ya tiene más de 10 años: IBM Works.<br /><br />Las macros, desde el punto de vista de un usuario final, son conjuntos de acciones que permiten ahorrar trabajo al usuario en un programa concreto. Ejecutando la macro al pulsar una combinación de teclas, pulsar un elemento de un menú, seleccionarla en un diálogo o como permita el programa, el usuario puede evitar realizar tareas repetitivas como <i>inserta el carácter hebreo aleph</i>, <i>selecciona el párrafo y dale otro formato</i>...<br /><br /> Ocasionalmente, las macros pueden tener una lógica interna más allá de una secuencia de tareas repetitivas y entonces el modo de realizarlas es a través de un lenguaje de programación de macros. Y son de estas macros de las que quiero hablar.<br /><br /> El problema que siempre ha existido con los lenguajes de programación de macros es que son específicos de la aplicación: el cliente IRC mIRC tiene su lenguaje de macros, Microsoft Office hasta ahora ha utilizado una variante de BASIC (Visual Basic for Applications), Open Office ha utilizado otra variante de BASIC, Lotus SmartSuite utiliza LotusScript, el editor de audio Audacity usa su propio lenguaje...<br /><br />Esto quiere decir que si el usuario desea aprender un lenguaje de macros, probablemente no pueda reutilizar sus conocimientos en otro sitio. Además, en algunos casos, la complejidad del lenguaje de macros para el tipo de tarea que desea el usuario puede resultarle excesiva (se encuentra con tipos de variables, declaraciones, módulos, objetos, métodos, sistemas de componentes y similares incluso para las macros más sencillas).<br /><br />Cuando hace más de 25 años, Mike Cowlishaw creó el lenguaje de programación REXX, uno de sus propósitos era que fácilmente pudiera ser utilizado como un lenguaje de macros. Y cuando IBM empezó a introducirlo como lenguaje de <i>scripts</i> de todos sus sistemas operativos, también empezó a convertirse en el lenguaje de macros de muchas aplicaciones para esos sistemas.<br /><br />En el mundo de la informática personal, dos sistemas operativos (uno ajeno a IBM) escogieron implementaciones de REXX como su lenguaje de macros preferido: OS/2 y Amiga OS.<br /><br />En OS/2 existía un pequeño paquete de oficina llamado IBM Works cuya hoja de cálculo utiliza macros REXX aunque apenas aproveche las posibilidades de esto.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCUJ0hPXNRpKrumTZbAjNqfHPB9ROp_KOzVz7W39j4EfsrEDj-1F3q7ubLuw6qmHmnS8sQZodm-cug_J7C6RNQtABPpTY4rOssoEZzPGtUe8HmNMSZ2Jt59mHENHDvLiNiE6EzZOYBNLbe/s1600-h/ibmworks.jpg"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCUJ0hPXNRpKrumTZbAjNqfHPB9ROp_KOzVz7W39j4EfsrEDj-1F3q7ubLuw6qmHmnS8sQZodm-cug_J7C6RNQtABPpTY4rOssoEZzPGtUe8HmNMSZ2Jt59mHENHDvLiNiE6EzZOYBNLbe/s320/ibmworks.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5108328477164920162" /></a><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuTN1Ltu_VxY3_ZenA_2vHTxv9HWcRXYPIyjQf7Soobdk69tL5tAjKUpWyqLxYMwEzky7gpLFsjI2UdyZ-lRvgut4Dm3V7KT0uB7hOlc3ylSQNCk1XU6iuIciPecbg9tWJp_VL8doprHu5/s1600-h/ibmworks_spread.jpg"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuTN1Ltu_VxY3_ZenA_2vHTxv9HWcRXYPIyjQf7Soobdk69tL5tAjKUpWyqLxYMwEzky7gpLFsjI2UdyZ-lRvgut4Dm3V7KT0uB7hOlc3ylSQNCk1XU6iuIciPecbg9tWJp_VL8doprHu5/s320/ibmworks_spread.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5108328477164920178" /></a><br /><br />Como puede verse en la segunda imagen, la primera columna corresponde a nombres de personas, la segunda a un NIF (Número de Identificación Fiscal) y la tercera muestra una comprobación de la validez del NIF utilizando una función de la hoja de cálculo IBM Works: <code>=rexx("isValidNIF.fnc",1,1,B4)</code>. La función <code>rexx</code> de IBM Works busca un fichero indicado en el primer parámetro (<code>isValidNIF.fnc</code>), decide que el valor de la celda será texto (si tuviésemos 0 en lugar de 1 tras la primera coma, trataría la celda como número) y lo ejecuta pasándole el número de parámetros indicado en el tercero de sus parámetros (en este caso uno)... Y el código de la macro no puede ser más sencillo:<br /><pre><code>/* isValidNIF.fnc */<br /> parse arg nif<br /> letras = 'TRWAGMYFPDXBNJZSQVHLCKE'<br /> numeros = '0123456789'<br /><br /> letra = right(nif, 1)<br /> dni = left(nif, length(nif) - 1)<br /><br /> select<br /> when pos(letra, letras) = 0 then<br /> ret = 'ERROR: Último carácter no es una letra'<br /> when verify(dni,'1234567890') <> 0 then<br /> ret = 'ERROR: El NIF debe comenzar por un número válido'<br /> when letra = substr(letras, dni//23 + 1, 1) then<br /> ret = 'NIF válido'<br /> otherwise<br /> ret = 'ERROR: La letra no corresponde al DNI'<br /> end<br /><br />return ret</code></pre><br />En esta aplicación concreta, la utilización de REXX como lenguaje de macros se ve reducida a su mínima expresión (al contrario que en casos como gnuplot, gdb, Photo>Graphics, GoServe, EPM...) y a pesar de ello se aprecia la sencillez.<br /><br /> Esto no solventa uno de los problemas de los sistemas de lenguajes de macros: la dependencia de un lenguaje concreto.<br /> Microsoft intentó eliminar la dependencia del lenguaje a través de su sistema de componentes COM que permite utilizar cualquier lenguaje para el que exista un WSE (<i>Windows Scripting Engine</i>) en cualquier aplicación que funcione como WSH (<i>Windows Scripting Host</i>) como son Internet Explorer o IIS, por ejemplo (y no es Microsoft Office, curiosamente), pero el sistema es incómodo para un no iniciado. OpenOffice desde sus últimas versiones permite ejecutar macros en más de un lenguaje, pero el sistema es tan barroco como el caso de los sistemas de Microsoft.<br /> Quizás la aproximación que dando independencia de lenguaje conserva la sencillez es una de las que siguen virtualmente todos los servidores web y algunos editores de texto: la macro se ejecuta por el intérprete deseado y coge la információn necesaria de la entrada estándar, los parámetros y las variables de entorno y devuelve la información a la aplicación a través de su salida estándar. Así es como funcionan los CGIs en los servidores web y las macros en el editor de texto para programadores TextMate (aunque en este caso, la documentación del editor restringe el concepto de macro), por ejemplo.<br /><br /> Es una pena que a veces las cosas sean innecesariamente complejas.<br /><br /> Incidentalmente: en la distribución del intérprete <a href="http://newlisp.org">newLISP</a> para Windows puede encontrarse un ejemplo de fichero de Excel que incluye una macro en Visual Basic que define una función que permite ejecutar código newLISP en cualquier fórmula de Excel de un modo muy similar al ejemplo de IBM Works. Y el mismo sistema puede utilizarse para ejecutar código de otros lenguajes.Salvador Parra Camachohttp://www.blogger.com/profile/06043187618736820735noreply@blogger.com1tag:blogger.com,1999:blog-8774163155458391091.post-23108194363961026262007-09-09T23:25:00.001+02:002007-09-10T00:10:53.158+02:00Synergy en OS/2,a href="http://www.netlabs.org":Netlabs,/a: cumple 10 aos, lo que es un buen motivo de celebracin... No es que me haya equivocado de tecla, es que estoy usando el teclado y el ratn del porttil de mi hermana (Windows) en mi ordenador de sobremesa (eComStation). Y que nadie piense que he sido tan bruto como para despedazar el porttil y hacer una chapuza, simplemente estoy usando Synergy a travs de la red. Pero volvamos a mi teclado...<br /><br />Hace unos días, <a href="www.netlabs.org">Netlabs</a> cumplía 10 años y explorando el directorio <i>incoming</i> en <a href="ftp://ftp.netlabs.org">su servidor FTP</a> como hago de vez en cuando me tropecé con un misterioso fichero llamado <i>synergybart.zip</i>. El <i>bart</i> me sugería quién era probablemente el autor (Bart van Leeuwen), pero el <i>synergy</i> me dejó descolocado y como la curiosidad extrema es uno de mis numerosos defectos, descargué el fichero y le eché un vistazo para encontrarme... que no llevaba ninguna documentación.<br /><br />Una rápida búsqueda a través de Google permite ver que <a href="http://synergy2.sourceforge.net/">Synergy</a> es un programa libre multiplataforma (hay versiones para Windows, Linux y Mac OS X) que permite usar el teclado y el ratón de un ordenador concreto (el servidor) en varios ordenadores conectados en una red. Es decir, podemos tener tres monitores correspondientes a tres CPUs distintas y controlar todos desde el mismo teclado y ratón. Moviendo el puntero a los bordes de un monitor, pasamos al siguiente...<br /><br />El que comparte el teclado y el ratón funciona como servidor ejecutando <code>synergys.exe</code> con la configuración y los parámetros adecuados. En mi caso, el fichero de configuración <code>synergy.conf</code> es así:<br /><pre><code>section: screens<br /> salva:<br /> fran:<br />end<br />section: links<br /> salva:<br /> right = fran<br /> fran:<br /> left = salva<br />end<br />section: options<br /> screenSaverSync = false<br />end</code></pre><br />En él se indican los nombres de los monitores y además la posición relativa de los mismos (<code>fran</code> está a la derecha de <code>salva</code> y <code>salva</code> está a la izquierda de <code>fran</code>).<br /><br />Si mi máquina tiene mi como IP la 192.168.0.3 y la de mi hermana tiene como IP la 192.168.0.1 y la mía funciona como servidor, debo ejecutar <code>synergys.exe --config synergy.conf --name salva</code> en mi máquina y <code>synergyc.exe --name fran 192.168.0.3</code> en el portátil de mi hermana. Mientras que en el caso en el que el servidor es el portátil, debo ejecutar <code>synergys.exe --config synergy.conf --name fran</code> en el portátil y <code>synergyc.exe --name salva 192.168.0.1</code> en mi ordenador.<br /><br />La versión de OS/2 del servidor parece no funcionar bien; solamente consigo que el puntero en el portátil se mueva, pero renqueando y sin que funcionen los botones y el teclado envía la señal al servidor en lugar de al cliente. (Digo <u>parece</u> porque puede ser culpa de la configuración.) La versión de OS/2 del cliente parece funcionar bien, salvo por lo que queda patente en el primer párrafo de la entrada.<br /><br />De hecho, lo más <i>espectacular</i> es ver cómo se copia y pega texto del <i>clipboard</i> (portapapeles) de forma completamente transparente entre una máquina y otra. (ClipView, la utilidad de Dave Saville también permite compartir el portapapeles entre dos máquinas a través de la red.)Salvador Parra Camachohttp://www.blogger.com/profile/06043187618736820735noreply@blogger.com0tag:blogger.com,1999:blog-8774163155458391091.post-65644112938560574542007-09-08T20:47:00.000+02:002007-09-08T21:19:57.470+02:00La sentencia parse versionLa instrucción <code>parse</code> de REXX permite, entre muchas otras cosas, saber con qué intérprete y qué versión del mismo estamos trabajando. A través de la sentencia <code>parse version rexxVersion</code>, el intérprete da a la variable un valor que indica el nombre del intérprete, el nivel del lenguaje y la fecha del intérprete.<br /><br />Así, por ejemplo, si es el intérprete de REXX clásico de eComStation el que interpreta el código, la variable valdrá <code>REXXSAA 4.00 3 Feb 1999</code>. Si es Regina, puede resultar algo como <code>REXX-Regina_3.3(MT) 5.00 25 Apr 2004</code> en las versiones más recientes o <code>REXX-Regina_3.0 4.95 25 Apr 2002</code> en versiones anteriores. Si es Reginald, puede devolver <code>REXX-Reginald_4.6 4.00 13 Aug 2005</code>, por ejemplo. Si es Open Object REXX, el resultado podría ser <code>REXX-ooRexx_3.0(MT) 6.00 28 Mar 2005</code>.<br /><br />En el primer ejemplo, <code>REXXSAA</code> identifica el intérprete REXX como el que forma parte de OS/2 y eComStation (si bien el intérprete REXX que forma parte del sistema operativo PC-DOS de IBM también se identifica a sí mismo como <code>REXXSAA</code> como probablemente le ocurra a alguna implementación más de IBM). El número <code>4.00</code> corresponde al nivel del lenguaje: el 4.00 corresponde al definido por la segunda edición de <i>The REXX Language</i> de Mike Cowlishaw, el nivel 5.00 corresponde al definido por el estándar ANSI de 1996 y el 6.00 corresponde al superconjunto de REXX clásico que es Object REXX. Y la fecha se supone que indica la fecha del intérprete en el mismo formato que <code>date()</code>.<br /><br />El estándar ANSI especifica que el nombre del intérprete debe ser la palabra REXX en mayúsculas seguida del nombre del intérprete en si mismo. Pero en algunos casos, el intérprete no sigue esa norma, como en el caso del Object REXX de IBM, que devuelve <code>OBJREXX 6.00 18 May 1999</code>, o BRexx, que devuelve <code>brexx 2.1.0 Mar 11 2003</code> (debe apreciarse que en este caso BRexx tampoco indica el nivel del lenguaje, sino su versión y que el formato de fecha no es el que se considera correcto por el estándar ANSI).<br /><br />Entre los intépretes más modernos se ha extendido la costumbre de indicar la versión del intérprete y la indicación de si es o no <i>multithreaded</i> (multihilo):<br /><ul><li><b>Regina (multihilo):</b> REXX-Regina_3.3(MT) 5.00 25 Apr 2004</li><li><b>Regina (ejecutable estático):</b> REXX-Regina_3.3 5.00 25 Apr 2004</li><li><b>Reginald:</b> REXX-Reginald_5.0 4.00 9 Apr 2006</li><li><b>Reginald Lite:</b> REXX-RegLite_5.0 4.00 3 Apr 2006</li><li><b>Open Object REXX:</b> REXX-ooRexx_3.0(MT) 6.00 28 Mar 2005</li></ul><br />El distinguir que intérprete y/o que nivel del lenguaje ejecuta nuestro código nos permite aprovechar características de un intérprete concreto o un nivel del lenguaje sin dejar a los otros fuera.<br /><br />El manejo de ficheros en REXX es una de las cosas que más cambian de una implementación a otra del lenguaje. Utilizando <code>parse version</code> podemos hacer lo siguiente:<br /><pre><code>parse version rxInterpreter rxLevel rxDate<br />select<br />when rxLevel < 4 then<br /> IO_routines = 'EXECIO'<br />when rxLevel < 5 then<br /> IO_routines = 'ANSI'<br />when rxLevel >= 5 then<br /> IO_routines = '.STREAM'<br />otherwise<br /> nop<br />end</code></pre>para decidir si usamos el comando EXECIO de los <i>mainframes</i> como sistema de manejo de ficheros, las funciones del estándar ANSI (<code>stream</code>, <code>charin</code>, <code>lineout</code>...) o el objeto <i>Stream</i> propio de Object REXX. O, si queremos dar soporte a BRexx y AREXX:<br /><pre><code>parse version rxInterpreter rxLevel rxDate<br />select<br />when rxInterpreter = 'AREXX' then<br /> IO_routines = 'AREXX'<br />when rxInterpreter = 'brexx' then<br /> IO_routines = 'BREXX'<br />when rxLevel < 4 then<br /> IO_routines = 'EXECIO'<br />when rxLevel < 5 then<br /> IO_routines = 'ANSI'<br />when rxLevel >= 5 then<br /> IO_routines = '.STREAM'<br />otherwise<br /> nop<br />end</code></pre><br />En ese ejemplo, consultando la variable <code>IO_routines</code>, podemos decidir qué código queremos ejecutar.<br /><br />Evidentemente este sistema es de utilidad limitada. Hay tantos intérpretes REXX para tantas plataformas que es imposible para cualquier programador conseguir que un programa de mediana envergadura se aproveche de <code>parse version</code> para que se ejecute en todos ellos.Salvador Parra Camachohttp://www.blogger.com/profile/06043187618736820735noreply@blogger.com0tag:blogger.com,1999:blog-8774163155458391091.post-40498767470438310202007-09-07T22:24:00.000+02:002007-09-07T23:00:38.793+02:00Salvando datos a través de FTPUn cliente nos trajo hace muy poquito un portátil HP al que deseaba que le realizásemos un formateo y una reinstalación del sistema operativo (un Windows XP Home Edition) sin borrarle sus ficheros y directorios de la partición de datos.<br /><br />El procedimiento no sería difícil de no ser por tres puntos esenciales:<br /><ol><li>El sistema operativo no arranca ni en modo seguro.</li><br /><li>El cliente ha destruido la partición de recuperación de HP</li><br /><li>Un Windows XP Home Edition Service Pack 2 ordinario no reconoce el disco duro SATA del citado portátil.</li></ol><br />La partición de recuperación que suelen incluir la mayor parte de los fabricantes que venden equipos preinstalados (HP, Dell, Acer...) generalmente es accesible a través de algún tipo de obscuro atajo de teclado en el arranque del PC. El PC arranca el sistema desde la partición de recuperación y normalmente puede recuperarse la partición del sistema tal como venía "de fábrica" sin tocar para nada la partición de los datos.<br />En el peor de los casos, cuando desconocemos el atajo de teclado o éste no funciona, podemos establecer con una herramienta de particionado de disco duro (como <a href="http://www.dfsee.com/">DFSee</a> no como Partition Magic) la partición de recuperación como partición de arranque, dejar que recupere el sistema y volver a establecer la partición del sistema como partición activa.<br /><br />Al no tener partición de recuperación se puede optar por instalar desde un CD ordinario (dado que no tenemos los discos de recuperación del sistema y aunque los tuviésemos, no tenemos garantías de que respeten la partición de datos), pero se da la circunstancia de que Windows XP Home SP2 no tiene los drivers necesarios para detectar el disco SATA y como el portátil no tiene disquetera (y no, una disquetera USB <b>NO</b> sirve) y por lo tanto no podemos instalar.<br /><br />Entonces es evidente que es necesario sacar los datos de algún modo del portátil. Un CD arrancable y un disco duro externo por USB parecen una buena opción, hasta que es patente que el único disco duro externo que tenemos no tiene suficiente espacio libre (y en ese momento no podemos liberar el espacio ocupado).<br /><br />Pienso un poquito y decido montar un servidor FTP con Filezilla en uno de nuestros ordenadores. Entonces inicio el portátil desde CD con un <a href="http://www.puppylinux.org/">Puppy Linux</a> (esa distribución es una verdadera joya en cuanto a ligereza y funcionalidad), configuro la red y con el cliente FTP que incluye (gFTP) transfiero todos los datos.<br /><br />Si los clientes fuesen conscientes de los malabarismos que a veces tenemos que hacer para proteger sus datos, quizás nos mirasen con otros ojos...Salvador Parra Camachohttp://www.blogger.com/profile/06043187618736820735noreply@blogger.com0tag:blogger.com,1999:blog-8774163155458391091.post-28684544689731442622007-09-06T22:18:00.000+02:002007-09-06T22:43:51.743+02:00Multifunción que bloquea el arranque de un PCEsta tarde me he enfrentado a uno de esos momentos tan poco gratificantes que se encuentran las personas demasiado a menudo en el mundo de la informática cuando un ordenador nuevecito, montado hacía apenas 24 horas, se negaba a arrancar.<br /><br />Puede ser bonito saber que el ordenador lleva en su interior una WinFast, pero cuando el logotipo permanece en la pantalla durante cinco minutos seguidos sin inmutarse por mucho que se pulsen las teclas (primero de uno de estos detestables teclados inalámbricos por USB -detestables por inalámbricos y por USB- y después con un teclado PS/2 de toda la vida) uno desea sacar un lanzagranadas y volar por los aires todo el equipo informático. Un equipo <u>completamente nuevo</u>.<br /><br />De todos modos, en estos casos se impone el sentido común antes que la ira y uno piensa que <i>tal vez algún dispositivo externo o un extraíble está causando el problema</i> aunque solamente sea porque ya ha visto cómo ordenadores se han bloqueado en el arranque al tener un llavero USB pinchado. Y un rápido vistazo permite comprobar que lo único inusual que tiene pinchado el PC es una multifunción Lexmark.<br /><br />En cuanto se despincha la multifunción, el ordenador arranca con completa normalidad.<br /><br />Presumiblemente el problema reside en el mismo punto que el caso de los llaveros USB pinchados en el momento del arranque, dado que la multifunción tiene un lector de tarjetas digitales que es tratado por el PC como un simple MSD (<i>Mass Storage Device</i>, es decir, un dispositivo de almacenamiento masivo).<br /><br />Si alguien piensa que apagando la impresora se soluciona el problema, lamento decepcionarle. Si alguien está pensando que basta con desactivar en la BIOS la búsqueda de arranque en <i>removables</i> (extraíbles), lamento decepcionarle.<br /><br />La solución más sencilla es quitar el cable de la multifunción y pincharla exclusivamente cuando el ordenador esté encendido.<br /><br />Sería interesante probar con distintas combinaciones de placas y multifunciones (conozco muchos casos de gente con multifunciones de HP que no tienen este tipo de problemas, desafortunadamente no sé si alguna de esos ordenadores tiene una WinFast) para ver cuáles dan este problema. Pero que no cuenten conmigo para ello.Salvador Parra Camachohttp://www.blogger.com/profile/06043187618736820735noreply@blogger.com0tag:blogger.com,1999:blog-8774163155458391091.post-35775753620580550782007-09-05T22:33:00.000+02:002007-09-05T23:27:23.313+02:00Precisión arbitraria en la aritmética REXXUna de las características de la familia REXX (REXX clásico, Object REXX, NetREXX y otras variaciones) que la diferencia de otros lenguajes de programación más extendidos es su aritmética.<br /><br />En ella no nos encontramos cosas como los clásicos conceptos de variables numéricas de tipo <code>int</code>, <code>float</code> o <code>double</code>... pero de lo que quisiera hablar hoy es de una característica concreta de la aritmética REXX: la precisión arbitraria.<br /><br />¿Qué queremos decir con <i>precisión arbitraria</i>?<br /><br />El siguiente código imprime el resultado del cociente de 1 entre 3:<br /><br /><code>say 1/3</code><br /><br />es decir: 0.333333333. Cualquiera que tenga claras ciertas nociones de matemáticas básicas sabrá que en realidad eso no es 1/3, sino simplemente una aproximación con 9 cifras significativas a 1/3 porque la representación decimal de 1/3 tiene infinitos decimales. <br /><br />REXX nos da el resultado con 9 cifras significativas porque es el número de cifras con el que trabaja.<br /><br />Si hacemos lo siguiente:<br /><br /><code>say 1000000000 + 1</code><br /><br />obtendremos 1.00000000E+9. Es decir, que perdemos ese 1 que hemos sumado. Puede que bajo ciertas circunstancias nos interesase ese dígito, pero dado que el lenguaje trabaja con 9 cifras significativas y que ese dígito extra sobrepasa los 9 parece que debamos quedarnos sin el mismo. Y aquí es donde entra en juego el carácter <i>arbitrario</i> de la precisión:<br /><br /><code>numeric digits 100<br />say 1000000000 + 1</code><br /><br />Con esta sentencia nueva en el código, el resultado se convierte en 1000000001. Y en el caso anterior de 1/3 obtendríamos una ristra de cien cifras significativas (es decir, cien bonitos números 3 uno detrás del otro). La instrucción <code>numeric digits</code> nos permite variar el número de cifras significativas.<br /><br />Consideremos la clásica función factorial escrita iterativamente:<br /><br /><code>factorial: procedure<br /> parse arg n<br /> factorial = 1<br /> do i = 1 for n<br /> factorial = factorial * i<br /> end<br /> return factorial</code><br /><br />Si ejecutamos:<br /><br /><code>say factorial(100)</code><br /><br />el resultado es 9.33262137E+157. Mientras que si ejecutamos:<br /><br /><code>numeric digits 1000<br />say factorial(100)</code><br /><br />el resultado es exactamente el factorial de 100: <br /><br />93326215443944152681<br />69923885626670049071<br />59682643816214685929<br />63895217599993229915<br />60894146397615651828<br />62536979208272237582<br />51185210916864000000<br />000000000000000000.<br /><br />Intentad haced esto utilizando exclusivamente la aritmética básica de otro lenguaje de programación y probablemente descubrais que no podeis o es terriblemente más complicado. Esto no significa que REXX sea mejor, simplemente que es diferente.Salvador Parra Camachohttp://www.blogger.com/profile/06043187618736820735noreply@blogger.com0tag:blogger.com,1999:blog-8774163155458391091.post-79108189238574191142007-09-04T22:35:00.000+02:002007-09-05T00:01:38.968+02:00¡Contagie su ordenador a través de USB en tres sencillos pasos!Esta misma mañana he invertido varias horas entre otras cosas en limpiar de <i>malware</i> (esto es, de <i>software</i> malintencionado como son los virus, los troyanos y los gusanos) unos cinco ordenadores de sobremesa, tres portátiles, seis llaveros USB y cuatro tarjetas de memoria (MMC y SD). Si bien no todos estaban infectados, era necesario comprobarlo uno a uno porque estaba claro cuál había sido el sistema de propagación de la mayoría de las infecciones presentes: los llaveros USB.<br /><br />Últimamente es algo muy común ver llaveros USB que transmiten virus de un ordenador a otro como si fuesen el mosquito anófeles transmitiendo la malaria. Y por lo que he podido ver, es algo que se produce con cierta frecuencia en centros públicos como colegios e institutos donde los usuarios llevan su información de un ordenador a otro. Sospecho que en estos casos la propagación es especialmente rápida y en una semana probablemente casi todos los ordenadores estén infectados.<br /><br />El modo en el que funciona el contagio es enormemente sencillo y se basa en lo que ya hace muchos años era para mí un fallo de diseño y seguridad de Windows 98: el <i>autorun</i>.<br /><br />Cada vez que se inserta un dispositivo extraíble como un CD, un DVD o un sistema de almacenamiento como una llave USB, Windows busca en la raiz de esa unidad un fichero de texto llamado <i>autorun.inf</i>. Ese fichero de texto indica a Windows cosas como el icono con el que debe aparecer en <i>Mi PC</i>, las acciones que deben agregarse al menú contextual de la unidad (el menú que aparece al pinchar con el botón derecho del ratón) y lo que debe pasar automaticamente al detectarse la unidad. Generalmente esto es utilizado en CDs y DVDs para iniciar algún tipo de asistente de instalación aunque yo mismo en un arranque de malicia hace años grabé algunos CDs con un <i>autorun.inf</i> que apagaba el ordenador en el se introdujese y esa característica de Windows estuviese activada.<br /><br />Los CDs, que eran comunes como medio de transporte de información hace cinco años, y los DVDs (que para el caso podemos considerar como CDs <i>grandes</i>) son dispositivos de <b>sólo lectura</b>. No podemos arrastrar ficheros a ellos para copiarlos en ellos, no podemos modificar ficheros existentes y es <b>IMPOSIBLE</b> añadir nada al CD si está finalizado. No son un modo cómodo de propagación para el <i>malware</i>.<br /><br />Pero desde que los llaveros USB y similares han desplazado casi completamente a los disquetes el <i>malware</i> tiene un método de propagación nuevo puesto que son dispositivos de lectura y escritura. Y ahí tenemos el primero de los pasos: si se pincha un llavero en un ordenador infectado por cierto tipo de <i>malware</i>, éste puede crear una o varias copias en el llavero y un fichero <i>autorun.inf</i> con instrucciones para ejecutar alguna de las copias. El segundo paso consiste en que el usuario lleva el llavero USB a otra máquina. Y en el tercero, al pinchar el llavero infectado en un ordenador limpio, si la característica de <i>autorun</i> está activada del modo adecuado, se ejecutará la copia del <i>malware</i> que se copiará a sí misma en el disco duro del ordenador obligándole a ejecutarla cada vez que lo encendamos.<br /><br />Un método sencillo, simple y efectivo.<br /><br />Evitar el contagio no es sencillo pero hay algunas cosas que probablemente ayuden:<br /><ul><br /><li>Si la llave USB lleva un método de bloqueo (los reproductores MP3 suelen llevar algún sistema de bloqueo generalmente etiquetado como <i>hold</i> y otro tanto ocurre con muchas tarjetas digitales) y simplemente nos interesa llevar algo a un ordenador que no es de confianza (y el que lea esto debe pensar como un paranoico que, en el mejor de los casos, solamente su ordenador es de confianza) lo activamos y así el dispositivo no podrá ser infectado.</li><br /><li>Desactivar algunas de las características del <i>autorun</i> en nuestro Windows para que nada se ejecute automáticamente sin nuestro permiso (para ello, buscad información en Internet).</li><br /><li>Darnos cuenta de que cuando en la ventana emergente que aparece al pinchar dispositivos extraíbles en Windows XP hay indicadores extraños sobre la lista de acciones con el nombre de "Programa", es probable que el llavero USB esté infectado y debamos someter a un escaneo tanto el llavero como el equipo.</li><br /></ul><br />Todo lo dicho solamente es aplicable a usuarios de Microsoft Windows. Aquellos que utiliceis otro sistema operativo (Linux, BeOS, Mac OS X, OS/2, FreeBSD... el que sea) podeis estar razonablemente seguros de que este sistema de infección no os afectará.Salvador Parra Camachohttp://www.blogger.com/profile/06043187618736820735noreply@blogger.com4tag:blogger.com,1999:blog-8774163155458391091.post-27294585836482924552007-09-03T23:06:00.000+02:002007-09-04T00:14:14.687+02:00Reimplementando BIFs en REXXEn REXX es frecuente referirse oficiosamente a toda función que forma parte del núcleo del lenguaje como BIF: <i>Built-In Function</i>. El estándar ANSI de 1996 define una serie de funciones dentro de esta categoría como por ejemplo <code>abbrev</code>, <code>words</code>, <code>date</code> o <code>address</code>. En general las implementaciones del lenguaje tienen todas las BIFs definidas en el estándar, añadiendo aportaciones propias o tal vez careciendo de alguna concreta.<br /><br />Lo peculiar del caso es que REXX permite que el programador defina las funciones internas de su programa (aquellas que se incluyen dentro del mismo fichero) utilizando los mismos nombres que alguna BIF y aun así seguir utilizando la BIF cuyo nombre hemos utilizado.<br /><br /> <code><br /> /* words.rex */<br /><br /> parse pull frase<br /> say words(frase)<br /><br /> exit<br /> </code><br /><br />Este sencillo ejemplo se limita a contar el número de palabras que tiene una cadena que introduce el usuario utilizando la BIF <code>words</code>. La línea con la sentencia <code>parse pull frase</code> se limita a meter la entrada del usuario en la variable <code>frase</code>. Y la siguiente línea nos dice la salida de la función <code>words</code> aplicada sobre la variable <code>frase</code>, es decir, muestra en pantalla el número de palabras.<br /><br />Si el programador introduce una función en el código como en el siguiente caso:<br /><br /> <code><br /> /* words.rex */<br /><br /> parse pull frase<br /> say words(frase)<br /><br /> exit<br /><br /> words: procedure<br /> return 'No me apetece contar palabras'<br /> </code><br /><br />El resultado es que en lugar de ejecutarse la BIF <code>words</code>, se ejecuta nuestra función. Es decir, que sea cual sea la entrada del usuario, el programa siempre imprimirá que no le apetece contar palabras.<br /><br />A pesar de tener <i>ocupado</i> el nombre de la BIF <code>words</code>, podemos seguir accediendo a ella llamandola por su nombre en mayúsculas entrecomillado (por comillas simples). Así, en el siguiente ejemplo, se imprime siempre que no le apetece contar palabras e inmediatamente después el número de palabras tal como lo cuenta la BIF <code>words</code>:<br /><br /> <code><br /> /* words.rex */<br /><br /> parse pull frase<br /> say words(frase)<br /> say 'WORDS'(frase)<br /><br /> exit<br /><br /> words: procedure<br /> return 'No me apetece contar palabras'<br /> </code><br /><br />Evidentemente podemos ejecutar la BIF desde dentro de nuestra función:<br /><br /> <code><br /> /* words.rex */<br /><br /> parse pull frase<br /> say words(frase)<br /><br /> exit<br /><br /> words: procedure<br /> parse arg cadena<br /> return 'WORDS'(cadena)<br /> </code><br /><br />Esto nos permite cierto número de posibilidades como <i>cambiar</i> el comportamiento de las BIFs de nuestro intérprete. Esto puede ser interesante, por ejemplo, cuando un intérprete no implementa una BIF como estamos acostumbrados a utilizar. Imaginemos que un programador acostumbrado a las características de la BIF <code>date</code> para hacer aritmética de fechas propias del estándar y presentes en Object REXX y Regina desea que su código funcione en REXX clásico en OS/2 (que carece de esa característica). Si hace una función <code>date</code> que supla esas características ausentes en ese intérprete, solamente tiene que añadir esa función en la versión de su programa para OS/2 y no tendrá que tocar ninguna línea más de código.<br /><br />Lo interesante es que podemos reimplementar muchas de las BIFs orientadas a manejo de cadenas solamente utilizando bucles condicionales y la instrucción <code>PARSE</code>. En el caso que nos ocupa, podríamos hacer:<br /><br /> <code><br /> words: procedure<br /> parse arg string<br /> n = 0<br /> do while string <> ''<br /> parse var string . string<br /> n = n + 1<br /> end<br /> return n<br /> </code><br /><br /><code>parse</code> coge el <i>arg</i>umento de la función que hemos escrito y lo introduce en la variable <code>string</code>, mientras la variable <code>string</code> no esté vacía <code>parse</code> coge la primera palabra de la <i>var</i>iable <code>string</code> y la descarta (.) metiendo el resto en <code>string</code>. Cada vez que descarta una palabra, aumenta el contador, y cuando las ha descartado todas, nos devuelve el valor de ese contador, es decir, del número de palabras. (Podríamos habernos ahorrado un par de líneas, pero he preferido dejarlo así por claridad.)<br /><br />Como ejercicio para principiantes, el intentar reimplementar BIFs sin utilizar BIFs es algo, creo yo, muy educativo. Permite apreciar el valor de la instrucción <code>parse</code> y familiarizarse con las BIFs orientadas a cadenas.<br /><br />Solamente podemos "redefinir" las BIFs a través de funciones internas de nuestro programa. Las funciones externas no nos valdrán y tampoco aquellas que estén en el macroespacio (si la implementación lo tiene). Pero cuando la BIF no está definida en nuestro intérprete (como ocurre con <code>countstr</code> en REXX clásico para OS/2), entonces podemos implementarla como una función externa y cargarla en el macroespacio...<br /><br />Pero, como decía Jack Lemmon en <i>Irma la dulce</i>: <i>Eso es otra historia</i>.Salvador Parra Camachohttp://www.blogger.com/profile/06043187618736820735noreply@blogger.com0