# Bluefish manual chapter 4: Development guidelines

anterior | contenidos | siguiente

# Capítulo 4: Pautas de Desarrollo

Este documento describe las convenciones usadas en el proyecto Bluefish para escribir código. Por favor, sugieran mejoras o agregados.

Esto no_significa poner obstáculos a tu código sino que sirve para estructurarlo un poco. Por el momento, Bluefish no está muy bien estructurado y actualmente estoy tratando de mejorar esto un poco.

¡Feliz Programación!
Olivier Sessink
http://bluefish.openoffice.nl/

### Depurando a Bluefish

#### Cuelgues - viendo el estado de la pila: backtrace

Para hacer un seguimiento útil y si no tienes idea dónde se cuelga el programa, ve al directorio de los archivos fuente y ejecuta el siguiente comando:`make distclean ./configure --with-debugging-output make gdb src/bluefish` Esto iniciará el depurador con el binario recién compilado. Si no tienes ninguna idea abre el archivo, agrega la siguiente línea en la parte superior `#define DEBUG` y ejecuta`make distclean ./configure make gdb src/bluefish` Una vez que se inicia el depurador presiona `r<enter>` si se detiene la ejecución o `c<enter>` si dice que no esta permitido leer la memoria. Corre el programa hasta que se cuelgue, entonces ejecuta `bt<enter>`. Envía la salida (digamos las últimas 50 líneas) a la lista de correo de desarrollo. Esto nos dará alguna información de depuración y nos dirá exactamente donde se localiza la falla en el programa.

### El Sangrado y el Formato

Sé perezoso y usa `cd src indent -kr -ts4 *.c *.h` Esta es la convención que usa Kernighan & Ritchie con ancho de tabulación 4

No uses comentarios tipo C++ sino usa el de C /* y */. gcc hace las cosas bien pero otros compiladores C pueden llejar a quejarse.

### Los Nombres

usa void name_cb() para una retrollamada (callback) que puede ser usada en forma global como, por ejemplo, una retrollamada para comenzar un diálogo (también puede ser cualquier cosa de allí el void)

usa static void name_lcb() para una retrollamada local como, por ejemplo, el botón OK de un diálogo (también puede ser cualquier cosa de allí el void)

trata de que el nombre de la función sugiera lo que puede hacer, por ejemplo, doc_do_replace() haría un reemplazo en un documento determinado, etc.

Actualmente poseemos un estándar para el document.c. Todas la funciones que empiezan con doc_...() tienen un parámetro Tdocument. Todas las funciones sin él o bien son antiguas (y por lo tanto se las deberían renombrar) o son funciones que funcionan como un main_v->current_document (un puntero al documento actual mostrado).

### Declarando Procedimientos

Siempre declarar a las funciones estáticas que no necesitan ser vistas fuera del archivo como static. La razón: evitar contaminar el espacio de los nombres globales. Las funciones estáticas serán enlazadas con el mismo fle. Todos los procedimientos que se usan en otros archivos (públicos) deben figurar en el archivo .h declarado.

Todas las variables que se usen en otros archivos (públicos) deben figurar en el .h precedidas por extern. Sin embargo, trata de evitar el uso de variables globales. La mayoría de las veces esto se puede hacer declarando una estructura typedef.

No pongas ningún extern bla() al principio de un archivo .c file, usa en cambio #include otherfile.h. Así si cambias una función sólo tendrás que modificar ese archivo .h en particular. En otras palabras, declara las funciones globales en los archivos .h y en ningún otro lado.

### Los Archivos de Cabecera

Si incluyes un archivo de cabecera tal como `#include <string.h>` por favor, agrega un comentario explicando por qué se necesita dicha cabecera. Algo así `#include <string.h> /* strlen() */`

### Archivos Nuevos

Si estás escribiendo un archivo .c nuevo, escribe también un archivo .h e inclúyelo en él. Usa include guards en todos los archivos .h como en bluefish.h

    #ifdef __BLUEFISH_H
    #define __BLUEFISH_H
    ... poner todas las declaraciones aquí ...
    #endif

La razón: permitir que el compilador verifique la consistencia entre los archivos .c y los .h

### Los distintos archivos

Listado en orden alfabético

