/[ambar]/ambar/accion.py
ViewVC logotype

Diff of /ambar/accion.py

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2.5 by TuringTest, Tue Aug 19 22:46:26 2003 UTC revision 2.6 by TuringTest, Sun Aug 24 23:34:41 2003 UTC
# Line 74  class Accion(object): Line 74  class Accion(object):
74      #      #
75      NOMBRES = {      NOMBRES = {
76            
77          "Personaje": {      "Personaje": {
78              "mover":               [ ("id", "Personaje"), ("sala_destino", "Sala") ],          "mover":               [ ("id", "Personaje"), ("sala_destino", "Sala") ],
79              "seguir":              [ ("id", "Personaje"), ("lider", "Personaje") ],          "seguir":              [ ("id", "Personaje"), ("lider", "Personaje") ],
80              "no_seguir":           [ ("id", "Personaje") ],          "no_seguir":           [ ("id", "Personaje") ],
81              "hablar":              [ ("id", "Personaje"), ("texto", "string"), ("idioma", "Idioma", "oestron") ],          "hablar":              [ ("id", "Personaje"), ("texto", "string"), ("idioma", "Idioma", "oestron") ],
82              "susurrar":            [ ("id", "Personaje"), ("oyente", "Personaje"), ("texto", "string"), ("idioma", "Idioma") ],          "susurrar":            [ ("id", "Personaje"), ("oyente", "Personaje"), ("texto", "string"), ("idioma", "Idioma") ],
83              "gritar":              [ ("id", "Personaje"), ("texto", "string"), ("idioma", "Idioma") ],          "gritar":              [ ("id", "Personaje"), ("texto", "string"), ("idioma", "Idioma") ],
84              "actuar":              [ ("id", "Personaje"), ("texto", "string") ],          "actuar":              [ ("id", "Personaje"), ("texto", "string") ],
85              "actuar_individual":   [ ("id", "Personaje"), ("espectador", "Personaje"), ("texto", "string") ],          "actuar_individual":   [ ("id", "Personaje"), ("espectador", "Personaje"), ("texto", "string") ],
86              "actuar_uno_mismo":    [ ("id", "Personaje"), ("texto", "string") ],          "actuar_uno_mismo":    [ ("id", "Personaje"), ("texto", "string") ],
87              "coger":               [ ("id", "Personaje"), ("id_objeto", "string"), ("cantidad", "numero"), ("n_orden", "numero"), ("n_instancia", "numero"), ("sigilo", "si_no") ],          "coger":               [ ("id", "Personaje"), ("id_objeto", "string"), ("cantidad", "numero"), ("n_orden", "numero"), ("n_instancia", "numero"), ("sigilo", "si_no") ],
88              "dejar":               [ ("id", "Personaje"), ("objeto", "Objeto"), ("cantidad", "numero"), ("sigilo", "si_no") ],          "dejar":               [ ("id", "Personaje"), ("objeto", "Objeto"), ("cantidad", "numero"), ("sigilo", "si_no") ],
89              "dar":                 [ ("id", "Personaje"), ("receptor", "Personaje"), ("objeto", "Objeto"), ("cantidad", "numero") ],          "dar":                 [ ("id", "Personaje"), ("receptor", "Personaje"), ("objeto", "Objeto"), ("cantidad", "numero") ],
90              "esconder":            [ ("id", "Personaje"), ("objeto", "Objeto"), ("cantidad", "numero") ],          "esconder":            [ ("id", "Personaje"), ("objeto", "Objeto"), ("cantidad", "numero") ],
91              "ponerse":             [ ("id", "Personaje"), ("objeto", "Objeto"), ("posicion", "string") ],          "ponerse":             [ ("id", "Personaje"), ("objeto", "Objeto"), ("posicion", "string") ],
92              "quitarse":            [ ("id", "Personaje"), ("posicion", "string") ],          "quitarse":            [ ("id", "Personaje"), ("posicion", "string") ],
93              "cambiar_experiencia": [ ("id", "Personaje"), ("puntos", "numero") ],          "cambiar_experiencia": [ ("id", "Personaje"), ("puntos", "numero") ],
94              "cambiar_vida":        [ ("id", "Personaje"), ("puntos", "numero") ],          "cambiar_vida":        [ ("id", "Personaje"), ("puntos", "numero") ],
95              "cambiar_atributo":    [ ("id", "Personaje"), ("atributo", "string"), ("niveles", "numero") ],          "cambiar_atributo":    [ ("id", "Personaje"), ("atributo", "string"), ("niveles", "numero") ],
96              "cambiar_idioma":      [ ("id", "Personaje"), ("idioma", "Idioma"), ("niveles", "numero") ],          "cambiar_idioma":      [ ("id", "Personaje"), ("idioma", "Idioma"), ("niveles", "numero") ],
97              "cambiar_confianza":   [ ("id", "Personaje"), ("interlocutor", "Personaje"), ("niveles", "numero") ],          "cambiar_confianza":   [ ("id", "Personaje"), ("interlocutor", "Personaje"), ("niveles", "numero") ],
98              "cambiar_renombre":    [ ("id", "Personaje"), ("puntos", "numero") ],          "cambiar_renombre":    [ ("id", "Personaje"), ("puntos", "numero") ],
99              "cambiar_infamia":     [ ("id", "Personaje"), ("puntos", "numero") ],          "cambiar_infamia":     [ ("id", "Personaje"), ("puntos", "numero") ],
100              "registrar_hazana":    [ ("id", "Personaje"), ("texto", "string"), ("anonimo", "si_no") ],          "registrar_hazana":    [ ("id", "Personaje"), ("texto", "string"), ("anonimo", "si_no") ],
101              "registrar_delito":    [ ("id", "Personaje"), ("texto", "string"), ("anonimo", "si_no") ],          "registrar_delito":    [ ("id", "Personaje"), ("texto", "string"), ("anonimo", "si_no") ],
102              "alimentar":           [ ("id", "Personaje"), ("puntos_nutritivos", "numero") ],          "alimentar":           [ ("id", "Personaje"), ("puntos_nutritivos", "numero") ],
103              "hidratar":            [ ("id", "Personaje"), ("puntos_hidratantes", "numero") ]          "hidratar":            [ ("id", "Personaje"), ("puntos_hidratantes", "numero") ]
104          },      },
105    
106          "Objeto": {      "Objeto": {
107              "mover":               [ ("id", "Objeto"), ("sala", "Sala") ],          "mover":               [ ("id", "Objeto"), ("sala", "Sala") ],
108              "cambiar_cargas":      [ ("id", "Objeto"), ("cargas", "numero") ],          "cambiar_cargas":      [ ("id", "Objeto"), ("cargas", "numero") ],
109              "cambiar_estado":      [ ("id", "Objeto"), ("puntos", "numero") ],          "cambiar_estado":      [ ("id", "Objeto"), ("puntos", "numero") ],
110              "reemplazar":          [ ("id", "Objeto"), ("id_objeto_nuevo", "string") ],          "reemplazar":          [ ("id", "Objeto"), ("id_objeto_nuevo", "string") ],
111              "actuar":              [ ("id", "Objeto"), ("texto", "string") ],          "actuar":              [ ("id", "Objeto"), ("texto", "string") ],
112              "actuar_individual":   [ ("id", "Objeto"), ("espectador", "Personaje"), ("texto", "string") ],          "actuar_individual":   [ ("id", "Objeto"), ("espectador", "Personaje"), ("texto", "string") ],
113              "destruir":            [ ("id", "Objeto") ]          "destruir":            [ ("id", "Objeto") ]
114          },      },
115    
116          "Sala": {      "Sala": {
117              "ambiente":            [ ("id", "Sala"), ("texto", "string"), ("rango_salas", "numero", 0) ],          "ambiente":            [ ("id", "Sala"), ("texto", "string"), ("rango_salas", "numero", 0) ],
118              "cambiar_aura":        [ ("id", "Sala"), ("puntos", "numero") ],          "cambiar_aura":        [ ("id", "Sala"), ("puntos", "numero") ],
119              "crear_objeto":        [ ("id", "Sala"), ("id_objeto", "string") ],          "crear_objeto":        [ ("id", "Sala"), ("id_objeto", "string") ],
120              "crear_pnj":           [ ("id", "Sala"), ("id_pnj", "string") ]          "crear_pnj":           [ ("id", "Sala"), ("id_pnj", "string") ]
121          },      },
122    
123          "area": {      "area": {
124              "ambiente":            [ ("id", "area"), ("texto", "string"), ("tipo_sala", "string"), ("excepciones", "string") ]          "ambiente":            [ ("id", "area"), ("texto", "string"), ("tipo_sala", "string"), ("excepciones", "string") ]
125          },      },
126    
127          "mundo": {      "mundo": {
128              "ambiente":            [ ("texto", "string"), ("tipo_sala", "string"), ("excepciones", "string") ]          "ambiente":            [ ("texto", "string"), ("tipo_sala", "string"), ("excepciones", "string") ]
129          }      }
130      }      }
131            
132    
# Line 136  class Accion(object): Line 136  class Accion(object):
136      # Métodos estáticos de la clase      # Métodos estáticos de la clase
137    
138      def nueva_xml(elem_accion, macros):      def nueva_xml(elem_accion, macros):
139          """Crea una accion nueva a partir de un nodo XML leido de un fichero de descripción.          """Crea una accion nueva a partir de un nodo XML leido de un fichero de descripción.
140        
141          Parámetros:          Parámetros:
142              elem_accion: el nodo XML              elem_accion: el nodo XML
143              macros ((string, string)[]): lista con los nombres y tipos de los macros permitidos en              macros ((string, string)[]): lista con los nombres y tipos de los macros permitidos en
144                                           el contexto de esta accion.                                           el contexto de esta accion.
145        
146          Ejemplo -> accion dentro del uso "personaje_bebe" del objeto "pocion01"          Ejemplo -> accion dentro del uso "personaje_bebe" del objeto "pocion01"
147        
148            elem_accion: <accion base="Personaje" nombre="cambiar_vida" puntos="+15">            elem_accion: <accion base="Personaje" nombre="cambiar_vida" puntos="+15">
149            macros: [("$usuario", "Personaje"), ("$sala", "Sala"), ("$objeto", "Objeto")]            macros: [("$usuario", "Personaje"), ("$sala", "Sala"), ("$objeto", "Objeto")]
150        
151          Requiere:          Requiere:
152              elem_accion != None              elem_accion != None
153              macros != None              macros != None
154          """          """
155          acc = Accion()          acc = Accion()
156          acc.__parsear_accion(elem_accion, macros)          acc.__parsear_accion(elem_accion, macros)
157          return acc          return acc
158        
159      nueva_xml = staticmethod(nueva_xml)      nueva_xml = staticmethod(nueva_xml)
160        
161        
162      def nueva_datos(base, nombre, parametros):      def nueva_datos(base, nombre, parametros):
163          """Crea una acción nueva aportando directamente sus datos.          """Crea una acción nueva aportando directamente sus datos.
164        
165          Requiere:          Requiere:
166              base != None              base != None
167              nombre != None              nombre != None
168              parametros != None              parametros != None
169              len(parametros) > 0              len(parametros) > 0
170          """          """
171          acc = Accion()          acc = Accion()
172          acc.__base = base          acc.__base = base
173          acc.__nombre = nombre          acc.__nombre = nombre
174          acc.__parametros = parametros          acc.__parametros = parametros
175          return acc          return acc
176    
177      nueva_datos = staticmethod(nueva_datos)      nueva_datos = staticmethod(nueva_datos)
178    
# Line 182  class Accion(object): Line 182  class Accion(object):
182      def __leer_base(self): return self.__base      def __leer_base(self): return self.__base
183    
184      base = property(__leer_base,      base = property(__leer_base,
185                      doc="""(string): el nombre de la clase base de esta acción.              doc="""(string): el nombre de la clase base de esta acción.
186    
187                      Invariantes:              Invariantes:
188                        base != None                base != None
189                      """)              """)
190    
191      def __leer_nombre(self): return self.__nombre      def __leer_nombre(self): return self.__nombre
192    
193      nombre = property(__leer_nombre,      nombre = property(__leer_nombre,
194                      doc="""(string): el nombre de accion (o sea, la operación que se ejecuta).              doc="""(string): el nombre de accion (o sea, la operación que se ejecuta).
195    
196                      Invariantes:              Invariantes:
197                        nombre != None                nombre != None
198                      """)              """)
199    
200    
201      def __leer_parametros(self): return self.__parametros      def __leer_parametros(self): return self.__parametros
202    
203      parametros = property(__leer_parametros,      parametros = property(__leer_parametros,
204                            doc="""({String:any})[]: descripción de los parámetros.                doc="""({String:any})[]: descripción de los parámetros.
205                                            
206                                Consiste en una lista de items, y cada item es un conjunto de                    Consiste en una lista de items, y cada item es un conjunto de
207                                propiedades en forma de diccionario:                    propiedades en forma de diccionario:
208                                 - "nombre" (string): nombre del parámetro.                     - "nombre" (string): nombre del parámetro.
209                                 - "valor" (any): puede ser un literal con el valor del parámetro,                     - "valor" (any): puede ser un literal con el valor del parámetro,
210                                                  un dato que permita obtener el valor cuando se                                      un dato que permita obtener el valor cuando se
211                                                  active la accion (por ejemplo, el id de una sala)                          active la accion (por ejemplo, el id de una sala)
212                                                  o un macro (si comienza por $).                          o un macro (si comienza por $).
213                                 - "tipo" (string): indica de que tipo es el parámetro, y determina                     - "tipo" (string): indica de que tipo es el parámetro, y determina
214                                                    cómo se va a calcular el valor.                                        cómo se va a calcular el valor.
215    
216                                Invariantes:                    Invariantes:
217                                    nombre != None                    nombre != None
218                                    valor != None                    valor != None
219                                    tipo in Accion.TIPOS_PARAMETROS                    tipo in Accion.TIPOS_PARAMETROS
220                                """)                    """)
221    
222      # Métodos privados      # Métodos privados
223    
224      def __parsear_accion(self, elem_accion, macros):      def __parsear_accion(self, elem_accion, macros):
225          """Extrae la información del elemento accion:          """Extrae la información del elemento accion:
226              - base              - base
227              - nombre              - nombre
228              - parametros              - parametros
229        
230          Requiere:          Requiere:
231              elem_accion != None              elem_accion != None
232              macros != None              macros != None
233          """          """
234          self.__nombre = extraer_atributo_xml(elem_accion, 'nombre')          self.__nombre = extraer_atributo_xml(elem_accion, 'nombre')
235        
236          if self.__nombre == "aceptar" or self.__nombre == "cancelar":          if self.__nombre == "aceptar" or self.__nombre == "cancelar":
237                self.__base = ""
238              self.__base = ""              self.__parametros = []
239              self.__parametros = []          else:
240                # Obtenemos la información del nombre de accion (es decir, la lista
241          else:              # de parámetros y sus tipos correspondientes).
242                self.__base = extraer_atributo_xml(elem_accion, 'base')
243              # Obtenemos la información del nombre de accion (es decir, la lista              try:
244              # de parámetros y sus tipos correspondientes).                  info_nombre = Accion.NOMBRES[self.__base][self.__nombre]
245              self.__base = extraer_atributo_xml(elem_accion, 'base')              except KeyError:
246              try:                  raise ValueError("No existe la accion %s.%s" % (self.__base, self.__nombre))
247                  info_nombre = Accion.NOMBRES[self.__base][self.__nombre]              
248              except KeyError:              # Obtenemos la lista de parámetros, sus valores y tipos.
249                  raise ValueError("No existe la accion %s.%s" % (self.__base, self.__nombre))              self.__parametros = []
250                            
251              # Obtenemos la lista de parámetros, sus valores y tipos.              for info_parametro in info_nombre:
252              self.__parametros = []                  nombre = info_parametro[0]
253                    tipo = info_parametro[1]
254              for info_parametro in info_nombre:                  valor = None
255                    
256                  nombre = info_parametro[0]                  if elem_accion.hasAttribute(nombre):
257                  tipo = info_parametro[1]                      # Si el atributo está presente en la definición XML, extraer el valor.
258                  valor = None                      valor = extraer_atributo_xml(elem_accion, nombre)
259                        valor = " ".join(valor.split())
260                  if elem_accion.hasAttribute(nombre):                  else:
261                      # Si el atributo está presente en la definición XML, extraer el valor.                      # Si no, inventarse un valor a partir del primer macro que tenga
262                      valor = extraer_atributo_xml(elem_accion, nombre)                      # un tipo compatible.
263                      valor = " ".join(valor.split())                      for macro in macros:
264                  else:                          if macro[1] == tipo:
265                      # Si no, inventarse un valor a partir del primer macro que tenga                              valor = macro[0]
266                      # un tipo compatible.                              break
267                      for macro in macros:                  
268                          if macro[1] == tipo:                  if valor == None:
269                              valor = macro[0]                      # Si no hay ningún valor, ver si el parámetro tiene valor por defecto.
270                              break                      if len(info_parametro) > 2:
271                            valor = info_parametro[2]
272                  if valor == None:                      else:
273                      # Si no hay ningún valor, ver si el parámetro tiene valor por defecto.                          raise ValueError("No se encuentra un valor para el parámetro %s de la accion %s.%s." %
274                      if len(info_parametro) > 2:                               (nombre, self.__base, self.__nombre))
275                          valor = info_parametro[2]                  
276                      else:                  self.__parametros.append({"nombre": nombre,
277                          raise ValueError("No se encuentra un valor para el parámetro %s de la accion %s.%s." %                                "valor": valor,
278                                           (nombre, self.__base, self.__nombre))                                "tipo": tipo})
   
                 self.__parametros.append({"nombre": nombre,  
                                           "valor": valor,  
                                           "tipo": tipo})  
279    
280    
281      # Métodos normales      # Métodos normales
282    
283      def ejecutar(self, macros):      def leer_parametro(self, nombre, default=None):
284          """Realiza la ejecución de la accion (es decir, que la accion ocurre).          """Extrae el valor de un parametro a partir de su nombre"""
285            resultados = [parametro["valor"] \
286          Aquí se calculan los valores reales de la ejecución. Los valores pueden incluir                          for parametro in self.__parametros \
287          macros, que se resuelven con el parámetro "macros" de esta función. Dicho                          if parametro["nombre"] == nombre]
288          parámetro es un diccionario con pares "$nombre_macro": valor.          if resultados:
289                return resultados[0]
290          Ejemplo -> Hirunatan se bebe la pocion en la posada          else:
291                        return default
            macros: {"$usuario": <instancia Hirunatan>,  
                     "$sala": <instancia posada01>)  
                     "$objeto": <instancia pocion01>}  
   
         Invariantes:  
             macros != None  
         """  
         if self.__nombre == "aceptar" or self.__nombre == "cancelar":  
   
             pass  
   
         else:  
               
             # Resolver los parámetros, y colocarlos en un diccionario {nombre: valor}.  
             # El parámetro llamado "id" no es en realidad un parámetro, sino el objeto  
             # base sobre el cual se aplicará la operación.  
             parametros_resueltos = {}  
             objeto_base = None  
             for parametro in self.__parametros:  
   
                 t = parametro["tipo"]  
                 v = parametro["valor"]  
   
                 if t == "numero":  
                     if v and v[0] == "$":  
                         valor_str = macros[v]  
                     else:  
                         valor_str = v  
   
                     if valor_str == "*" or valor_str == "+*":  
                         valor = sys.maxint  
                     elif valor_str == "-*":  
                         valor = -sys.maxint  
                     else:  
                         valor = float(valor_str)  
   
                 elif t == "string":  
                     if v and v[0] == "$":  
                         valor = macros[v]  
                     else:  
                         valor = v  
   
                 elif t == "si_no":  
                     if v and v[0] == "$":  
                         valor_str = macros[v].lower()  
                     else:  
                         valor_str = v.lower()  
                     if valor_str == 's' or valor_str == 'si' or valor_str == 'sí' \  
                        or valor_str == '1':  
                         valor = 1  
                     else:  
                         valor = 0  
                       
                 elif t == "Personaje":  
                     if v and v[0] == "$":  
                         valor = macros[v]  
                     else:  
                         sala = macros["$sala"]  
                         valor = sala.personajes[v]  
                       
                 elif t == "Sala":  
                     if v and v[0] == "$":  
                         valor = macros[v]  
                     else:  
                         valor = Mundo.localizar_sala(v)  
                       
                 elif t == "Objeto":  
                     if v and v[0] == "$":  
                         valor = macros[v]  
                     else:  
                         valor = None # %% La verdad, no sé qué hacer aquí :-?  
                       
                 elif t == "Idioma":  
                     if v and v[0] == "$":  
                         valor = macros[v]  
                     else:  
                         valor = Idioma_buscar(v)  
   
                 else:  
                     raise ValueError("Encontrado parametro %s con tipo desconocido: %s" %  
                                      (parametro["nombre"], t))  
   
                 if parametro["nombre"] == "id":  
                     objeto_base = valor  
                 else:  
                     parametros_resueltos[parametro["nombre"]] = valor  
292    
293              # Obtener la función sobre el objeto base, y llamarla.      def ejecutar(self, macros):
294            """Realiza la ejecución de la accion (es decir, que la accion ocurre).
295        
296            Aquí se calculan los valores reales de la ejecución. Los valores pueden incluir
297            macros, que se resuelven con el parámetro "macros" de esta función. Dicho
298            parámetro es un diccionario con pares "$nombre_macro": valor.
299                
300                Al concluir la acción, se llama al callback con prototipo finalizar(accion=self, cancelado=booleano).
301        
302            Ejemplo -> Hirunatan se bebe la pocion en la posada
303            
304               macros: {"$usuario": <instancia Hirunatan>,
305                        "$sala": <instancia posada01>)
306                    "$objeto": <instancia pocion01>}
307        
308            Invariantes:
309                macros != None
310            """
311            if self.__nombre == "aceptar" or self.__nombre == "cancelar":
312                    return self.__nombre == "aceptar"
313                    
314            else:
315                
316                # Resolver los parámetros, y colocarlos en un diccionario {nombre: valor}.
317                # El parámetro llamado "id" no es en realidad un parámetro, sino el objeto
318                # base sobre el cual se aplicará la operación.
319                parametros_resueltos = {}
320                objeto_base = None
321                for parametro in self.__parametros:
322                
323                    t = parametro["tipo"]
324                    v = parametro["valor"]
325                    
326                    if t == "numero":
327                        if v and v[0] == "$":
328                            valor_str = macros[v]
329                        else:
330                            valor_str = v
331                    
332                        if valor_str == "*" or valor_str == "+*":
333                            valor = sys.maxint
334                        elif valor_str == "-*":
335                            valor = -sys.maxint
336                        else:
337                            valor = float(valor_str)
338                    
339                    elif t == "string":
340                        if v and v[0] == "$":
341                            valor = macros[v]
342                        else:
343                            valor = v
344                    
345                    elif t == "si_no":
346                        if v and v[0] == "$":
347                            valor_str = macros[v].lower()
348                        else:
349                            valor_str = v.lower()
350                        if valor_str == 's' or valor_str == 'si' or valor_str == 'sí' \
351                           or valor_str == '1':
352                            valor = 1
353                        else:
354                            valor = 0
355                        
356                    elif t == "Personaje":
357                        if v and v[0] == "$":
358                            valor = macros[v]
359                        else:
360                            sala = macros["$sala"]
361                            valor = sala.personajes[v]
362                        
363                    elif t == "Sala":
364                        if v and v[0] == "$":
365                            valor = macros[v]
366                        else:
367                            from mundo import Mundo
368                            valor = Mundo.localizar_sala(v)
369                        
370                    elif t == "Objeto":
371                        if v and v[0] == "$":
372                            valor = macros[v]
373                        else:
374                            valor = None # %% La verdad, no sé qué hacer aquí :-?
375                        
376                    elif t == "Idioma":
377                        if v and v[0] == "$":
378                            valor = macros[v]
379                        else:
380                            valor = Idioma_buscar(v)
381                    
382                    else:
383                        raise ValueError("Encontrado parametro %s con tipo desconocido: %s" %
384                                         (parametro["nombre"], t))
385                    
386                    if parametro["nombre"] == "id":
387                        objeto_base = valor
388                    else:
389                        parametros_resueltos[parametro["nombre"]] = valor
390        
391                # Obtener la función sobre el objeto base, y llamarla.
392              escribir("Ejecutando accion: " + repr(self.nombre) + " sobre el objeto: " + repr(objeto_base) )              escribir("Ejecutando accion: " + repr(self.nombre) + " sobre el objeto: " + repr(objeto_base) )
393              funcion = getattr(objeto_base, self.nombre, None)              funcion = getattr(objeto_base, self.nombre, None)
394              if funcion != None:              if funcion != None:
395                  apply(funcion, (), parametros_resueltos)                  apply(funcion, (), parametros_resueltos)
396                        
397                return 1
398        
399    
400  # Código para pruebas unitarias del módulo.  # Código para pruebas unitarias del módulo.
401    

Legend:
Removed from v.2.5  
changed lines
  Added in v.2.6

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26