home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD1.iso / Editor / orb!g3.lha / Install / data / tools / Source / ed.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-04-30  |  11.4 KB  |  468 lines

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