- bflib.c - funciones generales sin GUI tales como las funciones de cadenas y otras
- bluefish.c - inicio ysalida, mensajes de administración de la cola de impresión
- callbacks.c - retrollamadas en general tales como las funciones de Weblint
- cap.c - con mayúsculas o sin mayúsculas en el HTML
- char_table.c - tabla de caracteres y elementos especiales
- coloursel.c - diálogo para la selección de colores
- configure.c - diálogo para la configuración
- document.c - todas las funcionan que manejan el Tdocument, cortar, copiar, pegar y otras funciones para trabajar sobre los documentos
- gtk_easy.c - atajos GTK sencillos para reducir la repetición de código usado en un montón de otros archivos
- highlight.c -el código para resaltar la sintaxis
- html.c - diálogos html y retrollamadas
- html_diag.c - las funciones que se usan para crear los diálogos html
- html_table.c - diálogos para tablas y retrollamadas
- html_form.c - diálogos para formularios y retrollamadas
- images.c - diálogos para imágenes y miniaturas
- init.c - analizador rcfile y línea de comandos para cargar opciones, poner valores por defectos a todas las variables, verificar si los directorios que se necesitan existen, etc.
- interface.c - la propia GUI principal y la pantalla inicial
- javascript.c - ??
- menu.c - el menú principal y el menú personalizado, incluyendo el editor de menú
- network.c - abrir código desde la Web. Aquí también se puede agregar un verificador de enlaces muertos
- pixmaps.c - carga de archivos xpm en el widget GTK
- project.c - todas las funciones que manejan el Tproject
- ref_dialog.c - el código del diálogo de referencia
- rpopup.c - menú click derecho y verificador de HTML en una GList
- snr2.c - buscar y reemplazar, administración de enlaces (usando regex)
- spell.c - verificador spell
- spell_gui.c - Gui verificador spell
- stringlist: una GList (ver documentación de glib) que posee sólo contenido gchar *
- stringlist.c - (GList con strings) funcionalidad de manejo de lista de cadenas y listas de arreglos en la GUI
  - arraylist: una GList que contiene un arreglo de gchar * terminado en NULL
- toolbars.c - las barras de herramientas principal y la HTML
- undo.c - deshacer/rehacer original
- undo2.c - reescrito desde el principio, actualmente está por defecto
- undo.c - deshacer/rehacer
- wizards.c - asistentes tales como los html*.c pero insertando múltiples etiquetas simultáneamente
- wml.c - soporte WML

### Parches

Antti-Juhani Kaijanaho escribió:

1. Conservo dos estucturas jerárquicas diferentes de Bluefish: una sin tocar (la pre-oficial) y otra que uso para trabajar. Por cada cambio introducido creo una nueva estructura jerárquica.
2. Antes de crear un parche ejecuto "make distclean".
3. Cuando quiero crear un parche, me posiciono en el directorio padre de las dos estructuras jeráquicas. Luego ejecuto "diff -Naur pre_estructura_oficial mi_estructura_modificada | bzip2 -9c > patchbla.diff.bz2" (donde de pre_estructura_oficial y mi_estructura_modificada son las dos estucturas jerárquicas).

### Uso del CVS

Olivier escribió:
Usar bash (rellenar con el propio nombre de usuario):

    CVSROOT=:pserver:USERNAME@cvs1.openave.net:/home/cvsroot/bluefish1
    export CVSROOT
    cvs login
    cvs checkout bluefish

esto descargará la versión más actual en desarrollo de Bluefish. Si ya has hecho esto antes puedes ejecutar

    cvs update -dP

para actualizar tus archivos locales con los nuevos cambios. Para enviar los archivos:

    cvs commit

enviará tus nuevos cambios al repositorio CVS. Por favor, siempre actualiza justo antes de hacer un envío, para comprobar si otras personas estan trabajandos sobre el mismo código fuente

Pueden resultar útiles algunos comandos másl:

- cvs log src/document.c mostrará los registros de este archivo indicando todas las revisiones
- cvs diff -c -r 1.2 -r 1.3 src/document.c devolverá un parche con las diferencias entre la revisión 1.2 y la 1.3 del document.c (-c = salida comprensible para humanos)
- cvs annotate src/document.c muestra un conjunto de anotaciones de cada parche y los comentarios referentes al archivo

