home *** CD-ROM | disk | FTP | other *** search
/ AMIGA PD 1 / AMIGA-PD-1.iso / Programme_zum_Heft / Anwendungen / Kurztests / GoldED / data / tools / ED / main.c next >
C/C++ Source or Header  |  1995-02-25  |  11KB  |  453 lines

  1. /* -----------------------------------------------------------------------------
  2.  
  3.   ED 2.1 - GoldED quick starter, ©1995 Dietmar Eilert. Dice:
  4.  
  5.   dcc main.c sprintf.a -// -proto -mRR -mi -pr -2.0 -o ram:ED
  6.  
  7.   ------------------------------------------------------------------------------
  8. */
  9.  
  10. /// "includes"
  11.  
  12. #include <amiga20/exec/exec.h>
  13. #include <string.h>
  14. #include <stdio.h>
  15. #include <string.h>
  16. #include <stdlib.h>
  17. #include <stdarg.h>
  18. #include <amiga20/intuition/intuition.h>
  19. #include <amiga20/dos/dos.h>
  20. #include <amiga20/dos/dosextens.h>
  21. #include <amiga20/dos/rdargs.h>
  22. #include <amiga20/dos/dostags.h>
  23. #include <amiga20/workbench/startup.h>
  24. #include <amiga20/workbench/workbench.h>
  25. #include <amiga20/rexx/errors.h>
  26. #include <amiga20/rexx/rxslib.h>
  27.  
  28. #include <amiga20/clib/alib_protos.h>
  29. #include <amiga20/clib/dos_protos.h>
  30. #include <amiga20/clib/exec_protos.h>
  31. #include <amiga20/clib/icon_protos.h>
  32. #include <amiga20/clib/intuition_protos.h>
  33. #include <amiga20/clib/utility_protos.h>
  34. #include <amiga20/clib/rexxsyslib_protos.h>
  35. #include <amiga20/clib/wb_protos.h>
  36.  
  37. #ifdef PRAGMAS
  38.  
  39. #include "Pragmas/exec.h"
  40. #include "Pragmas/disk.h"
  41. #include "Pragmas/diskfont.h"
  42. #include "Pragmas/dynamic.h"
  43. #include "Pragmas/gadtools.h"
  44. #include "Pragmas/keymap.h"
  45. #include "Pragmas/graphics.h"
  46. #include "Pragmas/icon.h"
  47. #include "Pragmas/input.h"
  48. #include "Pragmas/intuition.h"
  49. #include "Pragmas/layers.h"
  50. #include "Pragmas/locale.h"
  51. #include "Pragmas/misc.h"
  52. #include "Pragmas/timer.h"
  53. #include "Pragmas/wb.h"
  54. #include "Pragmas/xpkmaster.h"
  55. #include "Pragmas/amigaguide.h"
  56. #include "Pragmas/reqtools.h"
  57.  
  58. #endif
  59.  
  60. #define Prototype        extern
  61. #define MAX_LEN          120
  62. #define ARGBUFFER_SIZE   10500
  63. #define ARGBUFFER_LIMIT  10000
  64.  
  65. ///
  66. /// "prototypes"
  67.  
  68. Prototype void   main(ULONG, UBYTE **);
  69. Prototype int    wbmain(struct WBStartup *);
  70. Prototype void   Action(UBYTE *, UBYTE *, UBYTE *, BOOL, BOOL, ULONG *);
  71. Prototype UBYTE  *StartGED(UBYTE *, UBYTE *, BOOL);
  72. Prototype ULONG *SendRexxCommand(UBYTE *, UBYTE *, struct MsgPort *);
  73. Prototype UBYTE  *LookForGED(void);
  74. Prototype UBYTE  *myprintf(UBYTE *, UBYTE*, ...);
  75. Prototype UBYTE  *xsprintf(UBYTE *, APTR);
  76. Prototype BOOL   FindAssign(UBYTE *);
  77.  
  78. extern struct Library *IconBase;
  79. extern struct Library *DOSBase;
  80. extern struct Library *SysBase;
  81. extern struct Library *IntuitionBase;
  82.  
  83. ///
  84. /// "entry points"
  85.  
  86. /* --------------------------------------- main --------------------------------
  87.  
  88.  CLI entry point. Parse command line - create a string <argBuffer> containing
  89.  provided  file  names  (file names are made absolute). This string has to be
  90.  FreeVec()'ed later on. Additionally, command line options are checked.
  91.  
  92. */
  93.  
  94. void
  95. main(argc, argv)
  96.  
  97. ULONG argc;
  98. UBYTE *argv[];
  99. {
  100.     UBYTE *argBuffer;
  101.  
  102.     if (argBuffer = AllocVec(ARGBUFFER_SIZE, MEMF_PUBLIC | MEMF_CLEAR)) {
  103.  
  104.         struct RDArgs *rdArgs;
  105.  
  106.         ULONG args[] = { 0, 0, 0, 0, 0, 0, 0 };
  107.  
  108.         if (rdArgs = ReadArgs("C=CONFIG/K,S=SCREEN/K,Y=STICKY/S,F=FILE/M,HIDE/S,-STICKY/S,L=LINE/N", args, NULL)) {
  109.  
  110.             if (args[3]) {
  111.  
  112.                 UBYTE **nextFile, path[MAX_LEN + 1];
  113.                 BPTR    lock;
  114.  
  115.                 for (nextFile = (UBYTE **)args[3]; *nextFile; ++nextFile) {
  116.  
  117.                     strcpy(path, *nextFile);
  118.  
  119.                     if (lock = Lock(path, ACCESS_READ)) {
  120.  
  121.                         NameFromLock(lock, path, MAX_LEN);
  122.                         UnLock(lock);
  123.                     }
  124.                     else if (strchr(path, ':') == NULL) {
  125.  
  126.                         GetCurrentDirName(path, MAX_LEN);
  127.  
  128.                         AddPart(path, *nextFile, MAX_LEN);
  129.                     }
  130.  
  131.                     strcat(argBuffer, xsprintf("\42%s\42", path));
  132.  
  133.                     if (strlen(argBuffer) > ARGBUFFER_LIMIT)
  134.                         break;
  135.                 }
  136.             }
  137.  
  138.             Action(argBuffer, (UBYTE *)args[0], (UBYTE *)args[1], (BOOL)args[2], (BOOL)args[4] || (BOOL)args[5], (ULONG *)args[6]);
  139.  
  140.             FreeArgs(rdArgs);
  141.         }
  142.         else
  143.             exit(20);
  144.     }
  145.     exit(0);
  146. }
  147.  
  148. /* ------------------------------------ wbmain ---------------------------------
  149.  
  150.  Workbench entry point. Read tooltypes of ED icon to decide wether user prefers
  151.  a special configuration/public screen.
  152.  
  153. */
  154.  
  155. int
  156. wbmain(struct WBStartup *wbs)
  157. {
  158.     UBYTE *argBuffer;
  159.  
  160.     if (argBuffer = AllocVec(ARGBUFFER_SIZE, MEMF_PUBLIC | MEMF_CLEAR)) {
  161.  
  162.         struct DiskObject *diskObject;
  163.         UBYTE             *config, *screen, progName[MAX_LEN + 1];
  164.         BOOL               hide;
  165.  
  166.         screen = NULL;
  167.         config = NULL;
  168.  
  169.         hide = FALSE;
  170.  
  171.         NameFromLock(GetProgramDir(), progName, MAX_LEN);
  172.  
  173.         AddPart(progName, wbs->sm_ArgList[0].wa_Name, MAX_LEN);
  174.  
  175.         if (diskObject = GetDiskObject(progName)) {
  176.  
  177.             config = FindToolType(diskObject->do_ToolTypes, "CONFIG");
  178.             screen = FindToolType(diskObject->do_ToolTypes, "SCREEN");
  179.  
  180.             if (FindToolType(diskObject->do_ToolTypes, "HIDE"))
  181.                 hide = TRUE;
  182.         }
  183.  
  184.         if (--wbs->sm_NumArgs) {
  185.  
  186.             UBYTE file[MAX_LEN + 1];
  187.  
  188.             struct WBArg *wbArg = wbs->sm_ArgList;
  189.  
  190.             while ((wbs->sm_NumArgs)--) {
  191.  
  192.                 ++wbArg;
  193.  
  194.                 NameFromLock( wbArg->wa_Lock, file, MAX_LEN);
  195.                 AddPart(file, wbArg->wa_Name, MAX_LEN);
  196.  
  197.                 strcat(argBuffer, xsprintf("\42%s\42", file));
  198.  
  199.                 if (strlen(argBuffer) > ARGBUFFER_LIMIT)
  200.                     break;
  201.             }
  202.         }
  203.  
  204.         Action(argBuffer, config, screen, FALSE, hide, NULL);
  205.  
  206.         if (diskObject)
  207.             FreeDiskObject(diskObject);
  208.     }
  209.  
  210.     exit(0);
  211. }
  212.  
  213. ///
  214. /// "main routine"
  215.  
  216. /* ------------------------------------ Action ---------------------------------
  217.  
  218.   Run  GoldED  if no running instance of GED is found (note: running GED will
  219.   open  a  first  window, i.e. no need to open a further one unless files are
  220.   speciefied).  Send LOCK ARexx messages to running GoldED. Wait for positive
  221.   reply,  pass our list of <files> to that editor, unlock editor (use delayed
  222.   unlock  unless  <sticky>  is specified). Suggestions for improvements: Make
  223.   the  whole  thing aynchrounous. Send LOCK messages to all running instances
  224.   of GoldED, then wait for first reply (or timeout).
  225.  
  226. */
  227.  
  228. void
  229. Action(files, config, screen, sticky, hide, line)
  230.  
  231. UBYTE *files, *config, *screen;
  232. ULONG *line;
  233. BOOL   sticky, hide;
  234. {
  235.     static UBYTE version[] = "$VER: ED 2.1 (" __COMMODORE_DATE__ ")";
  236.  
  237.     BOOL   useResident;
  238.     ULONG *result;
  239.     UBYTE *host;
  240.  
  241.     useResident = ((host = LookForGED()) != NULL);
  242.  
  243.     if (useResident == FALSE)
  244.         host = StartGED(config, screen, hide);
  245.  
  246.     if (host && (*files || (useResident && (hide == FALSE)))) {
  247.  
  248.         struct MsgPort *replyPort;
  249.  
  250.         if (replyPort = CreateMsgPort()) {
  251.  
  252.             if (result = SendRexxCommand(host, "LOCK CURRENT", replyPort)) {
  253.  
  254.                 if (*result == RC_OK) {
  255.  
  256.                     if (config && useResident)
  257.                         SendRexxCommand(host, xsprintf("PREFS LOAD SMART CONFIG=\42%s\42 ", config), replyPort);
  258.  
  259.                     if (*files)
  260.                         strins(files, "OPEN SMART QUIET ");
  261.                     else
  262.                         strcpy(files, "MORE SMART");
  263.  
  264.                     SendRexxCommand(host, files, replyPort);
  265.  
  266.                     if (line)
  267.                         SendRexxCommand(host, xsprintf("GOTO LINE=%ld UNFOLD=TRUE", (APTR)*line), replyPort);
  268.  
  269.                     SendRexxCommand(host, sticky ? "UNLOCK STICKY" : "UNLOCK DELAY", replyPort);
  270.                 }
  271.             }
  272.  
  273.             DeleteMsgPort(replyPort);
  274.         }
  275.     }
  276.  
  277.     FreeVec(files);
  278. }
  279.  
  280. ///
  281. /// "misc"
  282.  
  283. /* -------------------------------- FindAssign ---------------------------------
  284.  
  285.  Check whether assign exists without annoying 'insert drive requester'
  286.  
  287. */
  288.  
  289. BOOL
  290. FindAssign(assign)
  291.  
  292. UBYTE *assign;
  293. {
  294.     BOOL success = (FindDosEntry(LockDosList(LDF_ASSIGNS | LDF_READ), assign, LDF_ASSIGNS) != NULL);
  295.  
  296.     UnLockDosList(LDF_ASSIGNS | LDF_READ);
  297.  
  298.     return(success);
  299. }
  300.  
  301.  
  302. /* ----------------------------------- LookForGED ----------------------------
  303.  
  304.  Look for running GoldED task (check GOLDED.1 to GOLDED.9)
  305.  
  306. */
  307.  
  308. UBYTE *
  309. LookForGED()
  310. {
  311.     static UBYTE host[] = "GOLDED.1";
  312.  
  313.     UWORD try;
  314.  
  315.     for (try = '1'; try <= '9'; try++) {
  316.  
  317.         host[7] = try;
  318.  
  319.         if (FindPort(host))
  320.             return(host);
  321.     } 
  322.  
  323.     return(NULL);
  324. }
  325.  
  326. /* ------------------------------------- StartGED -----------------------------
  327.  
  328.   Launch a new GoldED task. Look for "GOLDED:" assign. Add assign if none is
  329.   found (defaultPath[] is set by the installer script). Return pointer to host
  330.   name (or NULL). Screen/config keywords are considered.
  331.  
  332. */
  333.  
  334. UBYTE *
  335. StartGED(config, screen, hide)
  336.  
  337. UBYTE *config, *screen;
  338. BOOL   hide;
  339. {
  340.     static UBYTE defaultPath[255] = "$GOLDED";
  341.  
  342.     UBYTE command[MAX_LEN + 1];
  343.  
  344.     if (FindAssign("GOLDED") == FALSE)
  345.         AssignLock("GOLDED", Lock(defaultPath, ACCESS_READ));
  346.  
  347.     strcpy(command, "GOLDED:GOLDED");
  348.  
  349.     if (hide)
  350.         strcat(command, " HIDE");
  351.  
  352.     if (config)
  353.         strcat(command, xsprintf(" CONFIG=\42%s\42", config));
  354.  
  355.     if (screen)
  356.         strcat(command, xsprintf(" SCREEN=%s", screen));
  357.  
  358.     if (!SystemTags(command, SYS_Asynch, TRUE, SYS_Input, NULL, SYS_Output, NULL, NP_StackSize, 8192, TAG_DONE)) {
  359.  
  360.         static UBYTE host[] = "GOLDED.1";
  361.  
  362.         UWORD  try;
  363.  
  364.         for (try = 50; try; try--, Delay(10))
  365.             if (FindPort(host))
  366.                 return(host);
  367.     }
  368.  
  369.     return(FALSE);
  370. }
  371.  
  372. /* --------------------------------- xsprintf ----------------------------------
  373.  
  374.  sprintf frontend (returns pointer to static buffer)
  375.  
  376. */
  377.  
  378. UBYTE *
  379. xsprintf(template, data)
  380.  
  381. UBYTE *template;
  382. APTR  data;
  383. {
  384.     static UBYTE buffer[MAX_LEN + 1];
  385.  
  386.     return(myprintf(buffer, template, data));
  387. }
  388.  
  389.  
  390. ///
  391. /// "ARexx"
  392.  
  393. /* ---------------------------------- SendRexxCommand -------------------------
  394.  
  395.  Send ARexx message & wait for answer. Return pointer to result or NULL.
  396.  
  397. */
  398.  
  399. ULONG *
  400. SendRexxCommand(port, cmd, replyPort)
  401.  
  402. struct MsgPort *replyPort;
  403. UBYTE          *cmd, *port;
  404. {
  405.     struct MsgPort *rexxport;
  406.  
  407.     Forbid();
  408.  
  409.     if (rexxport = FindPort(port)) {
  410.  
  411.         struct RexxMsg *rexxMsg, *answer;
  412.  
  413.         if (rexxMsg = CreateRexxMsg(replyPort, NULL, NULL)) {
  414.  
  415.             if (rexxMsg->rm_Args[0] = CreateArgstring(cmd, strlen(cmd))) {
  416.  
  417.                 static ULONG result;
  418.  
  419.                 rexxMsg->rm_Action = RXCOMM | RXFF_RESULT;
  420.  
  421.                 PutMsg(rexxport, &rexxMsg->rm_Node);
  422.  
  423.                 do {
  424.                     
  425.                     WaitPort(replyPort);
  426.  
  427.                     if (answer = (struct RexxMsg *)GetMsg(replyPort))
  428.                         result = answer->rm_Result1;
  429.  
  430.                 } while (!answer);
  431.  
  432.                 Permit();
  433.  
  434.                 if (answer->rm_Result1 == RC_OK) 
  435.                     if (answer->rm_Result2)
  436.                         DeleteArgstring((UBYTE *)answer->rm_Result2);
  437.  
  438.                 DeleteArgstring((UBYTE *)ARG0(answer));
  439.  
  440.                 DeleteRexxMsg(answer);
  441.  
  442.                 return(&result);
  443.             }
  444.         }
  445.     }
  446.  
  447.     Permit();
  448.  
  449.     return(NULL);
  450. }
  451.  
  452. ///
  453.