miércoles, 29 de junio de 2011

Primera impresión del iPad2 de un programador de Software Libre

La semana pasada mi madre ha decidido comprarse un iPad2 por razones de movilidad. El simpático computador pesa alrededor de 600 gramos, y goza de una muy buena fama. Escogió el modelo con opción 3G y con 32 GB en disco duro. Por mi parte, no encontré ningún motivo para evitar esta compra para un usuario con modestas pretensiones. ¿Cuáles son estas pretensiones?
  • Escribir en un procesador de textos decente.
  • Proyectar películas desde YouTube, o presentaciones desde archivos PowerPoint.
La propaganda oficial argumenta una gran variedad software disponibles desde AppStore, las cuales es posible adquirir ya sea comprando o descargando gratuitamente. Desde que salió el iPhone, desconfié de esta plataforma cerrada, pero no había tenido la posibilidad de probarla en carne propia.
Al ayudar a mi madre en la configuración de su iPad para que pudiera cumplir sus expectativas me encontré con un verdadero calvario que comprobó mis reservas iniciales. Enumeraré lo peor que pude encontrar:
  • De las aplicaciones disponibles desde el AppStore son muy contadas las que ofrecen verdadera calidad, incluso dentro de las aplicaciones con costo.
  • No pude encontrar un Procesador de Textos decente. Un trabajo de investigación necesariamente requiere de citas y pies de página. Ni Pages(creado por Apple y la aplicación más avanzada en este sector) pudo ofrecer esta característica tan elemental. Las demás aplicaciones ofimáticas ofrecían aún menos capacidades.
  • La conectividad es pésima. El dispositivo se encuentra tan cerrado que no puede acceder libremente una red e imprimir en algún servidor de impresiones.
  • Si bien Pages es el procesador de texto más avanzado, su productor no permite conectarse a servicios tan importantes como Dropbox y sólo se limita a sus propios servicios (iDisk y iCloud).
Al final mi madre terminó usando DocsToGo para estar constantemente interactuando con su computadora vía Dropbox, aún a costa de características de Pages. En lo particular extrañé compilar las aplicaciones de mi preferencia, usar Python y en general gozar de una verdadera computadora.
El harware tiene buena pinta, el problema es lo cerrado del sistema. Yo no compraría uno de estos equipos y no los recomiendo, pero si alguien quiere gastar más de diez mil pesos para escuchar música, ver alguna película y jugar, adelante, quizá esta curiosidad es para ustedes.

sábado, 18 de junio de 2011

Hacer que autoconf detecte LUA 5.1

He tenido algunos problemas para poder hacer detectar las librerías de LUA en autotools. He logrado realizar esto con algunas pruebas de nombres y así lograr incluir las bibliotecas y las cabeceras. AUX_LUA.m4 no logra detectar LUA en Debian, pero no se si también tiene dificultades en otras distribuciones. Al parecer en Ubuntu también existe un problema semejante.

Aquí el código básico del configure.ac que busca LUA 5.1.



AC_INIT([luaexp], [1.0], algo@correo.com)

AC_PREREQ(2.61)
AC_CANONICAL_HOST
AC_CANONICAL_BUILD
AC_CANONICAL_TARGET

AM_INIT_AUTOMAKE([foreign -Wall -Werror])
AC_PROG_CC

dnl Check for LibLua: --------------------------------------------------------

AC_MSG_CHECKING([for Lua package name])
PKG_CHECK_EXISTS([lua5.1], [LUA="lua5.1"],
[PKG_CHECK_EXISTS([lua-5.1], [LUA="lua-5.1"], [LUA="lua"])])
AC_MSG_RESULT([$LUA])

