home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #6 / amigamamagazinepolishissue1998.iso / coders / biblioteki / c_library / extrdargs / extrdargs.c next >
C/C++ Source or Header  |  1977-12-31  |  16KB  |  546 lines

  1. /*
  2. ** $PROJECT: CLI/Workbench ReadArgs()
  3. **
  4. ** $VER: extrdargs.c 1.5 (08.01.95)
  5. **
  6. ** by
  7. **
  8. ** Stefan Ruppert , Windthorststraße 5 , 65439 Flörsheim , GERMANY
  9. **
  10. ** (C) Copyright 1994,1995
  11. ** All Rights Reserved !
  12. **
  13. ** $HISTORY:
  14. **
  15. ** 08.01.95 : 001.005 :  changed to ExtReadArgs()
  16. ** 24.09.94 : 001.004 :  now checks after ReadArgs the SIGBREAKF_CTRL_C flag,
  17. **                       thus if anyone canceled during ReadArgs() help
  18. **                       ExtReadArgs() fails
  19. ** 08.09.94 : 001.003 :  between two switches (no equal sign) there was
  20. **                       no space, this is fixed
  21. ** 08.09.94 : 001.002 :  wb files now enclosed in quotes
  22. ** 04.09.94 : 001.001 :  bumped to version 1
  23. ** 19.05.94 : 000.001 :  initial
  24. */
  25.  
  26. /* ------------------------------ include's ------------------------------- */
  27.  
  28. #include "extrdargs.h"
  29.  
  30. #include <clib/dos_protos.h>
  31. #include <clib/icon_protos.h>
  32. #include <clib/exec_protos.h>
  33.  
  34. #include <proto/dos.h>
  35. #include <proto/icon.h>
  36. #include <proto/exec.h>
  37.  
  38. /* ---------------------------- local defines ----------------------------- */
  39.  
  40. #define bug      kprintf
  41.  
  42. #ifdef DEBUG_CODE
  43. #define D(x)     x
  44.  
  45. extern void kprintf(char *fmt,...);
  46.  
  47. #else
  48. #define D(x)
  49. #endif
  50.  
  51. #define TEMPSIZE                     512
  52. #ifndef MAX
  53. #define MAX(a,b)  (((a) > (b)) ? (a) : (b))
  54. #endif
  55.  
  56. #ifndef EOS
  57. #define EOS    '\0'
  58. #endif
  59.  
  60. #define MODE_MULTI      1
  61.  
  62. /* -------------------------- static prototypes --------------------------- */
  63.  
  64. static struct DiskObject *ExtGetIcon(struct ExtRDArgs *args,struct WBStartup *wbarg);
  65. static void fstrcpy(struct ExtRDArgs *args,STRPTR string);
  66. static void getargname(struct ExtRDArgs *args,STRPTR buffer,ULONG size,ULONG *modes);
  67. static void getwbargname(struct WBArg *wbarg,STRPTR buffer,ULONG size);
  68.  
  69. /*FS*/ /*"AutoDoc --background--"*/
  70. /*GB*** ExtReadArgs/--background-- *******************************************
  71. *
  72. *    PURPOSE
  73. *        This is a CLI/Workbench transparent argument interface. I don't liked
  74. *        the way of parsing ToolTypes and used only the ReadArgs() function.
  75. *        Thus all my tools can only be invoked from the CLI/Shell . Thats the
  76. *        reason for building this project !
  77. *
  78. *    FUNCTION
  79. *        ExtReadArgs() copies all Workbench arguments in a single string and
  80. *        passes this string to the ReadArgs() function. All WBArg structure
  81. *        are expanded to their full filenames , enclosed in '"' and passed to
  82. *        the item specified via the erda_FileParameter field. Then all Tool-
  83. *        types are strcat()'ed into one line, thus ReadArgs() can handle it.
  84. *        To handle each Tooltype correctly the argument is enclosed in '"' !
  85. *
  86. *    NOTE
  87. *        There are some special feature according to the ReadArgs() function.
  88. *        If you have a template like "FROM/M/A,TO/A", you can select these
  89. *        files from workbench : Select the program, then the FROM files and
  90. *        finally select and double click th TO file. This is available,because
  91. *        ReadArgs() grab's the last string from a MultiArg FROM and uses it
  92. *        as the TO parameter, if no is explicitly given !
  93. *
  94. *    INSPIRATION
  95. *        I get the main idea, how I implement the Workbench ReadArgs()
  96. *        interface from the author of ARoach Stefan Winterstein. Thanks for
  97. *        this idea of parsing ToolTypes !
  98. *
  99. ******************************************************************************
  100. *
  101. */
  102. /*FE*/
  103.  
  104. /*FS*/ /*"AutoDoc ExtReadArgs()"*/
  105. /*GB*** ExtReadArgs/ExtReadArgs **********************************************
  106. *
  107. *    NAME
  108. *        ExtReadArgs - CLI/Workbench transparent ReadArgs() function
  109. *
  110. *    SYNOPSIS
  111. *        error = ExtReadArgs(ac,av,extrdargs);
  112. *
  113. *        LONG ExtReadArgs(LONG ,STRPTR *,struct ExtRDArgs *);
  114. *
  115. *    FUNCTION
  116. *        this function is a CLI/Workbench transparent interface to ReadArgs().
  117. *        It uses the argcount and argvector like SASC from the main entry 
  118. *        point, to get the initial startup parameter. If ac is zero, so the
  119. *        program is invoked from workbench and the av variable contains the
  120. *        WBStartup structure ! Before you can call this function, you must set
  121. *        up the library bases for dos.library and icon.library. Normally the
  122. *        SASC autoinitialization code does this for you !
  123. *        If all went right you get a return value of zero. This means the
  124. *        passed arguments fits the template and are ready to use. Otherwise
  125. *        you get a IoErr() like return code. You can pass this return value
  126. *        directly to PrintFault() or something like that !
  127. *
  128. *        NOTE : You must call the ExtFreeArgs() function to clean up, even
  129. *               this function fails (see EXAMPLE) !!!
  130. *
  131. *    INPUTS
  132. *        ac (LONG) - parameter normally get from main()
  133. *        av (STRPTR *) - parameter normally get from main()
  134. *        extrdargs (struct ExtRDArgs *) - structure , which hold any
  135. *            information used by ExtReadArgs()
  136. *
  137. *        structure fields to setup before calling ExtReadArgs() :
  138. *
  139. *            erda_Template - the really ReadArgs() template
  140. *            erda_Parameter - ReadArgs() LONG WORD array to hold the arguments
  141. *            erda_FileParameter - number of Argument in the template to use
  142. *                for the files passed via WBStartup->sm_ArgList or -1, that
  143. *                means you don't want any files
  144. *            erda_Window - window description string to open, if the program
  145. *                is started from the workbench or NULL for no window ! If
  146. *                in the ToolType Array exists a WINDOW description this is used
  147. *                instead of the parameter of the ExtRDArgs structure !
  148. *            erda_RDArgs - RDArgs structure to use for ReadArgs() call, thus
  149. *                you can use extended help !
  150. *            erda_Buffer - pointer to a buffer to use for the Workbench startup
  151. *                or NULL, that means ExtReadArgs() allocates a buffer for you
  152. *            erda_BufferSize - if you provided a buffer, here is the length of
  153. *                it. If not this is the length you would have ! This length is
  154. *                checked against a minimum of ERDA_MIN_BUFFER_SIZE !
  155. *
  156. *    RESULTS
  157. *        zero for success, otherwise an IoErr() like error code.
  158. *
  159. *        If the function successes you can check the erda_Flags field for the
  160. *        FRDAF_WORKBENCH flag, if you want to known from where the program was
  161. *        started
  162. *
  163. *    EXAMPLE
  164. *        \* In this example the dos.library and icon.library must be open
  165. *         * from autoinitialization code
  166. *         *\
  167. *        LONG main(LONG ac,STRPTR *av)
  168. *        {
  169. *           struct ExtRDArgs eargs = {NULL};
  170. *           LONG para[2];
  171. *           LONG error;
  172. *
  173. *           eargs.erda_Template      = "FILES/M/A,VERBOSE";
  174. *           eargs.erda_Parameter     = para;
  175. *           eargs.erda_FileParameter = 0;
  176. *           eargs.erda_Window        = "CON:////My WB-Window/CLOSE/WAIT";
  177. *
  178. *           if((error = ExtReadArgs(ac,av,&eargs)) == 0)
  179. *           {
  180. *              \* do something *\
  181. *           } else
  182. *              PrintFault(error,"MyProgram");
  183. *           ExtFreeArgs(&eargs);
  184. *
  185. *           return((error == 0) ? RETURN_OK : RETURN_FAIL);
  186. *        }
  187. *
  188. *    SEE ALSO
  189. *        ExtFreeArgs(), dos.library/ReadArgs(),
  190. *        icon.library/GetDiskObjectNew()
  191. *
  192. ******************************************************************************
  193. *
  194. */
  195. /*FE*/
  196.  
  197. LONG ExtReadArgs(LONG ac,STRPTR *av,struct ExtRDArgs *args)
  198. {
  199.    LONG error;
  200.  
  201.    args->erda_Flags = 0;
  202.  
  203.    if(ac == 0)
  204.    {
  205.       if(!(args->erda_RDArgs = AllocDosObject(DOS_RDARGS,NULL)))
  206.          return(ERROR_NO_FREE_STORE);
  207.       else
  208.       {
  209.          args->erda_Flags |= ERDAF_ALLOCRDARGS;
  210.  
  211.          if(!args->erda_Buffer)
  212.          {
  213.             args->erda_BufferSize = MAX(ERDA_MIN_BUFFER_SIZE,args->erda_BufferSize);
  214.             args->erda_Buffer     = AllocMem(args->erda_BufferSize,MEMF_ANY);
  215.             args->erda_Flags     |= ERDAF_ALLOCBUFFER;
  216.          }
  217.  
  218.          if(!args->erda_Buffer)
  219.             return(ERROR_NO_FREE_STORE);
  220.          else
  221.          {
  222.             struct WBStartup *wbstart = (struct WBStartup *) av;
  223.             struct DiskObject *dobj;
  224.  
  225.             args->erda_ActualPtr = args->erda_Buffer;
  226.             args->erda_EndPtr    = args->erda_Buffer + args->erda_BufferSize - 1;
  227.  
  228.             if(!(dobj = ExtGetIcon(args,wbstart)))
  229.                return(ERROR_OBJECT_NOT_FOUND);
  230.             else
  231.             {
  232.                struct WBArg *wbarg = args->erda_WBArg;
  233.                ULONG num           = args->erda_NumArgs;
  234.  
  235.                STRPTR *tooltypes = dobj->do_ToolTypes;
  236.                STRPTR name;
  237.                STRPTR temp;
  238.                STRPTR ptr;
  239.  
  240.                if(num > 1 && args->erda_FileParameter >= 0 && (temp = AllocMem(TEMPSIZE,MEMF_ANY)))
  241.                {
  242.                   ULONG modes = 0;
  243.  
  244.                   getargname(args,temp,TEMPSIZE,&modes);
  245.                   fstrcpy(args,temp);
  246.                   fstrcpy(args," ");
  247.  
  248.                   /* no "/M" specifier in the ReadArgs() template, thus use only the first file */
  249.                   if(modes != MODE_MULTI)
  250.                      num = 2;
  251.  
  252.                   while(num > 1)
  253.                   {
  254.                      getwbargname(wbarg,temp,TEMPSIZE);
  255.                      fstrcpy(args,"\"");
  256.                      fstrcpy(args,temp);
  257.                      fstrcpy(args,"\" ");
  258.                      num--;
  259.                      wbarg++;
  260.                   }
  261.  
  262.                   FreeMem(temp,TEMPSIZE);
  263.                }
  264.  
  265.                while(*tooltypes)
  266.                {
  267.                   ptr = *tooltypes;
  268.                   name = ptr;
  269.  
  270.                   /* check if this tooltype isn`t disabled */
  271.                   if(*ptr != '(')
  272.                   {
  273.                      while(*ptr != '=' && *ptr != EOS)
  274.                         ptr++;
  275.  
  276.                      if(*ptr == '=')
  277.                      {
  278.                         *ptr = EOS;
  279.  
  280.                         if(!strcmp(name,"WINDOW"))
  281.                         {
  282.                            STRPTR win;
  283.                            if((win = AllocVec(strlen(ptr + 1) + 1,MEMF_ANY)))
  284.                            {
  285.                               strcpy(win,ptr + 1);
  286.                               args->erda_Window = win;
  287.                               args->erda_Flags |= ERDAF_ALLOCWINDOW;
  288.                            }
  289.  
  290.                         } else
  291.                         {
  292.                            fstrcpy(args,name);
  293.  
  294.                            /* enclose the argument in "" */
  295.                            if(*(ptr + 1) == '"')
  296.                            {
  297.                               fstrcpy(args,"=");
  298.                               fstrcpy(args,ptr+1);
  299.                            } else
  300.                            {
  301.                               fstrcpy(args,"=\"");
  302.                               fstrcpy(args,ptr+1);
  303.                               fstrcpy(args,"\"");
  304.                            }
  305.  
  306.                            *ptr = '=';
  307.                         }
  308.                      } else
  309.                         fstrcpy(args,name);
  310.  
  311.                      fstrcpy(args," ");
  312.                   }
  313.                   tooltypes++;
  314.                }
  315.                fstrcpy(args,"\n");
  316.  
  317.                D(bug("final wb command line : %s\n",args->erda_Buffer));
  318.             }
  319.          }
  320.       }
  321.  
  322.       args->erda_RDArgs->RDA_Source.CS_Buffer = args->erda_Buffer;
  323.       args->erda_RDArgs->RDA_Source.CS_Length = strlen(args->erda_Buffer);
  324.  
  325.       args->erda_Flags |= ERDAF_WORKBENCH;
  326.    }
  327.  
  328.    args->erda_FreeArgs = ReadArgs(args->erda_Template,args->erda_Parameter,args->erda_RDArgs);
  329.  
  330.    if(SetSignal(0L,SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C)
  331.       SetIoErr(ERROR_BREAK);
  332.  
  333.    if((error = IoErr()) == 0 && ac == 0)
  334.       if(args->erda_Window)
  335.       {
  336.          if(args->erda_WindowFH = Open(args->erda_Window,MODE_NEWFILE))
  337.          {
  338.             args->erda_OldOutput = SelectOutput(args->erda_WindowFH);
  339.             args->erda_OldInput  = SelectInput(args->erda_WindowFH);
  340.          }
  341.       }
  342.  
  343.  
  344.    return(error);
  345. }
  346.  
  347. /*FS*/ /*"AutoDoc ExtFreeArgs()"*/
  348. /*GB*** ExtReadArgs/ExtFreeArgs **********************************************
  349. *
  350. *    NAME
  351. *        ExtFreeArgs - free's all allocated resources from ExtReadArgs()
  352. *
  353. *    SYNOPSIS
  354. *        ExtFreeArgs(extrdargs);
  355. *
  356. *        void ExtFreeArgs(struct ExtRDArgs *);
  357. *
  358. *    FUNCTION
  359. *        free's all allocated resources from a previously call to
  360. *        ExtReadArgs().
  361. *
  362. *    INPUTS
  363. *        extrdargs (struct ExtRDArgs *) - same pointer, which was passed
  364. *            to ExtReadArgs()
  365. *
  366. *    RESULTS
  367. *        none
  368. *
  369. *    SEE ALSO
  370. *        ExtReadArgs()
  371. *
  372. ******************************************************************************
  373. *
  374. */
  375. /*FE*/
  376.  
  377. void ExtFreeArgs(struct ExtRDArgs *args)
  378. {
  379.    /* FreeArgs() can handle a NULL pointer */
  380.    FreeArgs(args->erda_FreeArgs);
  381.  
  382.    if(args->erda_Flags & ERDAF_ALLOCRDARGS)
  383.       if(args->erda_RDArgs)
  384.          FreeDosObject(DOS_RDARGS,args->erda_RDArgs);
  385.  
  386.    if(args->erda_Flags & ERDAF_ALLOCBUFFER)
  387.       FreeMem(args->erda_Buffer,args->erda_BufferSize);
  388.  
  389.    if(args->erda_WindowFH)
  390.    {
  391.       SelectOutput(args->erda_OldOutput);
  392.       SelectInput(args->erda_OldInput);
  393.       Close(args->erda_WindowFH);
  394.    }
  395.  
  396.    if(args->erda_Flags & ERDAF_ALLOCWINDOW && args->erda_Window)
  397.       FreeVec(args->erda_Window);
  398.  
  399. }
  400.  
  401. /* This code was grapped from IconImage/wbarg.c/IconFromWBArg()
  402.  * Commodore-Amiga Example code
  403.  */
  404.  
  405. static struct DiskObject *ExtGetIcon(struct ExtRDArgs *args,struct WBStartup *wbstart)
  406. {
  407.    struct DiskObject *dob   = NULL;
  408.    struct WBArg      *wbarg = wbstart->sm_ArgList;
  409.    ULONG num                = wbstart->sm_NumArgs;
  410.  
  411.    UBYTE work_name[34];
  412.    BPTR old, new;
  413.  
  414.    /* Copy the WBArg contents */
  415.    strcpy (work_name, wbarg->wa_Name);
  416.  
  417.    if (new = DupLock (wbarg->wa_Lock))
  418.    {
  419.       D(bug("work_name : %s\n",work_name));
  420.  
  421.       /* go to the directory where the icon resides */
  422.       old = CurrentDir (new);
  423.  
  424.       dob = GetDiskObjectNew (work_name);
  425.  
  426.       /* test, if the first icon is a project icon and if so, get its icon */
  427.       if(wbstart->sm_NumArgs > 1)
  428.       {
  429.          BPTR new2;
  430.  
  431.          if((new2 = DupLock(wbarg[1].wa_Lock)))
  432.          {
  433.             struct DiskObject *prj;
  434.  
  435.             CurrentDir(new2);
  436.  
  437.             UnLock(new);
  438.             new = new2;
  439.  
  440.             strcpy(work_name,wbarg[1].wa_Name);
  441.  
  442.             if((prj = GetDiskObjectNew(work_name)))
  443.                if(prj->do_Type == WBPROJECT)
  444.                {
  445.                   BPTR test;
  446.  
  447.                   /* if this is only an icon skip it */
  448.                   if(!(test = Lock(work_name, SHARED_LOCK)))
  449.                   {
  450.                      wbarg++;
  451.                      num--;
  452.                   } else
  453.                     UnLock(test);
  454.  
  455.                   if(dob)
  456.                      FreeDiskObject(dob);
  457.  
  458.                   dob = prj;
  459.  
  460.                }
  461.          }
  462.       }
  463.  
  464.       if(dob)
  465.          D(bug("dobj window : %s\n",dob->do_ToolWindow));
  466.  
  467.       /* go back to where we used to be */
  468.       CurrentDir (old);
  469.  
  470.       /* release the duplicated lock */
  471.       UnLock(new);   
  472.  
  473.       args->erda_WBArg   = wbarg + 1;
  474.       args->erda_NumArgs = num;
  475.    }
  476.  
  477.    return (dob);
  478. }
  479.  
  480. static void fstrcpy(struct ExtRDArgs *args,STRPTR string)
  481. {
  482.    STRPTR ptr = args->erda_ActualPtr;
  483.    STRPTR end = args->erda_EndPtr;
  484.  
  485.    while(ptr < end && *string)
  486.       *ptr++= *string++;
  487.  
  488.    args->erda_ActualPtr = ptr;
  489. }
  490.  
  491. static void getargname(struct ExtRDArgs *args,STRPTR buffer,ULONG size,ULONG *modes)
  492. {
  493.    ULONG num = args->erda_FileParameter;
  494.    STRPTR ptr = args->erda_Template;
  495.  
  496.    *modes = 0;
  497.  
  498.    while(num > 0)
  499.    {
  500.       while(*ptr != ',' && *ptr != EOS)
  501.          ptr++;
  502.  
  503.       if(*ptr == ',')
  504.          ptr++;
  505.       num--;
  506.    }
  507.  
  508.    if(*ptr != EOS)
  509.    {
  510.       while(*ptr != ',' && *ptr != '/' && *ptr != EOS && size > 0)
  511.       {
  512.          *buffer++ = *ptr++;
  513.          size--;
  514.       }
  515.  
  516.       while(*ptr == '/')
  517.       {
  518.          ptr++;
  519.  
  520.          if(*ptr == 'M' || *ptr == 'm')
  521.             *modes = MODE_MULTI;
  522.  
  523.          ptr++;
  524.       }
  525.    }
  526.  
  527.    *buffer = EOS;
  528. }
  529.  
  530. static void getwbargname(struct WBArg *wbarg,STRPTR buffer,ULONG size)
  531. {
  532.    BPTR new;
  533.  
  534.    if((new = DupLock (wbarg->wa_Lock)))
  535.    {
  536.       if(!NameFromLock(new,buffer,size))
  537.          *buffer = EOS;
  538.       else if(!AddPart(buffer,wbarg->wa_Name,size))
  539.          *buffer = EOS;
  540.  
  541.       UnLock(new);
  542.    } else
  543.       *buffer = EOS;
  544. }
  545.  
  546.