home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Exec 5 / CD_Magazyn_EXEC_nr_5.iso / Programy / Programowanie / FetchRefs2.1.lha / FetchRefs2.1 / Source / FetchRefs / Main.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-01-28  |  10.9 KB  |  444 lines

  1. /* main.c
  2. Originaly written by Anders Melchiorsen, modified by Roland Florac
  3. SPrintf routine slightly modified (caused the CPU 040 060 to crash)
  4. Modified from the original version for the ARexx interface
  5. Version 2.01: 27 january 2001 (added FR_FILE function) */
  6.  
  7. #include "FetchRefs.h"
  8. #include <libraries/locale.h>
  9. #include <clib/locale_protos.h>
  10. #include <pragmas/locale_pragmas.h>
  11.  
  12. static void __regargs LoadDataFragmented (BPTR file);
  13. static __regargs void ReadWBArgs (struct WBArg * wb_arg);
  14.  
  15. #define VERSION_CATALOGUE 1
  16.  
  17. const UBYTE Vers_Tag[] = "$VER: FetchRefs " VERSION DATE;
  18.  
  19. struct IntuitionBase * IntuitionBase;
  20. struct Library * RexxSysBase, * GTLayoutBase;
  21. struct LocaleBase * LocaleBase;
  22.  
  23. APTR catalogue;
  24.  
  25. /* ReadArgs stuff */
  26. UBYTE Template[] = "FILES/M,PORTNAME";
  27. UBYTE CLI_Help[] = "\n"
  28.     "FetchRefs [[FILES] <wildcard> [...]] [PORTNAME <name>]\n"
  29.     "\n"
  30.     "- FILES are index files generated by GenerateIndex\n"
  31.     "- Default ARexx port name is FETCHREFS\n"
  32.     "- Please read the guide for further information\n"
  33.     "\n";
  34.  
  35. struct RDArgs *Args;
  36. struct {
  37.     STRPTR  (*Files)[];
  38.     STRPTR  Portname;
  39. } StartupArgs;
  40.  
  41. /* Other variables */
  42. struct List FileList;
  43. APTR FilePool;
  44. long WorkBench = 0;    /* Signale que le programme a été démarré du WorkBench */
  45.  
  46. /* Localized strings */
  47. char * texts[] = {
  48.     "AutoDoc/include file look-up utility",
  49.     "You need gtlayout.library V%ld+!", "Error opening ARexx port",
  50.     "There is a problem with this tool type:\n%s\n(%s [#%ld])",
  51.     "Warning: no match for pattern '%s'", "Removing FetchRefs...",
  52.     "FetchRefs " VERSION " (Anders Melchiorsen & Roland Florac)", "Okay",
  53.     "Select reference",
  54.     "Search _pattern", "Fetch reference", "_List file", "Cancel",
  55.     "Could not open guide", "Could not open amigaguide.library v34+",
  56.     "FetchRefs: Reference not found", "FetchRefs: Aborted!"
  57. };
  58.  
  59. char * __regargs GetString (long indice)
  60. {   STRPTR def = texts[indice];
  61.     return (catalogue ? GetCatalogStr (catalogue, indice, def) : def);
  62. }
  63.  
  64. void ouverture_port_ARexx (void)
  65. {   Forbid ();
  66.     if (FindPort ("FETCHREFS") == 0)
  67.     rexxPort = CreatePort ("FETCHREFS", 0);
  68.     Permit ();
  69. }
  70.  
  71. static void fermeture_port_ARexx (void)
  72. {   if (rexxPort)
  73.     {    RemPort (rexxPort);
  74.     DeletePort (rexxPort);
  75.     CloseLibrary (RexxSysBase);
  76.     }
  77. }
  78.  
  79. main (LONG argc, STRPTR argv)
  80. {
  81.     STRPTR port;
  82.     struct WBStartup * argmsg;        struct WBArg * wb_arg;
  83.     struct MsgPort *otherport;
  84.  
  85.     if (LocaleBase = (struct LocaleBase *) OpenLibrary ("locale.library", 38))
  86.     catalogue = OpenCatalog (NULL, "FetchRefs.catalog", OC_Version, VERSION_CATALOGUE, TAG_DONE);
  87.  
  88.     IntuitionBase = (struct IntuitionBase *) OldOpenLibrary ("intuition.library");
  89.     if (IntuitionBase == 0)
  90.     CloseAll (0);
  91.  
  92.     /* We need GTLayout */
  93.     GTLayoutBase = OpenLibrary ("gtlayout.library", 45);
  94.     if (GTLayoutBase == 0)
  95.     {
  96.     PostMessage (GetString(TEXTE_GTLAYOUT), 45);
  97.     CloseAll (0);
  98.     }
  99.  
  100.     /* Initialize list */
  101.     NewList (&FileList);
  102.  
  103.     if (!(FilePool = LibCreatePool (MEMF_CLEAR, 8 * 1024, 8 * 1024)))
  104.     CloseAll (ERROR_NO_FREE_STORE);
  105.  
  106.     /* Allocate memory for argument parsing */
  107.     if (!(Args = AllocDosObject (DOS_RDARGS, NULL)))
  108.     CloseAll (ERROR_NO_FREE_STORE);
  109.  
  110.     /* Convert tool types to something that ReadArgs() understands if we are
  111.      * run by Workbench.
  112.      */
  113.     if (argc == 0)
  114.     {    argmsg = (struct WBStartup *) argv;
  115.     wb_arg = argmsg->sm_ArgList ;
  116.     WorkBench = 0;
  117.     ReadWBArgs (wb_arg);
  118.     }
  119.  
  120.     /* Activate extended help */
  121.     Args->RDA_ExtHelp = CLI_Help;
  122.  
  123.     /* Parse arguments from either the Shell or Workbench */
  124.     if (!(ReadArgs (Template, (LONG *)&StartupArgs, Args)))
  125.     CloseAll (IoErr());
  126.  
  127.     /* Do not bother to start if the user pressed CTRL-C during load
  128.      * time or during a 'FetchRefs ?' help session.
  129.      */
  130.     if (CheckSignal (SIGBREAKF_CTRL_C))
  131.     CloseAll (0);
  132.  
  133.     /* Try to allocate an ARexx port. Default port name is FETCHREFS.
  134.      * We quit both copies of FetchRefs if our port name is used.
  135.      */
  136.     port = StartupArgs.Portname;
  137.  
  138.     if (!port)
  139.     port = "FETCHREFS";
  140.  
  141.     if (otherport = FindPort (port))
  142.     {    Signal (otherport->mp_SigTask, SIGBREAKF_CTRL_C);
  143.  
  144.     CloseAll (ERROR_RUNTWICE);
  145.     }
  146.  
  147.     /* Open ARexx port */
  148.     ouverture_port_ARexx ();
  149.     if (! rexxPort)
  150.     {
  151.     PostMessage (GetString (TEXTE_AREXX_PORT));
  152.     CloseAll (0);
  153.     }
  154.  
  155.     /* Expand each wildcard (which can also be just a file) and read refs */
  156.     if (StartupArgs.Files)
  157.     ReadWild (StartupArgs.Files);
  158.  
  159.     /* Install Commodities Broker */
  160.     InstallCx (port);
  161.  
  162.     /* Activate ARexx handler and quit when it returns */
  163.     MessageLoop ();
  164.     CloseAll (0);
  165. }
  166.  
  167. /* ReadWBArgs() - convert tool types to ReadArgs() string */
  168. static __regargs void ReadWBArgs (struct WBArg * wb_arg)
  169. {
  170.     struct DiskObject *diskobj;
  171.     STRPTR ToolTypeArgs;
  172.  
  173.     if (!(ToolTypeArgs = AllocVec (1024, NULL)))
  174.     CloseAll (ERROR_NO_FREE_STORE);
  175.  
  176.     CurrentDir (wb_arg->wa_Lock);
  177.     if (diskobj = GetDiskObject (wb_arg->wa_Name))
  178.     {
  179.     int err;
  180.  
  181.     if (err = ToolTypesToReadArgs (diskobj->do_ToolTypes, Template, ToolTypeArgs, 1))
  182.     {
  183.         UBYTE errortxt[80];
  184.  
  185.         Fault (err & 0xFFFF, NULL, errortxt, 80);
  186.  
  187.         PostMessage(
  188.         GetString (TEXTE_TOOLTYPE),
  189.         diskobj->do_ToolTypes[err >> 16],
  190.         errortxt,
  191.         err & 0xFFFF);
  192.  
  193.         FreeDiskObject (diskobj);
  194.         CloseAll (0);
  195.     }
  196.  
  197.     Args->RDA_Source.CS_Buffer = ToolTypeArgs;
  198.     Args->RDA_Source.CS_Length = strlen(ToolTypeArgs);
  199.     Args->RDA_Flags = RDAF_NOPROMPT;
  200.  
  201.     FreeDiskObject (diskobj);
  202.     }
  203. }
  204.  
  205. /* ReadWild() - read all files that match argument
  206.  * The argument is a pointer to an NULL terminated array of STRPTR (as
  207.  * returned by ReadArgs("ARG/M"); ). */
  208. void __regargs ReadWild (STRPTR (*patharrayptr)[])
  209. {
  210.     struct AnchorPath *fanchor;
  211.     LONG cnt;
  212.     STRPTR path;
  213.  
  214.     if (!(fanchor = AllocVec (sizeof(struct AnchorPath), MEMF_CLEAR)))
  215.     return;
  216.  
  217.     for (cnt = 0; path = (*patharrayptr)[cnt]; cnt++)
  218.     {
  219.     if (MatchFirst (path, fanchor) == 0)
  220.     {
  221.         do
  222.         {
  223.         BPTR olddir;
  224.  
  225.         olddir = CurrentDir (fanchor->ap_Current->an_Lock);
  226.         ReadRefs (fanchor->ap_Info.fib_FileName, fanchor->ap_Info.fib_Size);
  227.         CurrentDir (olddir);
  228.         }
  229.         while (MatchNext(fanchor) == 0);
  230.     }
  231.     else
  232.         PostMessage (GetString (TEXTE_PATTERN), path);
  233.  
  234.     MatchEnd (fanchor);
  235.     }
  236.     FreeVec (fanchor);
  237. }
  238.  
  239. /* ReadRefs() - Read all references in 'filename' (with length 'filesize') */
  240. void __regargs ReadRefs (STRPTR filename, LONG filesize)
  241. {
  242.     BPTR file;
  243.  
  244.     /* First ensure that we can really open the file */
  245.     if (!(file = Open (filename, MODE_OLDFILE)))
  246.     return;
  247.  
  248.     /* If we cannot load the file fast then try the slower routine */
  249.     if (!LoadData (file, filesize))
  250.     LoadDataFragmented (file);
  251.  
  252.     Close (file);
  253. }
  254.  
  255. /* LoadData() - fast loader using large memory chunk */
  256. BOOL __regargs LoadData (BPTR file, LONG filesize)
  257. {
  258.     struct FileEntry * fileentry = 0;
  259.     char * gotto, * buffer;
  260.  
  261.     if (!(buffer = LibAllocPooled (FilePool, filesize)))
  262.     return FALSE;
  263.  
  264.     Read (file, buffer, filesize);
  265.  
  266.     gotto = buffer;
  267.     buffer += filesize;
  268.  
  269.     while (gotto < buffer)
  270.     {
  271.     LONG size;
  272.  
  273.     /* The size is saved in the .ln_Succ field of the Node */
  274.     size = (LONG)(((struct Node *)gotto)->ln_Succ);
  275.  
  276.     if (((struct Node *) gotto)->ln_Type == 1)
  277.     {
  278.         fileentry = (struct FileEntry *) gotto;
  279.         AddTail (&FileList, &fileentry->node);
  280.         NewList (&fileentry->RefsList);
  281.         fileentry->node.ln_Name = fileentry->Name;
  282.     }
  283.     else if (((struct Node *)gotto)->ln_Type == 2)
  284.     {
  285.         struct RefsEntry *refsentry;
  286.         refsentry = (struct RefsEntry *) gotto;
  287.         AddTail (&fileentry->RefsList, &refsentry->node);
  288.         refsentry->node.ln_Name = fileentry->Name;
  289.     }
  290.     gotto += size;
  291.     }
  292.  
  293.     return TRUE;
  294. }
  295.  
  296. /* LoadDataFragmented() - Load into fragmented memory. A bit slower. */
  297. static void __regargs LoadDataFragmented (BPTR file)
  298. {
  299.     char * buffer;
  300.     struct FileEntry * fileentry = 0;
  301.     struct Node tmpnode;
  302.  
  303.     while (Read (file, &tmpnode, sizeof(struct Node)))
  304.     {
  305.     /* The size of the node is saved in the .ln_Succ filed */
  306.     if (!(buffer = LibAllocPooled (FilePool, (LONG)tmpnode.ln_Succ)))
  307.         break;
  308.  
  309.     /* Fill in the node with information from the file */
  310.     // fread (buffer + sizeof(struct Node), (LONG)tmpnode.ln_Succ - sizeof(struct Node), 1, file);
  311.     Read (file, buffer + sizeof(struct Node), (LONG)tmpnode.ln_Succ - sizeof(struct Node));
  312.  
  313.     if (tmpnode.ln_Type == 1)
  314.     {
  315.         /* A new file starts here */
  316.         fileentry = ((struct FileEntry *)buffer);
  317.  
  318.         AddTail (&FileList, &fileentry->node);
  319.         NewList (&fileentry->RefsList);
  320.         fileentry->node.ln_Name = fileentry->Name;
  321.     }
  322.     else if (tmpnode.ln_Type == 2)
  323.     {
  324.         struct RefsEntry * refsentry = ((struct RefsEntry *)buffer);
  325.  
  326.         /* Another reference in the current file */
  327.         AddTail (&fileentry->RefsList, &refsentry->node);
  328.         refsentry->node.ln_Name = fileentry->Name;
  329.     }
  330.     }
  331. }
  332.  
  333. /* FreeRefs() - Release all files from memory and re-initialize list */
  334. void FreeRefs ()
  335. {
  336.     NewList (&FileList);
  337.     LibDeletePool (FilePool);
  338.  
  339.     if (!(FilePool = LibCreatePool (MEMF_CLEAR, 8 * 1024, 8 * 1024)))
  340.     CloseAll (ERROR_NO_FREE_STORE);
  341. }
  342.  
  343. /* CloseAll() - Clean up and possibly print an error report */
  344. void CloseAll (LONG error, ...)
  345. {
  346.     LibDeletePool (FilePool);
  347.  
  348.     if (WorkBench)
  349.     FreeVec (Args->RDA_Source.CS_Buffer);
  350.  
  351.     if (Args)
  352.     {
  353.     FreeArgs (Args);
  354.     FreeDosObject (DOS_RDARGS, Args);
  355.     }
  356.  
  357.     if (error)
  358.     {
  359.     /* Print an error message, either standard or custom... */
  360.  
  361.     if (error > ERROR_SPECIALMAX)
  362.     {
  363.         UBYTE errtxt[80];
  364.  
  365.         Fault (error, "FetchRefs", errtxt, 80);
  366.         PostMessage (errtxt);
  367.     }
  368.     else if (error != ERROR_RUNTWICE)
  369.     {
  370.         va_list args;
  371.  
  372.         va_start (args, error);
  373.         PostMessage (*(STRPTR *)args);
  374.         va_end (args);
  375.     }
  376.     }
  377.     else
  378.     TellWeStopOutline ();
  379.  
  380.     if (IntuitionBase)
  381.     CloseLibrary (IntuitionBase);
  382.  
  383.     if (LocaleBase)
  384.     {    CloseCatalog (catalogue);
  385.     CloseLibrary (LocaleBase);
  386.     }
  387.  
  388.     if (GTLayoutBase)
  389.     {
  390.     CloseLibrary (GTLayoutBase);
  391.     GTLayoutBase = 0;
  392.     }
  393.     RemoveCx();
  394.     fermeture_port_ARexx();
  395.     _exit((error) && (error != ERROR_RUNTWICE)  ? 5 : 0);
  396. }
  397.  
  398. /* PostMessage() - printf() like requester function. Uses Shell if available */
  399. void PostMessage (STRPTR fmt, ...)
  400. {
  401.     static struct EasyStruct msgreq = {
  402.     sizeof(struct EasyStruct),
  403.     0,
  404.     0,
  405.     NULL,
  406.     0
  407.     };
  408.  
  409.     va_list args;
  410.  
  411.     msgreq.es_Title = GetString (TEXTE_VERSION);
  412.     msgreq.es_GadgetFormat = GetString (TEXTE_OK);
  413.     msgreq.es_TextFormat = fmt;
  414.  
  415.     va_start (args, fmt);
  416.  
  417.     if (WorkBench)
  418.     EasyRequestArgs (NULL, &msgreq, NULL, args);
  419.     else
  420.     {
  421.     VPrintf (fmt, args);
  422.     PutStr ("\n");
  423.     }
  424.  
  425.     va_end (args);
  426. }
  427.  
  428. /* SPrintf() - Low-cost sprintf routine using RawDoFmt()-formatting */
  429. void SPrintf (UBYTE *buf, UBYTE *fmt, ...)
  430. {
  431.     /* The "\x16\xC0\x4E\x75" part is really code that gets executed
  432.      * for each character output:
  433.      *    move.b    d0,(a3)+
  434.      *    rts
  435.      * DATA (move, rts) MUST BE STATIC TO BE USED WITH CACHE PROCESSORS ! (680x0)
  436.      */
  437.     static __aligned char move_rts[4] = { '\x16', '\xC0', '\x4E', '\x75' };
  438.     va_list args;
  439.  
  440.     va_start (args, fmt);
  441.     RawDoFmt (fmt, args, (void *)move_rts, buf);
  442.     va_end (args);
  443. }
  444.