/*--------------------------------------------------------------------
 * FICHERO:  FchLisNo.c
 * OBJETIVO: Definir la funcin Fch_ListaNombre()
 * AUTOR:    Pedro Reina
 * FECHA:    V.14.7.1995
 *------------------------------------------------------------------*/

/*--------------------------------------------------------------------
 * Funciones privadas QL
 *
 *   Fch_FinalCoincidencia()
 *------------------------------------------------------------------*/

/*--------------------------------------------------------------------
 * Ficheros de cabecera
 *------------------------------------------------------------------*/

#include "Fichero.h"

#ifdef OLIMPO_PC
#include <dir.h>                /* findfirst()  findnext()          */
#endif

#ifdef OLIMPO_QL
#include <qlib.h>    /* qdir_read()  qdir_delete()  isdevice()  getcwd()  */
#endif

/*--------------------------------------------------------------------
 * Declaracin de funciones
 *------------------------------------------------------------------*/

#ifdef OLIMPO_QL
static contador Fch_FinalCoincidencia();
#endif

/*--------------------------------------------------------------------
 * Definicin de funciones
 *------------------------------------------------------------------*/

/*--------------------------------------------------------------Olimpo
 * FUNCION:  Fch_ListaNombre()
 * OBJETIVO: Dada una mscara, dar una lista con los nombres
 *           que encajen con esa mscara
 * ENTRADAS: Una mscara para los ficheros
 * SALIDAS:  Una lista con los nombres o NIL si no se 
 *           encuentra ninguno
 * NOTAS:    1. La lista devuelta hay que destruirla cuando no
 *              sea necesaria
 *           2. Se pueden utilizar dos comodines: * y ?
 * EJEMPLO:  Fch_ListaNombre ("*.txt")
 *------------------------------------------------------------------*/

#ifdef OLIMPO_PC
lista Fch_ListaNombre (Mascara)
cadena Mascara;
  {
  lista  Respuesta = NIL;
  cadena Nombre;
  struct ffblk BloqueDir;

  Fch_Inicia();

  if ( findfirst(Mascara,&BloqueDir,0) == 0 )
    {
    Respuesta = Lis_Crea();
    Nombre = Cad_Crea(12);
    Cad_Copia (Nombre,BloqueDir.ff_name);
    Lis_PonContenido (Respuesta,Nombre);

    while ( findnext (&BloqueDir) == 0 )
      {
      Nombre = Cad_Crea(12);
      Cad_Copia (Nombre,BloqueDir.ff_name);
      Respuesta = Lis_AgregaFin (Respuesta,Nombre);
      }
    }

  return ( Respuesta );
  }
#endif

#ifdef OLIMPO_QL
lista Fch_ListaNombre (Mascara)
cadena Mascara;
  {
  lista    Respuesta = NIL;
  cadena   Nombre;
  logico   Primero = SI;
  contador Comienzo, Final;
  struct DIR_LIST * InfoDir, * Nodo;

  if ( InfoDir = qdir_read (Mascara,"",3) )
    {
    Respuesta = Lis_Crea();
    Comienzo = Fch_FinalCoincidencia (Mascara,InfoDir->dl_dir.d_name);

    Nodo = InfoDir;
    while ( Nodo )
      {
      Final = Cad_Longitud (Nodo->dl_dir.d_name);
      Nombre = Cad_Trozo (Nodo->dl_dir.d_name,Comienzo,Final);
      if ( Primero )
        {
        Lis_PonContenido (Respuesta,Nombre);
        Primero = NO;
        }
      else
        { Respuesta = Lis_AgregaFin (Respuesta,Nombre); }
      Nodo = Nodo->dl_next;
      }

    qdir_delete (InfoDir);
    }
  return ( Respuesta );
  }
#endif

#ifdef OLIMPO_QL
/*--------------------------------------------------------------------
 * FUNCION:  Fch_FinalCoincidencia()
 * OBJETIVO: Decir cul es el nmero del carcter en que finaliza la
 *           coincidencia entre una mscara y el nombre de un fichero
 * ENTRADAS: Una mscara y el nombre de un fichero
 * SALIDAS:  El nmero de carcter en que ya no hay coincidencia, siendo
 *           el carcter anterior el separador de subdirectorios ('_')
 * NOTA:     Los caracteres se empiezan a contar en 1
 * EJEMPLO:  Fch_FinalCoincidencia ("*_txt","Trabajo_Prueba_txt")
 * ALGORITMO:
 *      Si la Mscara no comienza con el nombre de una unidad fsica
 *        anteponer a Mscara el directorio de datos por defecto
 *      Quitar a Mscara la unidad fsica, quitando hasta el primer separador
 *               (caso normal) o 2 (si la unidad est en un QL remoto)
 *      Devolver el primer carcter que est detrs de un separador y no sea
 *               igual en la mscara que en el nombre
 *------------------------------------------------------------------*/
static contador Fch_FinalCoincidencia (Mascara,Nombre)
cadena Mascara, Nombre;
  {
  char     Unidad[37];
  int      Extra;
  cadena   MascaraReal, MascaraRecortada;
  contador NumSep, Respuesta, i;

  if ( ! isdevice (Mascara,&Extra) )
    {
    getcwd (Unidad,0);
    MascaraReal = Cad_Une (Unidad,Mascara,CAD_FIN);
    }
  else
    { MascaraReal = Cad_Duplica (Mascara); }

  isdevice (MascaraReal,&Extra);
  NumSep = 1 + ( Extra & NETDEV > 0 );

  for ( i=0 , MascaraRecortada=MascaraReal ; i<NumSep ; MascaraRecortada++ )
    { if ( *MascaraRecortada == '_' ) { i++; } }
  Cad_Destruye (MascaraReal);

  for ( Respuesta=0 , i=0 ; 
        Car_Mayus(*(MascaraRecortada++)) == Car_Mayus(*(Nombre++)) ; 
        i++ )
    { if ( *MascaraRecortada == '_' ) { Respuesta = i; } }

  return ( Respuesta ? Respuesta + 3 :  1 );
  }
#endif