### Lineamientos del CVS

Antti-Juhani escribió:

- Los envíos al tronco se permiten siempre y cuando no destruyas la estructura. Si deseas añadir nuevas características significativas primero discútelas en la lista de correos. El tronco es la serie "inestable"...es lo que usas

      cvs checkout

- Cuando deseamos congelar una versión se crea una rama "congelada" (con el nombre, por ejemplo, rel_0_5_branch para la versión congelada 0.5). Los envíos a una rama congelada se permiten sólo si:
  - si no rompes la estructura
  - si no agregas nuevas características
  - si tu envío es necesario para la siguiente versión (supresión de errores, actualizaciones de archivos po, etc)
  Esto lo consigues haciendo

      cvs checkout -r nombre_rama

- Cuando el lanzamiento de una rama congelada está listo, el conjunto de archivos más reciente de la rama se lo etiqueta como, por ejemplo, "rel_0_5" (para el lanzamiento 0.5). La rama se declara "estable". Se crean los tarballs, debs y rpms. No se permiten envíos en una rama estable. Después del lanzamiento la rama estable se une al tronco.

Este plan de lanzamiento de tres etapas, según el modelo seguido por Debian, tiene en cuenta los desarrollos inestables paralelamente a la preparacíon del lanzamiento.

Para crear una rama:

    cvs tag -b nombre_rama

Observemos que el árbol donde se hizo cvs tag sigue siendo el tronco, no la rama. Se necesita luego verificar una nueva copia de la rama:

    cd algún_lugar
    cvs checkout -r nombre_rama

Haciendo el envío a esta copia de trabajo equivale a hacerlo a la rama dejando el tronco sin tocar. Otras personas pueden acceder a la rama haciendo lo mismo.

    cvs checkout -r.

Cuando quieres agregar tus cambios al tronco haz lo siguiente

    cvs update -j name_of_branch

en el árbol original (el tronco). Arregla cualquier conflicto y envíalo.

### Traducciones

Roland Steinbach (roland@ratisbona.com)escribió:
si deseas comenzar, por ejemplo, con la traducción al griego (gr) debes:

- copiar el bluefish.pot al gr.po
- las líneas msgid llevan el texto que se debe traducir las líneas msgtxt contienen las traducciones
- envía el archivo .po a mí o a la lista

En futuras versiones si necesitas actualizar el archivo .po tienes que:

- buscar las líneas que contienen la palabra "fuzzy" (salvo la línea 6 que está bien). Se tratan de traducciones aproximadas burdas. Borra la línea que contiene la palabra "fuzzy" y corrige la traducción
- buscar las líneas sin traducir (buscar 'msgtxt ""') y tradúcelas.

¡Eso es todo!

### Algunos trucos

- si deseas agregar una propiedad, agrégala a Tproperty (en bluefish.h) y fija la línea de inicialización en main_v_props_init() de init.c. Si la quieres en la GUI debes editar configure.c, debería haber una línea en configure_cb() y otro línea en apply_config(). Podría haber más líneas en el caso de propiedades más avanzadas.
- gtk_easy.c contiene una gran cantidad de funciones gtk fáciles de usar para crear diálogos y fijar el valor a un montón de variables
- La macro DEBUG_MSG() funciona como la función printf(), si #define DEBUG está al principio del archivo o si se usa ./configure con --with-debug, también lo removerá el preprocesador.

### Nuevas versiones

Cosas para hacer en las próximas versiones:

- quitar #define DEVELOPMENT de default_header.h
- comentar que el include depende del Makefile (se rompe en un HP-UX)
- usar cvs export

... Tengo que terminar esto.

### Enlaces útiles

- referencia glib , mira las funciones de cadenas y las listas doblemente enlazadas
- referencia gdk , fuentes y mapas de colores
- refencia gtk , el resto, todos los widgets, prototipos de retrollamadas etc.
- preprocesador C
- autoconf/automake, o el GNU configure build system
- Programando en C, un tutorial muy bueno
- CVS book, un buen libro sobre el uso del CVS
- cvs2cl, generador CVS-ChangeLog

anterior | contenidos | siguiente