home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Amiga 14 / MA_Cover_14.iso / source / c / pegase_src / pegase.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1999-08-14  |  18.7 KB  |  597 lines

  1.                           /**************************************************/
  2.                           /*                                                */
  3.                           /*                   Pegase.cpp                   */
  4.                           /*                                                */
  5.                           /**************************************************/
  6.  
  7. /*
  8. ** $Revision: 1.3 $
  9. ** $State: Exp $
  10. ** $Date: 1998/08/16 19:03:34 $
  11. **
  12. ** $Log: Pegase.cpp $
  13. ** Revision 1.3  1998/08/16 19:03:34  kakace
  14. ** Version Beta3+
  15. **
  16. */
  17.  
  18.  
  19. //----------------------------------------------------------------------------------------------------
  20.  
  21. /// Includes
  22.  
  23. #ifndef  _PEGASECOND_HPP
  24. #include "PegaseCond.hpp"
  25. #endif
  26.  
  27. #ifndef  _FILEINFOS_CLASS_HPP
  28. #include "FileInfosC.hpp"
  29. #endif
  30.  
  31. #ifndef  _PEGASE_HPP
  32. #include "Pegase.hpp"
  33. #endif
  34.  
  35. #ifndef  CLASS_DISPLAY_HPP
  36. #include "Display.hpp"
  37. #endif
  38.  
  39. #ifndef  _COMMON_HPP
  40. #include "Common.hpp"
  41. #endif
  42.  
  43. #ifndef  _ARGSCONTROL_CLASS_HPP
  44. #include "ArgsControlClass.hpp"
  45. #endif
  46.  
  47. ///
  48.  
  49. #define CATCOMP_NUMBERS
  50. #ifndef  PEGASE_H
  51. #include "Pegase.h"
  52. #endif
  53.  
  54.  
  55. //----------------------------------------------------------------------------------------------------
  56.  
  57. extern const char *_verstr_;
  58.  
  59. PegaseConfigC GlobalConfig;         // Paramètres par défaut de l'encodeur.
  60. Display *display;
  61.  
  62.  
  63. // Resource tracking.
  64. //  Initialise le pointeur "display" avant d'appeler main() ou wbmain() et libère les ressources
  65. //  associées en fin de programme.
  66.  
  67. static struct DispResource {
  68.     DispResource() { ::display = NULL; }
  69.     ~DispResource() { delete ::display; }
  70. } dispResource;
  71.  
  72.  
  73. //----------------------------------------------------------------------------------------------------
  74. //============================================ Arguments =============================================
  75. //----------------------------------------------------------------------------------------------------
  76.  
  77. // Parameters storage
  78.  
  79. CPegaseArgs goPegaseArgs = {};
  80.  
  81.  
  82. /// CArgsControl goPegaseArgsControl[]
  83.  
  84. #define GET_OFFSET(a)   (offsetof(CPegaseArgs, a) / sizeof(LONG))
  85.  
  86.  
  87. // Parameters definition
  88.  
  89. const LONG default_layer     =     2;
  90. const LONG default_frequency = 44100;
  91. const LONG default_bitrate   =   160;
  92. const LONG default_priority  =     0;
  93. const LONG default_FRXPos    =    20;
  94. const LONG default_FRYPos    =    20;
  95. const LONG default_FRWidth   =   300;
  96. const LONG default_FRHeight  =   220;
  97.  
  98. const CArgsControl goPegaseArgsControl[] = {
  99.     {"FROM",      "/M",      GET_OFFSET(pa_From),      ARG_STRING_ARRAY, ARGF_CLI, 0, 0, 0 },
  100.     {"TO",        "/K",      GET_OFFSET(pa_To),        ARG_STRING,       ARGF_CLI | ARGF_WB, 0, 0, 0},
  101.     {"LAYER",     "/K/N",    GET_OFFSET(pa_Layer),     ARG_NUMBER,       ARGF_CLI_WB_DEF_CHECK, (LONG) &default_layer, 1, 2},
  102.     {"FREQ",      "/K/N",    GET_OFFSET(pa_Frequency), ARG_NUMBER,       ARGF_CLI_WB_DEF_CHECK, (LONG) &default_frequency, 30769, 49920},
  103.     {"BITRATE",   "=BR/K/N", GET_OFFSET(pa_Bitrate),   ARG_NUMBER,       ARGF_CLI_WB_DEF_CHECK, (LONG) &default_bitrate, 32, 448},
  104.     {"MONO",      "/S",      GET_OFFSET(pa_Mono),      ARG_BOOL,         ARGF_CLI_WB_DEF, 0, 0, 0},
  105.     {"JSTEREO",   "/S",      GET_OFFSET(pa_JStereo),   ARG_BOOL,         ARGF_CLI_WB_DEF, 0, 0, 0},
  106.     {"COPYRIGHT", "/S",      GET_OFFSET(pa_Copyright), ARG_BOOL,         ARGF_CLI_WB_DEF, 0, 0, 0},
  107.     {"ORIGINAL",  "/S",      GET_OFFSET(pa_Original),  ARG_BOOL,         ARGF_CLI_WB_DEF, 0, 0, 0},
  108.     {"CRC",       "/S",      GET_OFFSET(pa_CRC),       ARG_BOOL,         ARGF_CLI_WB_DEF, 0, 0, 0},
  109.     {"PRIORITY",  "/K/N",    GET_OFFSET(pa_Priority),  ARG_NUMBER,       ARGF_CLI_WB_DEF_CHECK, (LONG) &default_priority, -128, 5},
  110.     {"VERBOSE",   "/S",      GET_OFFSET(pa_Verbose),   ARG_BOOL,         ARGF_CLI_WB_DEF, 0, 0, 0},
  111.     {"INTEL",     "/S",      GET_OFFSET(pa_UseIntFmt), ARG_BOOL,         ARGF_CLI, 0, 0, 0},
  112.     {"MOTOROLA",  "/S",      GET_OFFSET(pa_UseMotFmt), ARG_BOOL,         ARGF_CLI, 0, 0, 0},
  113.     {"PATTERN",   NULL,      GET_OFFSET(pa_Pattern),   ARG_STRING,       ARGF_WB_DEF, (LONG) "~(#?.info)", 0, 0},
  114.  
  115.     {"FR_SOURCE", NULL,      GET_OFFSET(pa_DefSource), ARG_STRING,       ARGF_WB, 0, 0, 0},
  116.     {"FR_XPOS",   NULL,      GET_OFFSET(pa_FR_XPos),   ARG_NUMBER,       ARGF_WB_DEF, (LONG) &default_FRXPos, 0, 0},
  117.     {"FR_YPOS",   NULL,      GET_OFFSET(pa_FR_YPos),   ARG_NUMBER,       ARGF_WB_DEF, (LONG) &default_FRYPos, 0, 0},
  118.     {"FR_WIDTH",  NULL,      GET_OFFSET(pa_FR_Width),  ARG_NUMBER,       ARGF_WB_DEF, (LONG) &default_FRWidth, 0, 0},
  119.     {"FR_HEIGHT", NULL,      GET_OFFSET(pa_FR_Height), ARG_NUMBER,       ARGF_WB_DEF, (LONG) &default_FRHeight, 0, 0},
  120.     {NULL}
  121. };
  122.  
  123.  
  124. //----------------------------------------------------------------------------------------------------
  125. //======================================== Prototypes privés =========================================
  126. //----------------------------------------------------------------------------------------------------
  127.  
  128. e_FileListErrors CollectFiles();
  129. void    ShowEncodingInfos(const EncoderConfigC &roConfig);
  130. void    EncodeFiles();
  131. void    InitConfig();
  132. int     ShellEncoder();
  133. void    ShowStartupError(CStartup::Errors errorCode);
  134.  
  135.  
  136. //----------------------------------------------------------------------------------------------------
  137. //===================================== Modules d'initialisation =====================================
  138. //----------------------------------------------------------------------------------------------------
  139.  
  140. /// CheckCPUModel()
  141. /****** CheckCPUModel/ ******************************************************
  142. *
  143. *   NAME
  144. *   CheckCPUModel -- Contrôler le type de CPU et la version de l'OS
  145. *
  146. *   SYNOPSIS
  147. *   CheckCPUModel()
  148. *
  149. *   void CheckCPUModel();
  150. *
  151. *   FUNCTION
  152. *   Contrôle que le CPU utilisé est compatible avec la version du programme,
  153. *   et vérifie que la version de l'OS est suffisante.
  154. *   Dans le cas contraire, une erreur est affichée, et le programme est
  155. *   avorté.
  156. *
  157. *   NOTES
  158. *   Le niveau de cette fonction INIT assure que le fichier ".catalog" est
  159. *   déjà chargé. De fait, le message d'erreur peut être localisé.
  160. *
  161. *****************************************************************************
  162. *
  163. */
  164.  
  165. #ifndef  EXEC_EXECBASE_H
  166. #include <exec/execbase.h>
  167. #endif
  168.  
  169. void CheckCPUModel()
  170. {
  171. #ifndef __PPC__
  172.  
  173.     extern struct ExecBase *SysBase;
  174.  
  175. #if   _CPUMODEL_ == 68020
  176.     const UWORD CPUMASK = AFF_68020;                        // = 68020/68030 sans FPU
  177. #elif _CPUMODEL_ == 68030
  178.     const UWORD CPUMASK = AFF_68020|AFF_68881;              // = 68020/68030 + 68881/68882
  179. #elif _CPUMODEL_ == 68040
  180.     const UWORD CPUMASK = AFF_68040|AFF_FPU40|AFF_68881;    // = 68040+FPU
  181. #elif _CPUMODEL_ == 68060
  182.     const UWORD CPUMASK = 0x80|AFF_FPU40|AFF_68881;         // = 68060+FPU
  183. #endif
  184.  
  185.  
  186.     if (SysBase->LibNode.lib_Version < 37)
  187.     {
  188.         exit(20);        // Version OS incorrecte.
  189.     }
  190.  
  191.     if ((SysBase->AttnFlags & CPUMASK) != CPUMASK)
  192.     {
  193.         EasyStruct sBadCPU = {sizeof(EasyStruct), 0, };
  194.  
  195.         sBadCPU.es_Title        = (char *) GetString(MSG_FATALERROR_TXT);
  196.         sBadCPU.es_TextFormat   = (char *) GetString(MSG_BADCPU_TXT);
  197.         sBadCPU.es_GadgetFormat = (char *) GetString(MSG_QUIT_GADGET);
  198.  
  199.         // Afficher un requester d'erreur si la version du programme ne correspond pas
  200.         // avec le modèle de CPU utilisé.
  201.  
  202.         IntuitionLib::EasyRequestArgs(NULL, &sBadCPU, NULL, NULL);
  203.  
  204.         exit(20);
  205.     }
  206.  
  207. #endif  // __PPC__
  208. }
  209. ///
  210.  
  211.  
  212. //----------------------------------------------------------------------------------------------------
  213. //====================================== Fonctions de démarrage ======================================
  214. //----------------------------------------------------------------------------------------------------
  215.  
  216.  
  217. /// main()
  218. //----------------------------------------------------------------------------------------------------
  219. // NOTE : L'ordre logique des choses, en ce qui concerne les paramètres de l'encodeur, est
  220. //        le suivant :
  221. //     · CLI : - Initialisation de PegaseConfigC avec les valeurs par défaut.
  222. //             - Lecture des ToolTypes => Initialisation de s_Def_params.
  223. //             - Analyse de la ligne de commande => Modification de s_Def_params.
  224. //             - Mise à jour de PegaseConfigC en fonction des choix de l'utilisateur.
  225. //     · WB :  - Initialisation de PegaseConfigC avec les valeurs par défaut.
  226. //             - Lecture des ToolTypes => Initialisation de s_Def_params.
  227. //             - Mise à jour de PegaseConfigC en fonction des données définies par les
  228. //               ToolTypes.
  229. //
  230. //   Si l'option NOGUI est spécifiée, la configuration de l'encodeur est
  231. //   affichée à l'écran. De même, si aucune source n'est mentionnée, un
  232. //   requester de fichier est ouvert de façon à laisser une dernière chance à
  233. //   l'utilisateur pour choisir les fichiers à encoder.
  234.  
  235.  
  236. void main()
  237. {
  238.     CStartup *startup;
  239.     int return_code = RETURN_FAIL;
  240.  
  241.     CheckCPUModel();
  242.     display = new CLIDisplay;
  243.     startup = new CStartup(goPegaseArgsControl, (LONG *) &goPegaseArgs, GetString(MSG_EXTENDED_HELP));
  244.  
  245.     if (startup != NULL)
  246.     {
  247.         CStartup::Errors startup_error;
  248.  
  249.         if ( (startup_error = startup->ParseArgs()) == CStartup::NO_ERROR)
  250.         {
  251.             InitConfig();
  252.             return_code = ShellEncoder();
  253.         }
  254.         else
  255.         {
  256.             ShowStartupError(startup_error);
  257.         }
  258.         delete startup;
  259.     }
  260.     else
  261.     {
  262.         display->PrintDOSError(ERROR_NO_FREE_STORE);
  263.     }
  264.  
  265.     exit(return_code);
  266. }
  267. ///
  268.  
  269.  
  270. void wbmain(WBStartup *wbStartup)
  271. {
  272.     CStartup *startup;
  273.  
  274.     CheckCPUModel();
  275.     display = new WBDisplay;
  276.     startup = new CStartup(goPegaseArgsControl, (LONG *) &goPegaseArgs);
  277.  
  278.     // Get default settings from the ToolTypes.
  279.  
  280.     if (startup != NULL)
  281.     {
  282.         CStartup::Errors startup_error;
  283.  
  284.         if ( (startup_error = startup->ParseToolTypes(wbStartup->sm_ArgList->wa_Name)) == CStartup::NO_ERROR)
  285.         {
  286.             InitConfig();
  287.             ShellEncoder();
  288.         }
  289.         else
  290.         {
  291.             ShowStartupError(startup_error);
  292.         }
  293.         delete startup;
  294.     }
  295.     else
  296.     {
  297.         display->PrintDOSError(ERROR_NO_FREE_STORE);
  298.     }
  299. }
  300.  
  301.  
  302. void ShowStartupError(CStartup::Errors errorCode)
  303. {
  304.     switch (errorCode)
  305.     {
  306.         case CStartup::NO_MEMORY:
  307.             display->PrintDOSError(ERROR_NO_FREE_STORE);
  308.             break;
  309.  
  310.         case CStartup::READARGS_ERROR:
  311.             display->PrintDOSError(DOSLib::IoErr());
  312.             break;
  313.  
  314.         case CStartup::BAD_ARGUMENT:
  315.             display->PrintErrorMsg("Illegal argument");
  316.             break;
  317.  
  318.         default:
  319.             break;
  320.     }
  321. }
  322.  
  323.  
  324. /// ShellEncoder()
  325. //----------------------------------------------------------------------------------------------------
  326. //========================================== ShellEncoder() ==========================================
  327. //----------------------------------------------------------------------------------------------------
  328.  
  329. int ShellEncoder()
  330. {
  331.     // Pas de fichier source : ouvrir un requester.
  332.  
  333.     if (GlobalConfig.CurrentIndex() == 0)
  334.     {
  335.         RequestFileList();
  336.  
  337.         // Avorter si aucun fichier n'est sélectionné (on ne peut rien faire d'autre si
  338.         // l'utilisateur a volontairement désactivé l'interface...)
  339.  
  340.         if (GlobalConfig.CurrentIndex() == 0)
  341.         {
  342.             display->PrintDOSError(ERROR_REQUIRED_ARG_MISSING);
  343.             return RETURN_FAIL;
  344.         }
  345.     }
  346.  
  347.     // Collationer toute la liste des fichiers audio.
  348.  
  349.     if (CollectFiles() != NO_ERROR || GlobalConfig.CurrentIndex() == 0)
  350.     {
  351.         display->PrintDOSError(ERROR_OBJECT_NOT_FOUND);
  352.         return RETURN_FAIL;
  353.     }
  354.  
  355.     // Traiter les fichiers audio indiqués (mode SHELL).
  356.  
  357.     display->DisplayBanner();                               // Afficher le Copyright.
  358.     display->ShowConfig(GlobalConfig);                      // Afficher les réglages retenus par l'encodeur.
  359.  
  360.     // Encoder tous les fichiers audio trouvés.
  361.  
  362.     FileInfosC *poFileInfos;
  363.  
  364.     for(poFileInfos = (FileInfosC *) GlobalConfig.First(); poFileInfos; poFileInfos = (FileInfosC *) poFileInfos->Next())
  365.     {
  366.         poFileInfos->DefineOutputName();
  367.         display->ShowCurrentJob(poFileInfos);
  368.         display->ShowEncodingInfos(poFileInfos);
  369.  
  370.         if (EncodeFile(*poFileInfos) == FALSE) break;       // Arrêt global (mode batch)
  371.     }
  372.  
  373.     // Restaurer la priorité du Shell.
  374.  
  375.     GlobalConfig.ChangePriority();
  376.  
  377.     return RETURN_OK;
  378. }
  379. ///
  380. /// CollectFiles()
  381. //----------------------------------------------------------------------------------------------------
  382. //========================================== CollectFiles() ==========================================
  383. //----------------------------------------------------------------------------------------------------
  384. /****** Class CollectFiles/ *************************************************
  385. *
  386. *   NAME
  387. *   CollectFiles -- Collationner la liste des fichiers à encoder.
  388. *
  389. *   SYNOPSIS
  390. *   Erreur = CollectFiles()
  391. *
  392. *   e_FileListErrors CollectFiles();
  393. *
  394. *   FUNCTION
  395. *   Recherche tous les fichiers audio à encoder en partant des informations
  396. *   fournies par l'utilisateur. Chaque fichier trouvé est examiné afin de
  397. *   déterminer son type, ainsi que les données qui le caractérisent.
  398. *
  399. *   RESULT
  400. *   Erreur - Code d'erreur.
  401. *
  402. *   NOTES
  403. *   La fonction avorte immédiatement si un manque de mémoire est détecté.
  404. *
  405. *****************************************************************************
  406. *
  407. */
  408.  
  409.  
  410. e_FileListErrors CollectFiles()
  411. {
  412.     ULONG iFileIndex = 0;
  413.     e_FileListErrors iListError = NO_ERROR;
  414.  
  415.     // Ajuster la destination en fonction des conditions.
  416.  
  417.     if (GlobalConfig.CurrentIndex() > 1 && GlobalConfig.GetTargetType() == TARGET_FILE)
  418.     {
  419.         GlobalConfig.SetDestination(NULL);
  420.         GlobalConfig.SetTargetType(TARGET_EMPTY);
  421.     }
  422.  
  423.     // Obtenir la liste de tous les fichiers à encoder. La boucle se charge de faire examiner chacune
  424.     // des sources indiquée sur la ligne de commande (ou via le requester de fichier), que ces sources
  425.     // soient des fichiers ou des répertoires.
  426.  
  427.     for (iFileIndex = 0; iFileIndex < GlobalConfig.CurrentIndex(); iFileIndex++)
  428.     {
  429.         if ( (iListError = ReadFileList(GlobalConfig, iFileIndex) ) != NO_ERROR)
  430.         {
  431.             // Avorter en cas d'erreur.
  432.  
  433.             return iListError;
  434.         }
  435.     }
  436.     return NO_ERROR;
  437. }
  438. ///
  439.  
  440. void InitConfig()
  441. {
  442.     // Modifier la priorité de fonctionnement si nécessaire.
  443.  
  444.     if (*goPegaseArgs.pa_Priority) GlobalConfig.ChangePriority(*goPegaseArgs.pa_Priority);
  445.  
  446.     // Type de Layer à utiliser pour l'encodage.
  447.  
  448.     GlobalConfig.SetLayer(*goPegaseArgs.pa_Layer);
  449.  
  450.     // Mode de fonctionnement de l'encodeur (mode stéréo si aucun de ces arguments n'est indiqué).
  451.     // (RDArgs retourne la valeur -1 lorsqu'un argument est indiqué)
  452.  
  453.     if (goPegaseArgs.pa_Mono + goPegaseArgs.pa_JStereo < -1)
  454.     {
  455.         goPegaseArgs.pa_Mono = goPegaseArgs.pa_JStereo = 0;
  456.     }
  457.  
  458.     if (goPegaseArgs.pa_Mono)           GlobalConfig.SetEncodingMode(MONO);
  459.     else if (goPegaseArgs.pa_JStereo)   GlobalConfig.SetEncodingMode(JOINTSTEREO);
  460.     else                                GlobalConfig.SetEncodingMode(STEREO);          // Mode par défaut.
  461.  
  462.     // Drapeaux divers.
  463.  
  464.     if (goPegaseArgs.pa_Copyright)     GlobalConfig.SetCopyrightBit(TRUE);
  465.     if (goPegaseArgs.pa_Original)      GlobalConfig.SetOriginalBit(TRUE);
  466.     if (goPegaseArgs.pa_CRC)           GlobalConfig.SetCRCBit(TRUE);
  467.  
  468.     if (goPegaseArgs.pa_UseIntFmt != goPegaseArgs.pa_UseMotFmt)
  469.     {
  470.         GlobalConfig.SetCDDAFmt(goPegaseArgs.pa_UseMotFmt ? 1 : 2);
  471.     }
  472.  
  473.     // Fréquence d'échantillonage. On sélectionne la fréquence standard la plus proche de celle
  474.     // mentionnée par l'utilisateur.
  475.  
  476.     if (!GlobalConfig.SetSampleFreq(*goPegaseArgs.pa_Frequency))
  477.     {
  478.         GlobalConfig.SetSampleFreq(44100);
  479.     }
  480.  
  481.     // Taux de sortie de l'encodeur.
  482.  
  483.     GlobalConfig.SetBitRate(*goPegaseArgs.pa_Bitrate);
  484.  
  485.     GlobalConfig.SetVerboseBit(goPegaseArgs.pa_Verbose);
  486.     GlobalConfig.SetDestination(goPegaseArgs.pa_To);
  487.     GlobalConfig.SetPattern(goPegaseArgs.pa_Pattern);
  488.  
  489.     if (goPegaseArgs.pa_From) GlobalConfig = goPegaseArgs.pa_From;
  490. }
  491. ///
  492.  
  493. //----------------------------------------------------------------------------------------------------
  494. //======================================= Classe PegaseConfigC =======================================
  495. //----------------------------------------------------------------------------------------------------
  496.  
  497. /// PegaseConfigC::CONSTRUCTOR
  498. /****** Class PegaseConfigC/CONSTRUCTOR *************************************
  499. *
  500. *   NAME
  501. *   PegaseConfigC::PegaseConfigC -- Constructeur
  502. *
  503. *   SYNOPSIS
  504. *   PegaseConfigC::PegaseConfigC()
  505. *
  506. *   PegaseConfigC::PegaseConfigC();
  507. *
  508. *   FUNCTION
  509. *   Initialise les paramètres par défaut de l'encodeur.
  510. *
  511. *****************************************************************************
  512. *
  513. */
  514.  
  515.  
  516. PegaseConfigC::PegaseConfigC()
  517. {
  518.     cfg_cPattern         = NULL;
  519.     ecfg_iLayer          = LAYER_II;             // Encodage en Layer II
  520.     ecfg_sFlags.encoding = STEREO;               // Mode stéréo
  521.     ecfg_sFlags.psycho2  = TRUE;                 // Modèle psycho-acoustique n°2
  522.  
  523.     ecfg_wSampling       = 44100;                // Fréquence d'échantillonage = 44,1 KHz
  524.     ecfg_sModes.sampfreq = F_44100;              // Code de fréquence
  525.     ecfg_wBitrate        = 128;                  // Taux de sortie = 128 kbits/s
  526.     ecfg_sModes.bitrate  = 7;                    // Index du taux de sortie.
  527. }
  528. ///
  529. /// PegaseConfigC::DESTRUCTOR
  530. /****** Class PegaseConfigC/DESTRUCTOR **************************************
  531. *
  532. *   NAME
  533. *   PegaseConfigC::~PegaseConfigC -- Destructeur
  534. *
  535. *   SYNOPSIS
  536. *   PegaseConfigC::~PegaseConfigC()
  537. *
  538. *   PegaseConfigC::~PegaseConfigC();
  539. *
  540. *   FUNCTION
  541. *   Libère chaque objet FileInfosC contenu dans la liste avant de détruire
  542. *   la liste.
  543. *
  544. *****************************************************************************
  545. *
  546. */
  547.  
  548.  
  549. PegaseConfigC::~PegaseConfigC()
  550. {
  551.     class FileInfosC *poNode;
  552.  
  553.     while ( (poNode = (FileInfosC *) RemHead()) != NULL)
  554.         delete poNode;
  555.  
  556.     if (cfg_cPattern) delete cfg_cPattern;
  557. }
  558. ///
  559. /// PegaseConfigC::SetDestination()
  560. void PegaseConfigC::SetDestination(STRING cDest)
  561. {
  562.     FileInfoBlock *pFIB;
  563.     CDOSObject     obj;
  564.     CLock          lock;
  565.     e_Targets t = TARGET_FILE;
  566.  
  567.     if (cDest == NULL || *cDest == 0)
  568.     {
  569.         t = TARGET_EMPTY;
  570.     }
  571.     else
  572.     {
  573.         if ( (lock.Lock(cDest, CLock::READ)) )
  574.         {
  575.             if ( (pFIB = (FileInfoBlock *) obj.Allocate(CDOSObject::FIB)) )
  576.             {
  577.                 if (::Examine(lock, pFIB))
  578.                 {
  579.                     if (pFIB->fib_DirEntryType >= 0)
  580.                     {
  581.                         t = TARGET_DIRECTORY;
  582.                     }
  583.                     else
  584.                     {
  585.                         t = TARGET_FILE;
  586.                     }
  587.                 }
  588.             }
  589.         }
  590.     }
  591.  
  592.     SetOutputName((char *) cDest);
  593.     SetTargetType(t);
  594. }
  595. ///
  596.  
  597.