PKG_CHECK_MODULES([LUA],
[$LUA],
,
[ [echo "$LUA not found via pkg_config, checking AC_CHECK_LIB:"]
AC_CHECK_LIB([$LUA],
[lua_newstate],
,
[AC_MSG_ERROR([LUA no found! http://www.lua.org/download.html])]
)
[echo "$LUA successfully located"]
]
)

AC_DEFINE([HAVE_LUA],[1],[Define to 1 if you have the `LUA` library])


CFLAGS="$CFLAGS $LUA_CFLAGS"
LIBS="$LIBS $LUA_LIBS"


AC_CONFIG_HEADERS([config.h])
AC_CONFIG_FILES([Makefile src/Makefile])

AC_OUTPUT


Espero esto ayude a cualquier otra persona que necesite incluir LUA en su proyecto. En negrita resalto el código específico para la detección.

viernes, 26 de noviembre de 2010

Google Code-In en acción!

Muchos jovenes de menos de 18 años están participando en un verdadero maratón, resolviendo las tareas más variadas que les ponen en el mundo del software libre y abierto. El premio: $500 dólares y una invitación a google de los jóvenes más destacados. Tux4Kids, con todos sus proyectos también está participando, y los primeros resultados son muy halagadores.
En este momento me encuentro subiendo al repositorio un arquero que un joven creó para TuxHistory. también tuxMath ha tenido un avance muy importante; la reorganización de sus asteroides en niveles.
Inivito a todos lo interesados a darse una vuelta por www.google-melange.com para participar, o simplemente para observar el avance del concurso.

jueves, 12 de agosto de 2010

El verano ha terminado: TuxHistory



Les muestro la primera versión de prueba, limitada, pero funcional como resultado del Google Summer of Code. Falta mucho camino por recorrer para volver a este juego en una opción real de entretenimiento, pero las bases han sido creadas. Lo veo después de mucho esfuerzo, y siento que falta aún tanto.

sábado, 7 de agosto de 2010

Corrupción de memoria? La solución es

Esto será una entrada corta. Programando en C uno no puede menos que pensar que en algún momento los punteros, allocs y por supuesto los arreglos no funcionarán como uno espera. Pero encontrar estos errores entre míles de líneas de código definitivamente no es algo agradabale, claro. sin la ayuda de buenas herramientas.
Programando Tuxhistory me encontré con una muy desagradable sorpresa, un fallo de segmentación que se daba en los lugares mas diversos. Parecería como si hubiera una sinfín de ellos esparcidos por tódo el código. El debugging simple no daba con el responsable, gdb arrojaba lugares exactos donde sedaban, pero nada parecía estar mal, hasta que, gdb señaló al culpable a glib, malloc, etc... Esto no parecía ser más que una corrupción grave de memoria.
Por suerte logré encontrar el fabuloso VALGRIND! Wow! Una estupenda herramienta para poder identificar el verdadero orígen del problema y analizar las errores de escritura, lectura, corrupcion y leaks de memoria. Logré descubrir que el verdadero problema se encontraba en un arreglo que se debordaba con el paso del tiempo y corrompía la memoria aledaña. En verdad, si se encuentran en una situación como esta, les recomiendo ampliamente usar Valgrind http://valgrind.org/ y su excelente documentación: http://valgrind.org/docs/manual/manual.html
Y lo mejor es LIBRE bajo GPL!

jueves, 22 de julio de 2010

Mi configuración VIM

Agrego mi configuración de mi archivo .vimrc Lo hago para compartirlo con el todos y sobre todo para poderlo usar en otras computadoras.


syntax on
set hls
set expandtab
set textwidth=0
set tabstop=4
set softtabstop=4
set shiftwidth=4
set autoindent
set backspace=indent,eol,start
set incsearch
set ignorecase
set ruler
set wildmenu
set smarttab
set nu
set mouse=a

filetype indent on
filetype on
filetype plugin on

let g:pydiction_location = '/home/julio/.vim/after/ftplugin/pydiction/pydiction-1.2/complete-dict'

autocmd FileType python set omnifunc=pythoncomplete#Complete
autocmd FileType javascript set omnifunc=javascriptcomplete#CompleteJS
autocmd FileType html set omnifunc=htmlcomplete#CompleteTags
autocmd FileType css set omnifunc=csscomplete#CompleteCSS
autocmd FileType xml set omnifunc=xmlcomplete#CompleteTags
autocmd FileType php set omnifunc=phpcomplete#CompletePHP
autocmd FileType c set omnifunc=ccomplete#Complete

map <C-s>:setlocal spell spelllang=es_mx<CR>
map <C-e>:setlocal spell spelllang=en_us<CR>
map <C-q>:setlocal nospell<CR>

miércoles, 14 de julio de 2010

Arreglos dinámicos multidimensionales en C

En muchas ocaciones no queremos crear un arreglo que se utilice sólo la menoria necesaria en tiempo de ejecución. Sin embargo no resulta tan claro crear este tipo de arreglos de forma dinámica. Peor aún, si creamos un arreglo dentro de una función y queremos revolver el valor de un arreglo estatico esto sería imposible, ya que como es una variable local de la función se elimina antes de poder pasar el valor. Por lo tanto incluyo este pequeño código para poder realizar estas funciones.



#include <stdlib.h>
#define FREE(p) do { free(p); (p) = NULL; } while(0)

int **alloc_array(int, int);
void free_array(int **, int);

int **alloc_array(int x_size, int y_size)
{
int i;
int **array;
array = malloc(x_size * sizeof(int *));
if(array == NULL)
{
return NULL;
}
for(i = 0; i < x_size; i++)
{
array[i] = malloc(y_size * sizeof(int));
if(array[i] == NULL)
{
return NULL;
}
}
return array;
}

void free_array(int **array, int x_size)
{
int i;
for(i = 0; i < x_size; i++)
FREE(array[i]);
FREE(array);
}


Como vemos, tambien es necesario liberar la memoria que hemos reservado para nuestra memoria. Es necesario hacer esto para cada una de las variables y a su vez referenciar todos los punteros a NULL.