home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 8 Other / 08-Other.zip / casprep.zip / CASPREP.CMD
OS/2 REXX Batch file  |  1993-05-11  |  94KB  |  1,843 lines

  1. /********************************************************************/
  2. /* This exec will merge the base and user created pieces of the     */
  3. /* LCU.CMD file into the final .CMD file.                           */
  4. /*                                                                  */
  5. /* This exec reads into a stem variable a user defined input file   */
  6. /* and a base file. These 2 files are merged into an output file    */
  7. /* which is a command file used by LCU to install products on a     */
  8. /* client machine.                                                  */
  9. /*                                                                  */
  10. /* The user defined file is read from the stem variable that it is  */
  11. /* contained in and each line is parsed to get the information      */
  12. /* needed to build the output file. 2 types of input files are      */
  13. /* handled by this exec; the basic and the advanced input files.    */
  14. /* These are defined in the LCU user's guide.                       */
  15. /*                                                                  */
  16. /* Following are the structures that are used when parsing the      */
  17. /* input file and building the output file:                         */
  18. /*                                                                  */
  19. /* - prod_cnt    - util_cnt    - elem_cnt   - vars_cnt              */
  20. /*|             |             |            |                        */
  21. /*|             |             |            |                        */
  22. /*| Product     | Utility     |  Queue     |  Vars                  */
  23. /*V ---------   V ---------   V ---------  V ---------              */
  24. /* |prog.name|   |prog.name|   |Prod 1   | 1|Var 1    |             */
  25. /*P|---------|  U|---------|  e|---------|  |---------|             */
  26. /*r|user_name|  t|user_name|  l|Prod 2   | 2|Var 2    |             */
  27. /*o|---------|  i|---------|  e|---------|  |---------|             */
  28. /*d|invoke   |  l|invoke   |  m|Prod 3   | 3|Var 3    |             */
  29. /* |---------|   |---------|   |---------|  |---------|             */
  30. /*1|rspdir   |  1|rspdir   |  1|Prod 4   | 4|Var 4    |             */
  31. /* |---------|   |---------|   |---------|  |---------|             */
  32. /* |default  |   |default  |   |Srvattch |  /         /             */
  33. /* |---------|   |---------|   |---------|  /         /             */
  34. /* /         /   /         /   /         / n|Var n    |             */
  35. /* /         /   /         /   /         /  |---------|             */
  36. /* |prog.name|   |prog.name|   |Prod 1   |                          */
  37. /*p|---------|  U|---------|  e|---------|                          */
  38. /*r|user_name|  t|user_name|  l|Prod 2   |                          */
  39. /*o|---------|  i|---------|  e|---------|                          */
  40. /*d|invoke   |  l|invoke   |  m|Prod 3   |                          */
  41. /* |---------|   |---------|   |---------|                          */
  42. /*n|rspdir   |  n|rspdir   |  n|Srvattch |                          */
  43. /* |---------|   |---------|    ---------                           */
  44. /* |default  |   |default  |                                        */
  45. /*  ---------     ---------                                         */
  46. /*                                                                  */
  47. /*                                                                  */
  48. /********************************************************************/
  49. /*                                                                  */
  50. /*  Internal Subroutines                                            */
  51. /*                                                                  */
  52. /********************************************************************/
  53. /*                                                                  */
  54. /*                                                                  */
  55. /*  fix_quotes: procedure                                           */
  56. /*  remove_comments: procedure                                      */
  57. /*  bump_inc: procedure                                             */
  58. /*  help: procedure                                                 */
  59. /*                                                                  */
  60. /********************************************************************/
  61.  
  62.   /********************************************************************/
  63.   /*                                                                  */
  64.   /* Parse the input parameters - The user can specify the user       */
  65.   /* defined file, the output file, and the base file to be used      */
  66.   /* by the preprocessor.                                             */
  67.   /*                                                                  */
  68.   /********************************************************************/
  69.  
  70.   parse upper value arg(1) with infn '.' infext outfn '.' outfext basefn '.' basefext
  71.  
  72.   /********************************************************************/
  73.   /*                                                                  */
  74.   /* Fill in the defaults if variables are blank                      */
  75.   /*                                                                  */
  76.   /********************************************************************/
  77.  
  78.   if infn = '' | infn = '?' then            /* If the input file name */
  79.      do                                     /* is blank or ? then     */
  80.        call help                            /* call help              */
  81.        return (1)
  82.      end
  83.  
  84.   if outfn = '' then                        /* If the output file     */
  85.      do                                     /* name is blank then     */
  86.        call help                            /* call help              */
  87.        return (1)
  88.      end
  89.   if basefn = '' then basefn = 'CASBASE'    /* Base file name         */
  90.   if basefext = '' then basefext = 'FIL'    /* Base file type         */
  91.  
  92.   /********************************************************************/
  93.   /*                                                                  */
  94.   /* Get the base part of the LCU.CMD file and store in an stem       */
  95.   /*                                                                  */
  96.   /********************************************************************/
  97.  
  98.   inputfile = basefn||'.'||basefext
  99.   line_ctr = 1
  100.  
  101.   /********************************************************************/
  102.   /*                                                                  */
  103.   /* See if the base file exists. If not display error.               */
  104.   /*                                                                  */
  105.   /********************************************************************/
  106.  
  107.  if stream(inputfile,'c','query exists') <> '' then
  108.    do while lines(inputfile) > 0
  109.      base_cmd.data.line_ctr = linein(inputfile)
  110.      line_ctr = line_ctr + 1
  111.    end
  112.    else do
  113.      say "Error - Base file " inputfile " not found."
  114.      return (1)
  115.    end
  116.   base_cmd.data.0 = line_ctr - 1
  117.  
  118.   /********************************************************************/
  119.   /*                                                                  */
  120.   /* Get the user part of the LCU.CMD file and store in an array      */
  121.   /*                                                                  */
  122.   /********************************************************************/
  123.  
  124.   inputfile = infn||'.'||infext
  125.   say "Reading input file " infn||'.'infext
  126.   line_ctr = 1
  127.  
  128.   /********************************************************************/
  129.   /*                                                                  */
  130.   /* See if the input file exists. If not display error.              */
  131.   /*                                                                  */
  132.   /********************************************************************/
  133.  
  134.   if stream(inputfile,'c','query exists') <> '' then
  135.     do while lines(inputfile) > 0
  136.       client_cmd.data.line_ctr = linein(inputfile)
  137.       line_ctr = line_ctr + 1
  138.     end
  139.     else do
  140.       say "Error - Input file " inputfile " not found."
  141.       return (1)
  142.     end
  143.   client_cmd.data.0 = line_ctr - 1
  144.   say 'Processing' inputfile
  145.  
  146.   /********************************************************************/
  147.   /*                                                                  */
  148.   /* Start reading the client CMD file, parse the data and update     */
  149.   /* the appropriate variables.                                       */
  150.   /*                                                                  */
  151.   /********************************************************************/
  152.  
  153.   var_cnt = 1          /* Variable counter                            */
  154.   prod_cnt=1           /* product counter                             */
  155.   util_cnt=1           /* utility counter                             */
  156.   srvatt_cnt=1         /* SRVATTACH counter                           */
  157.   queue_cnt = 1        /* Queue counter                               */
  158.   element = 1          /* Queue element counter                       */
  159.   user_cnt = 1         /* user line counter                           */
  160.   name_inc = 1         /* used to create a unique name                */
  161.   srvattch_cnt = 1     /* srvattch counter                            */
  162.   que_srvattch_cnt = 1 /* install queue srvattch counter              */
  163.   TRUE = 1             /* true constant                               */
  164.   FALSE = 0             /* false constant                              */
  165.   NOPLUS = FALSE       /* no plus found flag                          */
  166.  
  167.   /********************************************************************/
  168.   /*                                                                  */
  169.   /* Process each line of the user defined file. Remove any comments  */
  170.   /* and search for keywords.                                         */
  171.   /*                                                                  */
  172.   /********************************************************************/
  173.  
  174.   do client_i = 1 to client_cmd.data.0
  175.     client_cmd.data.client_i = remove_comments(client_cmd.data.client_i)
  176.     keyword_id = pos(':',strip(client_cmd.data.client_i))
  177.     if keyword_id = 1 then do
  178.       parse value client_cmd.data.client_i with keyword arg1
  179.       select
  180.  
  181.   /********************************************************************/
  182.   /*                                                                  */
  183.   /* Process :VARS keyword                                            */
  184.   /* Remove any comments parse the line into the variable and the     */
  185.   /* variable assignment. Fix the quotes to not be around any         */
  186.   /* variables. Store the variable away until the final file is built.*/
  187.   /* Add the configsys variable which is needed in every output file. */
  188.   /*                                                                  */
  189.   /********************************************************************/
  190.  
  191.         when translate(keyword) = ':VARS'
  192.           then do
  193.             call bump_inc
  194.             do while translate(client_cmd.data.client_i) <> ":ENDVARS"
  195.            /* call remove_comments(client_cmd.data.client_i) */
  196.               vars.var_cnt = client_cmd.data.client_i
  197.               parse var client_cmd.data.client_i variable '=' assignment
  198.               variable = strip(variable)
  199.               if translate(variable) = "EXEPATH" then
  200.                 exepath_done = 1
  201.               if translate(variable) = "BOOTDRIVE" then
  202.                 bootdrive_done = 1
  203.               assignment = strip(assignment)
  204.               assignment = fix_quotes(assignment)
  205.               vars.var_cnt = variable '=' assignment
  206.               call bump_inc
  207.               if client_cmd.data.client_i = '' then call bump_inc
  208.               var_cnt = var_cnt + 1
  209.             end
  210.             vars.var_cnt = "configsys = bootdrive || ""\CONFIG.SYS"""
  211.             if bootdrive_done <> 1
  212.               then do
  213.                 say "Error - BOOTDRIVE variable not defined."
  214.               end
  215.             if exepath_done <> 1
  216.               then do
  217.                 say "Error - EXEPATH variable not defined."
  218.               end
  219.             if exepath_done <> 1 | bootdrive_done <> 1
  220.               then return (1)
  221.           end
  222.  
  223.   /********************************************************************/
  224.   /*                                                                  */
  225.   /* Process :SRVATTCH keyword                                        */
  226.   /* Remove any comments. Fix the quotes to not be around any         */
  227.   /* variables. Store the SRVATTCH away until the final file is built.*/
  228.   /*                                                                  */
  229.   /********************************************************************/
  230.  
  231.         when translate(keyword) = ':SRVATTCH'
  232.           then do
  233.             call bump_inc
  234.             do while translate(client_cmd.data.client_i) <> ":ENDSRVATTCH"
  235.           /*  call remove_comments(client_cmd.data.client_i) */
  236.               srvattch.srvatt_cnt = client_cmd.data.client_i
  237.               srvattch.srvatt_cnt = fix_quotes(srvattch.srvatt_cnt)
  238.               srvatt_cnt = srvatt_cnt + 1
  239.               call bump_inc
  240.               if client_cmd.data.client_i = '' then call bump_inc
  241.             end
  242.           end
  243.  
  244.   /********************************************************************/
  245.   /*                                                                  */
  246.   /* Process :PROG keyword                                            */
  247.   /* Parse the line to get the keyword and the argument. Remove       */
  248.   /* any blanks around the keyword and the argument. Processing       */
  249.   /* continues until :ENDPROG is found.                               */
  250.   /*                                                                  */
  251.   /********************************************************************/
  252.  
  253.         when translate(keyword) = ':PROG'
  254.           then do
  255.             if symbol('prog_name.arg1') = 'LIT'
  256.               then do
  257.                 product.prod_cnt.prog_name = arg1
  258.                 call bump_inc
  259.                 prog_name.arg1 = arg1
  260.               end
  261.               else do
  262.                 say "Error - Duplicate Prog name was found ("arg1") line number " client_i
  263.                 return (1)
  264.               end
  265.             do while translate(client_cmd.data.client_i) <> ":ENDPROG"
  266.               parse value client_cmd.data.client_i with keyword '=' arg1
  267.               keyword=strip(keyword)
  268.               arg1=strip(arg1)
  269.               select
  270.  
  271.   /********************************************************************/
  272.   /*                                                                  */
  273.   /* Process :NAME keyword                                            */
  274.   /* Check to see if this name has been used before. If yes, tell the */
  275.   /* user this is a duplicate name. If no, store it away in the part  */
  276.   /* of the product array for this product. Also, put it in the names */
  277.   /* array so we know it has been used. Display message if duplicate  */
  278.   /* name is found.                                                   */
  279.   /*                                                                  */
  280.   /********************************************************************/
  281.  
  282.                 when translate(keyword) = 'NAME'
  283.                   then do
  284.                     if symbol('names.arg1') = 'LIT'
  285.                       then do
  286.                         product.prod_cnt.name = arg1
  287.                         call bump_inc
  288.                         names.arg1 = arg1
  289.                       end
  290.                       else do
  291.                         say "Error - Duplicate Product name was found ("arg1") line number " client_i
  292.                         return (1)
  293.                       end
  294.                   end
  295.  
  296.   /********************************************************************/
  297.   /*                                                                  */
  298.   /* Process :INVOKE keyword                                          */
  299.   /* Fix the quotes around any variables. Check to see if the argument*/
  300.   /* spans more than 1 line. If yes, process the lines until next     */
  301.   /* keyword. Store it away in the part of the product array for this */
  302.   /* product. The Invoke keyword may span more than one line so each  */
  303.   /* line is store in a seperate element of the invoke array.         */
  304.   /* invoke_cnt is the count of the invoke array. Each element in the */
  305.   /* array has the leading and traing blanks removed and has the      */
  306.   /* quotes changed from denoting the variable (input file form)      */
  307.   /* to denoting the string (REXX form).                              */
  308.   /*                                                                  */
  309.   /********************************************************************/
  310.  
  311.                 when translate(keyword) = 'INVOKE'
  312.                   then do
  313.                     product.prod_cnt.invoke.1 = arg1
  314.                     product.prod_cnt.invoke.1 = fix_quotes(product.prod_cnt.invoke.1)
  315.                     invoke_cnt = 2
  316.                     call bump_inc
  317.                     call find_keyword
  318.                     do while result <> 1 &,
  319.                         substr(strip(client_cmd.data.client_i),1,1) <> ":"
  320.                       product.prod_cnt.invoke.invoke_cnt = strip(client_cmd.data.client_i)
  321.                       product.prod_cnt.invoke.invoke_cnt = fix_quotes(product.prod_cnt.invoke.invoke_cnt)
  322.                       invoke_cnt = invoke_cnt + 1
  323.                       call bump_inc
  324.                       if client_cmd.data.client_i = ''
  325.                         then do
  326.                           call bump_inc
  327.                           call find_keyword
  328.                         end
  329.                         else do
  330.                         call find_keyword
  331.                         end
  332.                     end
  333.                   end
  334.  
  335.   /********************************************************************/
  336.   /*                                                                  */
  337.   /* Process :RSPDIR keyword                                          */
  338.   /* Fix the quotes around any variables. Store it away in the part   */
  339.   /* of the product array for this product.                           */
  340.   /*                                                                  */
  341.   /********************************************************************/
  342.  
  343.                 when translate(keyword) = 'RSPDIR'
  344.                   then do
  345.                     if strip(arg1,b,'"') <> "" & strip(arg1,b,"'") <> ""
  346.                       then do
  347.                         arg1 = fix_quotes(arg1)
  348.                         product.prod_cnt.rspdir = arg1
  349.                         call bump_inc
  350.                       end
  351.                       else call bump_inc
  352.                   end
  353.  
  354.   /********************************************************************/
  355.   /*                                                                  */
  356.   /* Process :DEFAULT keyword                                         */
  357.   /* Fix the quotes around any variables. Store it away in the part   */
  358.   /* of the product array for this product.                           */
  359.   /*                                                                  */
  360.   /********************************************************************/
  361.  
  362.                 when translate(keyword) = 'DEFAULT'
  363.                   then do
  364.                     if strip(arg1,b,'"') <> "" & strip(arg1,b,"'") <> ""
  365.                       then do
  366.                         arg1 = fix_quotes(arg1)
  367.                         product.prod_cnt.default = arg1
  368.                         call bump_inc
  369.                       end
  370.                       else call bump_inc
  371.                   end
  372.  
  373.   /********************************************************************/
  374.   /*                                                                  */
  375.   /* If this line is blank skip over it.                              */
  376.   /*                                                                  */
  377.   /********************************************************************/
  378.  
  379.                 when translate(keyword) = ''
  380.                   then do
  381.                     call bump_inc
  382.                   end
  383.  
  384.   /********************************************************************/
  385.   /*                                                                  */
  386.   /* If the keyword is invalid tell the user.                         */
  387.   /*                                                                  */
  388.   /********************************************************************/
  389.  
  390.                 otherwise
  391.                   say "Error - Found invalid keyword in :PROG list ("keyword") line number" client_i
  392.                   return (1)
  393.               end
  394.             end
  395.  
  396.   /********************************************************************/
  397.   /*                                                                  */
  398.   /* This product is complete so start a new product definition.      */
  399.   /*                                                                  */
  400.   /********************************************************************/
  401.  
  402.             prod_cnt = prod_cnt + 1
  403.           end
  404.  
  405.   /********************************************************************/
  406.   /*                                                                  */
  407.   /* Process :UTILITY keyword                                         */
  408.   /* Parse the line to get the keyword and the argument. Remove       */
  409.   /* any blanks around the keyword and the argument. Processing       */
  410.   /* continues until :ENDUTILITY is found.                            */
  411.   /*                                                                  */
  412.   /********************************************************************/
  413.  
  414.         when translate(keyword) = ':UTILITY'
  415.           then do
  416.             if symbol('prog_name.arg1') = 'LIT'
  417.               then do
  418.                 utility.util_cnt.util_name = arg1
  419.                 call bump_inc
  420.                 prog_name.arg1 = arg1
  421.               end
  422.               else do
  423.                 say "Error - Duplicate Utility name was found ("arg1") line number " client_i
  424.                 return (1)
  425.               end
  426.             do while translate(client_cmd.data.client_i) <> ":ENDUTILITY"
  427.               parse value client_cmd.data.client_i with keyword '=' arg1
  428.               keyword = strip(keyword)
  429.               arg1 = strip(arg1)
  430.               select
  431.  
  432.   /********************************************************************/
  433.   /*                                                                  */
  434.   /* Process :NAME keyword                                            */
  435.   /* Check to see if this name has been used before. If yes, tell the */
  436.   /* user this is a duplicate name. If no, store it away in the part  */
  437.   /* of the utility array for this utility. Also, put it in the names */
  438.   /* array so we know it has been used. Display message if duplicate  */
  439.   /* name is found.                                                   */
  440.   /*                                                                  */
  441.   /********************************************************************/
  442.  
  443.                 when translate(keyword) = 'NAME'
  444.                   then do
  445.                     if symbol('names.arg1') = 'LIT'
  446.                       then do
  447.                         utility.util_cnt.name = arg1
  448.                         call bump_inc
  449.                         names.arg1 = arg1
  450.                       end
  451.                       else do
  452.                         say "Error - Duplicate Utility name was found ("arg1") line number " client_i
  453.                         return (1)
  454.                       end
  455.                   end
  456.  
  457.   /********************************************************************/
  458.   /*                                                                  */
  459.   /* Process :INVOKE keyword                                          */
  460.   /* Fix the quotes around any variables. Check to see if the argument*/
  461.   /* spans more than 1 line. If yes, process the lines until next     */
  462.   /* keyword. Store it away in the part of the utility array for this */
  463.   /* utility. The Invoke keyword may span more than one line so each  */
  464.   /* line is store in a seperate element of the invoke array.         */
  465.   /* invoke_cnt is the count of the invoke array. Each element in the */
  466.   /* array has the leading and traing blanks removed and has the      */
  467.   /* quotes changed from denoting the variable (input file form)      */
  468.   /* to denoting the string (REXX form).                              */
  469.   /*                                                                  */
  470.   /********************************************************************/
  471.  
  472.                 when translate(keyword) = 'INVOKE'
  473.                   then do
  474.                     utility.util_cnt.invoke.1 = arg1
  475.                     utility.util_cnt.invoke.1 = fix_quotes(utility.util_cnt.invoke.1)
  476.                     invoke_cnt = 2
  477.                     call bump_inc
  478.                     call find_keyword
  479.                     do while result <> 1 &,
  480.                         substr(strip(client_cmd.data.client_i),1,1) <> ":"
  481.                       utility.util_cnt.invoke.invoke_cnt = strip(client_cmd.data.client_i)
  482.                       utility.util_cnt.invoke.invoke_cnt = fix_quotes(utility.util_cnt.invoke.invoke_cnt)
  483.                       invoke_cnt = invoke_cnt + 1
  484.                       call bump_inc
  485.                       if client_cmd.data.client_i = ''
  486.                         then do
  487.                           call bump_inc
  488.                           call find_keyword
  489.                         end
  490.                         else do
  491.                         call find_keyword
  492.                         end
  493.                     end
  494.                   end
  495.  
  496.   /********************************************************************/
  497.   /*                                                                  */
  498.   /* Process :RSPDIR keyword                                          */
  499.   /* Fix the quotes around any variables. Store it away in the part   */
  500.   /* of the utility array for this utility.                           */
  501.   /*                                                                  */
  502.   /********************************************************************/
  503.  
  504.                 when translate(keyword) = 'RSPDIR'
  505.                   then do
  506.                     if strip(arg1,b,'"') <> "" & strip(arg1,b,"'") <> ""
  507.                       then do
  508.                         arg1 = fix_quotes(arg1)
  509.                         utility.util_cnt.rspdir = arg1
  510.                         call bump_inc
  511.                       end
  512.                       else call bump_inc
  513.                   end
  514.  
  515.   /********************************************************************/
  516.   /*                                                                  */
  517.   /* Process :DEFAULT keyword                                         */
  518.   /* Fix the quotes around any variables. Store it away in the part   */
  519.   /* of the utility array for this utility.                           */
  520.   /*                                                                  */
  521.   /********************************************************************/
  522.  
  523.                 when translate(keyword) = 'DEFAULT'
  524.                   then do
  525.                     if strip(arg1,b,'"') <> "" & strip(arg1,b,"'") <> ""
  526.                       then do
  527.                         arg1 = fix_quotes(arg1)
  528.                         utility.util_cnt.default = arg1
  529.                         call bump_inc
  530.                       end
  531.                       else call bump_inc
  532.                   end
  533.  
  534.   /********************************************************************/
  535.   /*                                                                  */
  536.   /* If this line is blank skip over it.                              */
  537.   /*                                                                  */
  538.   /********************************************************************/
  539.  
  540.                 when translate(keyword) = ''
  541.                   then do
  542.                     call bump_inc
  543.                   end
  544.  
  545.   /********************************************************************/
  546.   /*                                                                  */
  547.   /* If the keyword is invalid tell the user.                         */
  548.   /*                                                                  */
  549.   /********************************************************************/
  550.  
  551.                 otherwise do
  552.                   say "Error - Found invalid keyword in :UTILITY list ("keyword") line number " client_i
  553.                   return (1)
  554.                 end  /* end otherwise */
  555.               end  /* end select */
  556.             end  /* end do while */
  557.  
  558.   /********************************************************************/
  559.   /*                                                                  */
  560.   /* This utility is complete so start a new utility definition.      */
  561.   /*                                                                  */
  562.   /********************************************************************/
  563.  
  564.             util_cnt = util_cnt + 1
  565.           end  /* end do for utility */
  566.  
  567.   /********************************************************************/
  568.   /*                                                                  */
  569.   /* Process :INSTALL keyword                                         */
  570.   /* There are 2 types of installs. The first has KEYWORDS as a       */
  571.   /* parameter. It is used in the advanced form of input file. The    */
  572.   /* second type does not have any parameters. It is used for the     */
  573.   /* basic input file. Processing for both continues until :ENDINSTALL*/
  574.   /* is found.                                                        */
  575.   /*                                                                  */
  576.   /********************************************************************/
  577.  
  578.         when translate(keyword) = ':INSTALL'
  579.           then do
  580.             start_pars = 1
  581.  
  582.   /********************************************************************/
  583.   /*                                                                  */
  584.   /* Process :INSTALL KEYWORDS                                        */
  585.   /*                                                                  */
  586.   /* Process until :ENDINSTALL is found. Parse the line into keyword  */
  587.   /* and arg1. Strip leading and trailing blanks from the keyword and */
  588.   /* arg1.                                                            */
  589.   /*                                                                  */
  590.   /********************************************************************/
  591.  
  592.             if translate(arg1) = 'KEYWORDS'
  593.               then do
  594.                 call bump_inc
  595.                 do while translate(client_cmd.data.client_i) <> ":ENDINSTALL"
  596.                   parse value client_cmd.data.client_i with,
  597.                        keyword '=' arg1
  598.                   keyword = strip(keyword)
  599.                   arg1 = strip(arg1)
  600.  
  601.                   select
  602.  
  603.   /********************************************************************/
  604.   /*                                                                  */
  605.   /* The following code processes a SRVATTCH=. A SRVATTCH= will       */
  606.   /* insert a SRVATTCH statement in a "When OVERALL STATE" sequence.  */
  607.   /* It will not be placed in a runinstall statement. It will be      */
  608.   /* place in the CMD file just as it is in the advanced text         */
  609.   /* file; quotes will not be adjusted.                               */
  610.   /*                                                                  */
  611.   /********************************************************************/
  612.  
  613.                     when translate(keyword) = 'SRVATTCH'
  614.                       then do
  615.                         queue.queue_cnt.element = client_cmd.data.client_i
  616.                         nextline = client_i + 1
  617.                         if pos('+', client_cmd.data.nextline) = 0 then do
  618.                           queue_cnt= queue_cnt + 1
  619.                           element = 1
  620.                         end
  621.                         else element = element + 1
  622.                         call bump_inc
  623.                       end
  624.  
  625.   /********************************************************************/
  626.   /*                                                                  */
  627.   /* The following code processes a USERLINE=. A USERLINE= will       */
  628.   /* insert a line in a "When OVERALL STATE" sequence. It will not    */
  629.   /* be placed in a runinstall statement. It will be place in the     */
  630.   /* CMD file just as it is in the advanced text file; quotes will    */
  631.   /* not be adjusted.                                                 */
  632.   /*                                                                  */
  633.   /********************************************************************/
  634.  
  635.                     when translate(keyword) = 'USERLINE'
  636.                       then do
  637.                             queue.queue_cnt.element = client_cmd.data.client_i
  638.                             nextline = client_i + 1
  639.                             if pos('+', client_cmd.data.nextline) = 0
  640.                               then do
  641.                                 queue_cnt= queue_cnt + 1
  642.                                 element = 1
  643.                               end
  644.                             else element = element + 1
  645.                             call bump_inc
  646.                       end
  647.  
  648.                     otherwise do
  649.  
  650.   /********************************************************************/
  651.   /*                                                                  */
  652.   /* The following code will parse the program install statements.    */
  653.   /*                                                                  */
  654.   /********************************************************************/
  655.  
  656.                       do until NOPLUS = TRUE
  657.                         select
  658.                           when client_cmd.data.client_i = "" then
  659.                              call bump_inc
  660.  
  661.   /********************************************************************/
  662.   /*                                                                  */
  663.   /* The following code will look for any statements that end in a +. */
  664.   /* If the statement is only a plus bump to the next line in the     */
  665.   /* CMD file. Or else take off any leading and trailing +s and       */
  666.   /* parse the string. Put the product names in the queue to be       */
  667.   /* processed later.                                                 */
  668.   /*                                                                  */
  669.   /********************************************************************/
  670.  
  671.                           when lastpos('+', strip(client_cmd.data.client_i)) =,
  672.                                length(strip(client_cmd.data.client_i)) then do
  673.                             if substr(strip(client_cmd.data.client_i),1) = '+' &,
  674.                                length(strip(client_cmd.data.client_i)) = 1
  675.                                  then call bump_inc
  676.                             else do
  677.                               client_data = strip(strip(client_cmd.data.client_i),'L','+')
  678.                               client_data = strip(client_data,'T','+')
  679.                               last_plus = lastpos('+', client_data)
  680.                               if last_plus = 0 then do
  681.                                 queue.queue_cnt.element = client_data
  682.                                 call bump_inc
  683.                                 element = element + 1
  684.                               end
  685.                               else do
  686.                                 start_pars = 1
  687.  
  688.   /********************************************************************/
  689.   /*                                                                  */
  690.   /* The following code loops through the install statement and       */
  691.   /* puts the product names in the product queue.                     */
  692.   /*                                                                  */
  693.   /********************************************************************/
  694.  
  695.                                 do until separator = last_plus
  696.                                   separator = pos('+',client_data,start_pars)
  697.                                     queue.queue_cnt.element =,
  698.                                         substr(client_data,start_pars,,
  699.                                         separator-start_pars)
  700.                                     start_pars = separator
  701.                                     start_pars = start_pars + 1
  702.                                     element = element + 1
  703.                                 end
  704.  
  705.   /********************************************************************/
  706.   /*                                                                  */
  707.   /* Save the last product name from the previous loop.               */
  708.   /*                                                                  */
  709.   /********************************************************************/
  710.  
  711.                                 queue.queue_cnt.element =,
  712.                                   substr(client_data,start_pars)
  713.                                 element = element + 1
  714.                                 call bump_inc
  715.                               end
  716.                             end
  717.                           end
  718.  
  719.   /********************************************************************/
  720.   /*                                                                  */
  721.   /* The following code handles an install statement that has only    */
  722.   /* one product in it.                                               */
  723.   /*                                                                  */
  724.   /********************************************************************/
  725.  
  726.                           when lastpos('+', strip(client_cmd.data.client_i)) = 0,
  727.                               then do
  728.                             nextline = client_i + 1
  729.                             if substr(strip(client_cmd.data.nextline),1,1) = "+"
  730.                                 then do
  731.                               queue.queue_cnt.element = client_cmd.data.client_i
  732.                               call bump_inc
  733.                               element = element + 1
  734.                             end
  735.                             else do
  736.                               queue.queue_cnt.element = client_cmd.data.client_i
  737.                               call bump_inc
  738.                               queue_cnt = queue_cnt + 1
  739.                               element = 1
  740.                               NOPLUS = TRUE
  741.                             end
  742.                           end
  743.  
  744.   /********************************************************************/
  745.   /*                                                                  */
  746.   /* The following code handles an install statement that a plus at   */
  747.   /* the beginning of it.                                             */
  748.   /*                                                                  */
  749.   /********************************************************************/
  750.  
  751.                           when pos('+', strip(client_cmd.data.client_i)) = 1,
  752.                               then do
  753.                             client_data = strip(strip(client_cmd.data.client_i),'L','+')
  754.  
  755.   /********************************************************************/
  756.   /*                                                                  */
  757.   /* If there was only one plus then store the product name and       */
  758.   /* go to the next line.                                             */
  759.   /*                                                                  */
  760.   /********************************************************************/
  761.  
  762.                             last_plus = lastpos('+', client_data)
  763.                             if last_plus = 0 then do
  764.                               queue.queue_cnt.element = client_data
  765.                               call bump_inc
  766.                               element = element + 1
  767.                             end
  768.                             else do
  769.  
  770.   /********************************************************************/
  771.   /*                                                                  */
  772.   /* Loop through the install statement and store the product names   */
  773.   /* in the queue.                                                    */
  774.   /*                                                                  */
  775.   /********************************************************************/
  776.  
  777.                               start_pars = 1
  778.                               do until separator = last_plus
  779.                                 separator = pos('+',client_data,start_pars)
  780.                                   queue.queue_cnt.element =,
  781.                                       substr(client_data,start_pars,,
  782.                                       separator-start_pars)
  783.                                   start_pars = separator
  784.                                   start_pars = start_pars + 1
  785.                                   element = element + 1
  786.                               end
  787.  
  788.   /********************************************************************/
  789.   /*                                                                  */
  790.   /* Store the last name from the previous loop.                      */
  791.   /*                                                                  */
  792.   /********************************************************************/
  793.  
  794.                               queue.queue_cnt.element =,
  795.                                   substr(client_data,start_pars)
  796.                               nextline = client_i + 1
  797.                               if substr(strip(client_cmd.data.nextline),1,1) = "+"
  798.                                   then do
  799.                                 call bump_inc
  800.                                 element = element + 1
  801.                               end
  802.                               else do
  803.                                 call bump_inc
  804.                                 queue_cnt = queue_cnt + 1
  805.                                 element = 1
  806.                                 NOPLUS = TRUE
  807.                               end
  808.                             end
  809.                           end
  810.  
  811.   /********************************************************************/
  812.   /*                                                                  */
  813.   /* The following code handles a statement that does not have a + at */
  814.   /* either end of an install statement.                              */
  815.   /*                                                                  */
  816.   /********************************************************************/
  817.  
  818.                           otherwise do
  819.  
  820.                             last_plus = lastpos('+', client_cmd.data.client_i)
  821.                             start_pars = 1
  822.  
  823.   /********************************************************************/
  824.   /*                                                                  */
  825.   /* Loop through the install statement and store the product names   */
  826.   /* in the queue.                                                    */
  827.   /*                                                                  */
  828.   /********************************************************************/
  829.  
  830.                             do until separator = last_plus
  831.                               separator = ,
  832.                                   pos('+',client_cmd.data.client_i,start_pars)
  833.                                 queue.queue_cnt.element =,
  834.                                     substr(client_cmd.data.client_i,start_pars,,
  835.                                     separator-start_pars)
  836.                                 start_pars = separator
  837.                                 start_pars = start_pars + 1
  838.                                 element = element + 1
  839.                             end
  840.   /********************************************************************/
  841.   /*                                                                  */
  842.   /* Store last product in queue element. Increment to the next line  */
  843.   /* to be read from the inout file, bump the queue count, and reset  */
  844.   /* the element count to 1.                                          */
  845.   /*                                                                  */
  846.   /********************************************************************/
  847.  
  848.                             queue.queue_cnt.element =,
  849.                                 substr(client_cmd.data.client_i,start_pars)
  850.                             call bump_inc
  851.                             queue_cnt = queue_cnt + 1
  852.                             element = 1
  853.  
  854.                             if substr(strip(client_cmd.data.client_i),1) = '+' &,
  855.                                length(strip(client_cmd.data.client_i)) = 1
  856.                                  then call bump_inc
  857.                             else NOPLUS = TRUE
  858.                           end
  859.                         end
  860.  
  861.                       end
  862.                     end  /* do until */
  863.                   end  /* end select */
  864.                 end  /* end for do while <> ENDINSTALL */
  865.               end  /* end for if KEYWORDS install */
  866.               else do
  867.  
  868.   /********************************************************************/
  869.   /*                                                                  */
  870.   /* Process :INSTALL (no keywords)                                   */
  871.   /*                                                                  */
  872.   /* Process until :ENDINSTALL is found. The Invoke keyword may span  */
  873.   /* more than one line so each line is stored in a separate element  */
  874.   /* of the invoke array. "invoke_cnt" is the count of the invoke     */
  875.   /* array. Each element in the array has the leading and trailing    */
  876.   /* blanks removed and has the quotes changed from denoting the      */
  877.   /* variable (input file form) to denoting the string (REXX form).   */
  878.   /*                                                                  */
  879.   /********************************************************************/
  880.  
  881.                 call bump_inc
  882.                 do while translate(client_cmd.data.client_i) <> ":ENDINSTALL"
  883.                   select
  884.                     when translate(client_cmd.data.client_i) = ""
  885.                       then do
  886.                          call bump_inc
  887.                       end
  888.  
  889.                     Otherwise do
  890.                       invoke_cnt = 1
  891.  
  892.   /********************************************************************/
  893.   /*                                                                  */
  894.   /* If this line does not have a + or a ++ at the end of the line    */
  895.   /* and the next line is not :ENDINSTALL then the invoke command     */
  896.   /* spans more than one line, process the invoke command until a +,  */
  897.   /* ++, or endinstall is found.                                      */
  898.   /*                                                                  */
  899.   /********************************************************************/
  900.  
  901.                       do until pos('++',client_cmd.data.prevline) <> 0 |,
  902.                                translate(strip(client_cmd.data.client_i)),
  903.                                = ":ENDINSTALL"
  904.                         select
  905.  
  906.   /********************************************************************/
  907.   /*                                                                  */
  908.   /* If this line is a USERLINE then add the line to the queue. If    */
  909.   /* the next line is a plus it belongs to this queue so increment    */
  910.   /* the element count and bump to the next line. If the next is a ++ */
  911.   /* then it is to be in a queue by itself. Increment to the          */
  912.   /* next queue and reset the element count to 1.                     */
  913.   /*                                                                  */
  914.   /********************************************************************/
  915.  
  916.                           when translate(substr(strip(client_cmd.data.client_i),1,8)),
  917.                                   = "USERLINE" then do
  918.                             queue.queue_cnt.element = client_cmd.data.client_i
  919.                             nextline = client_i + 1
  920.                             if pos('+', client_cmd.data.nextline) = 0 |,
  921.                                pos('++',client_cmd.data.nextline) <> 0
  922.                               then do
  923.                                 queue_cnt= queue_cnt + 1
  924.                                 element = 1
  925.                               end
  926.                             else element = element + 1
  927.                             call bump_inc
  928.                           end
  929.  
  930.   /********************************************************************/
  931.   /*                                                                  */
  932.   /* If this line is a SRVATTCH then add the line to the queue. If    */
  933.   /* the next line is a plus it belongs to this queue so increment    */
  934.   /* the element count and bump to the next line. If the next is a ++ */
  935.   /* then it is to be in a queue by itself. Increment to the          */
  936.   /* next queue and reset the element count to 1.                     */
  937.   /*                                                                  */
  938.   /********************************************************************/
  939.  
  940.                           when translate(substr(strip(client_cmd.data.client_i),1,8)),
  941.                                   = "SRVATTCH" then do
  942.  
  943.                             queue.queue_cnt.element = client_cmd.data.client_i
  944.                             nextline = client_i + 1
  945.                             if pos('+', client_cmd.data.nextline) = 0 |,
  946.                                pos('++',client_cmd.data.nextline) <> 0
  947.                               then do
  948.                                 queue_cnt= queue_cnt + 1
  949.                                 element = 1
  950.                               end
  951.                             else element = element + 1
  952.                             call bump_inc
  953.                           end
  954.  
  955.   /********************************************************************/
  956.   /*                                                                  */
  957.   /* When only a + on the line go to the next in the CMD file.        */
  958.   /*                                                                  */
  959.   /********************************************************************/
  960.  
  961.                           when length(strip(client_cmd.data.client_i))= 1 &,
  962.                                pos('+', client_cmd.data.nextline) <> 0
  963.                             then call bump_inc
  964.  
  965.   /********************************************************************/
  966.   /*                                                                  */
  967.   /* When only a ++ on the line go to the next in the CMD file.       */
  968.   /*                                                                  */
  969.   /********************************************************************/
  970.  
  971.                           when length(strip(client_cmd.data.client_i))= 2 &,
  972.                                pos('++', client_cmd.data.nextline) <> 0
  973.                             then call bump_inc
  974.  
  975.   /********************************************************************/
  976.   /*                                                                  */
  977.   /* The following code is to handle the invoke statement.            */
  978.   /*                                                                  */
  979.   /********************************************************************/
  980.  
  981.                           otherwise
  982.                             do until pos('+',client_cmd.data.client_i) <> 0 |,
  983.                                      pos('++',client_cmd.data.client_i) <> 0 |,
  984.                                      translate(strip(client_cmd.data.client_i)),
  985.                                      = ":ENDINSTALL"
  986.                                select
  987.  
  988.   /********************************************************************/
  989.   /*                                                                  */
  990.   /* if the line is blank then go to the next line in the CMD file.   */
  991.   /*                                                                  */
  992.   /********************************************************************/
  993.  
  994.                                  when translate(client_cmd.data.client_i) = ""
  995.                                    then call bump_inc
  996.  
  997.   /********************************************************************/
  998.   /*                                                                  */
  999.   /* Strip off the trailing + and any blanks, then store away this    */
  1000.   /* line of the invoke statement.                                    */
  1001.   /*                                                                  */
  1002.   /********************************************************************/
  1003.  
  1004.                                  otherwise
  1005.                                    product.prod_cnt.invoke.invoke_cnt =,
  1006.                                       strip(client_cmd.data.client_i,'t','+')
  1007.                                    product.prod_cnt.invoke.invoke_cnt =,
  1008.                                       strip(product.prod_cnt.invoke.invoke_cnt)
  1009.                                    product.prod_cnt.invoke.invoke_cnt =,
  1010.                                       fix_quotes(product.prod_cnt.invoke.invoke_cnt)
  1011.                                    invoke_cnt = invoke_cnt + 1
  1012.                                    call bump_inc
  1013.                                end
  1014.                             end
  1015.  
  1016.   /********************************************************************/
  1017.   /*                                                                  */
  1018.   /* If the next line is not an ENDINSTALL store it away else         */
  1019.   /* decrement the line count so we find the ENDINSTALL on the do     */
  1020.   /* loop                                                             */
  1021.   /*                                                                  */
  1022.   /********************************************************************/
  1023.  
  1024.                             if translate(strip(client_cmd.data.client_i)),
  1025.                                 <> ":ENDINSTALL"
  1026.                             then do
  1027.                               product.prod_cnt.invoke.invoke_cnt =,
  1028.                                  strip(client_cmd.data.client_i,'t','+')
  1029.                               product.prod_cnt.invoke.invoke_cnt =,
  1030.                                  strip(product.prod_cnt.invoke.invoke_cnt)
  1031.                               product.prod_cnt.invoke.invoke_cnt =,
  1032.                                  fix_quotes(product.prod_cnt.invoke.invoke_cnt)
  1033.                             end
  1034.  
  1035.                             else do
  1036.                               client_i = client_i - 1
  1037.                             end
  1038.  
  1039.   /********************************************************************/
  1040.   /*                                                                  */
  1041.   /* Parse out the name from the invoke string. The name will be      */
  1042.   /* between the last "/" and the first " " (blank).                  */
  1043.   /*                                                                  */
  1044.   /********************************************************************/
  1045.                             first_parm = pos(' ',product.prod_cnt.invoke.1)
  1046.                             instprog = strip(substr(product.prod_cnt.invoke.1,1,first_parm - 1))
  1047.                             start_prog = lastpos('\',instprog)
  1048.                             prod_name = strip(substr(instprog,start_prog + 1))
  1049.  
  1050.   /********************************************************************/
  1051.   /*                                                                  */
  1052.   /* If a product is to be invoked more than once each invocation     */
  1053.   /* must have a unique name. To make it unique a number is           */
  1054.   /* concatenated to the name. Check to see if the name is unique. If */
  1055.   /* it is store it away. If not increment the concatentaion number   */
  1056.   /* by 1, see if it has been used. If it has not been used           */
  1057.   /* concatenate it and store it away.                                */
  1058.   /*                                                                  */
  1059.   /********************************************************************/
  1060.  
  1061.                             if symbol('names.prod_name') = 'LIT'
  1062.                               then do
  1063.                                 names.prod_name = prod_name
  1064.                                 user_name = prod_name
  1065.                               end
  1066.                               else do
  1067.                                 name_inc = 1
  1068.                                 new_name = prod_name
  1069.                                 do until symbol('names.new_name') = 'LIT'
  1070.                                   new_name = prod_name||name_inc
  1071.                                   name_inc = name_inc + 1
  1072.                                 end
  1073.                                 user_name = new_name
  1074.                                 names.new_name = new_name
  1075.                                 prod_name = new_name
  1076.                               end
  1077.  
  1078.   /********************************************************************/
  1079.   /*                                                                  */
  1080.   /* If this line ends in ++ or the next line is :ENDINSTALL then     */
  1081.   /* this is the end of the queue, say so by setting end_queue = yes. */
  1082.   /* Store away the product information and bump the counters.        */
  1083.   /* Continue processing products for this queue.                     */
  1084.   /*                                                                  */
  1085.   /********************************************************************/
  1086.  
  1087.                             queue.queue_cnt.element = prod_name
  1088.                             product.prod_cnt.prog_name = prod_name
  1089.                             product.prod_cnt.name = user_name
  1090.                             element = element + 1
  1091.                             prod_cnt = prod_cnt + 1
  1092.                             invoke_cnt = 1
  1093.                             prevline = client_i
  1094.                             call bump_inc
  1095.  
  1096.                         end /* select  */
  1097.  
  1098.                       end /* end plusplus */
  1099.  
  1100.   /********************************************************************/
  1101.   /*                                                                  */
  1102.   /* Came to the end of the products for this queue. Reset counters   */
  1103.   /* and process the next queue if there is one.                      */
  1104.   /*                                                                  */
  1105.   /********************************************************************/
  1106.  
  1107.                       queue_cnt = queue_cnt + 1
  1108.                       element = 1
  1109.  
  1110.                     end /* end otherwise */
  1111.                   end /* end select */
  1112.                 end  /* end do while */
  1113.               end /* end else do for non keyword install */
  1114.           end /* end then for INSTALL keyword */
  1115.  
  1116.   /********************************************************************/
  1117.   /*                                                                  */
  1118.   /* If this line is blank skip over it.                              */
  1119.   /*                                                                  */
  1120.   /********************************************************************/
  1121.  
  1122.         when client_cmd.data.client_i = '' then NOP
  1123.  
  1124.         otherwise
  1125.  
  1126.   /********************************************************************/
  1127.   /*                                                                  */
  1128.   /* If the keyword is invalid tell the user.                         */
  1129.   /*                                                                  */
  1130.   /********************************************************************/
  1131.  
  1132.           say "Error - Found invalid :KEYWORD ("keyword") line number " client_i
  1133.           return (1)
  1134.       end /* end select */
  1135.     end /* end if */
  1136.   end /* end do while */
  1137.  
  1138.   /********************************************************************/
  1139.   /*                                                                  */
  1140.   /* The input file has been processed. Now we build the output file. */
  1141.   /* Read the bas file and store the lines from it into the output    */
  1142.   /* file.                                                            */
  1143.   /*                                                                  */
  1144.   /********************************************************************/
  1145.  
  1146.   castle_i = 1
  1147.  
  1148.   do base_i = 1 to base_cmd.data.0
  1149.     comment = substr(base_cmd.data.base_i,3,30)
  1150.     select
  1151.  
  1152.   /********************************************************************/
  1153.   /*                                                                  */
  1154.   /* Combined with system data, not used.                             */
  1155.   /*                                                                  */
  1156.   /********************************************************************/
  1157.  
  1158.       when translate(comment) = 'START VARS HERE'
  1159.         then do
  1160.           var_cnt = 1
  1161.           castle_cmd.data.castle_i = base_cmd.data.base_i
  1162.           castle_i = castle_i + 1
  1163.           castle_cmd.data.castle_i = ''
  1164.           castle_i = castle_i + 1
  1165.         end
  1166.  
  1167.   /********************************************************************/
  1168.   /*                                                                  */
  1169.   /* Insert the SRVATTCHes into the output file. Keep processing the  */
  1170.   /* srvattch array until a literal is found which means the end of   */
  1171.   /* the array.                                                       */
  1172.   /*                                                                  */
  1173.   /********************************************************************/
  1174.  
  1175.       when translate(comment) = 'START SRVATTACHES HERE'
  1176.         then do
  1177.           srvatt_cnt = 1
  1178.           castle_cmd.data.castle_i = base_cmd.data.base_i
  1179.           castle_i = castle_i + 1
  1180.           castle_cmd.data.castle_i = ''
  1181.           castle_i = castle_i + 1
  1182.           do while symbol('srvattch.srvatt_cnt') <> 'LIT'
  1183.             castle_cmd.data.castle_i = '"SRVATTCH"' srvattch.srvatt_cnt
  1184.             castle_i = castle_i + 1
  1185.             srvatt_cnt = srvatt_cnt + 1
  1186.           end
  1187.         end
  1188.  
  1189.   /********************************************************************/
  1190.   /*                                                                  */
  1191.   /* Insert the variables into the output file. Keep processing the   */
  1192.   /* variable array until a literal is found which means the end of   */
  1193.   /* the array.                                                       */
  1194.   /*                                                                  */
  1195.   /********************************************************************/
  1196.  
  1197.       when translate(comment) = 'START SYSTEM DATA HERE'
  1198.         then do
  1199.           var_cnt = 1
  1200.           castle_cmd.data.castle_i = base_cmd.data.base_i
  1201.           castle_i = castle_i + 1
  1202.           castle_cmd.data.castle_i = ''
  1203.           castle_i = castle_i + 1
  1204.           do while symbol('vars.var_cnt') <> 'LIT'
  1205.             castle_cmd.data.castle_i = vars.var_cnt
  1206.             castle_i = castle_i + 1
  1207.             var_cnt = var_cnt + 1
  1208.           end
  1209.         end
  1210.  
  1211.   /********************************************************************/
  1212.   /*                                                                  */
  1213.   /* Insert the product data into the output file. Keep processing    */
  1214.   /* the data for each product until the name for a product is a      */
  1215.   /* literal. This indicates the end of the product array.            */
  1216.   /*                                                                  */
  1217.   /********************************************************************/
  1218.  
  1219.       when translate(comment) = 'START PRODUCT DATA HERE'
  1220.         then do
  1221.           castle_cmd.data.castle_i = base_cmd.data.base_i
  1222.           castle_i = castle_i + 1
  1223.           castle_cmd.data.castle_i = ''
  1224.           castle_i = castle_i + 1
  1225.           prod_cnt = 1
  1226.           util_cnt = 1
  1227.           do until symbol('product.prod_cnt.name') = 'LIT'
  1228.  
  1229.   /********************************************************************/
  1230.   /*                                                                  */
  1231.   /* Assign a product number to the product name.                     */
  1232.   /*                                                                  */
  1233.   /********************************************************************/
  1234.  
  1235.             castle_cmd.data.castle_i = "x."product.prod_cnt.prog_name" = ",
  1236.                prod_cnt
  1237.             castle_i = castle_i + 1
  1238.  
  1239.   /********************************************************************/
  1240.   /*                                                                  */
  1241.   /* Store the product name.                                          */
  1242.   /*                                                                  */
  1243.   /********************************************************************/
  1244.  
  1245.             castle_cmd.data.castle_i = "x."prod_cnt".name = ",
  1246.                '"'product.prod_cnt.name'"'
  1247.             castle_i = castle_i + 1
  1248.  
  1249.   /********************************************************************/
  1250.   /*                                                                  */
  1251.   /* assign the state variable for this product and add it to the     */
  1252.   /* output file.                                                     */
  1253.   /*                                                                  */
  1254.   /********************************************************************/
  1255.  
  1256.             castle_cmd.data.castle_i = "x."prod_cnt".statevar = ""CAS_""",
  1257.                 "|| x."||prod_cnt||".name"
  1258.             castle_i = castle_i + 1
  1259.  
  1260.   /********************************************************************/
  1261.   /*                                                                  */
  1262.   /* Store the product install command and all of its parameters.     */
  1263.   /* Keep reading the parameters from the invoke array until a        */
  1264.   /* literal is returned.                                             */
  1265.   /*                                                                  */
  1266.   /********************************************************************/
  1267.  
  1268.             castle_cmd.data.castle_i = "x."prod_cnt".instprog = ",
  1269.                product.prod_cnt.invoke.1","
  1270.             castle_i = castle_i + 1
  1271.             invoke_cnt = 2
  1272.             do while symbol('product.prod_cnt.invoke.invoke_cnt') <> 'LIT'
  1273.               castle_cmd.data.castle_i = '                    'product.prod_cnt.invoke.invoke_cnt','
  1274.               castle_i = castle_i + 1
  1275.               invoke_cnt = invoke_cnt + 1
  1276.             end
  1277.             castle_i = castle_i - 1
  1278.             castle_cmd.data.castle_i = strip(castle_cmd.data.castle_i,'t',',')
  1279.             castle_i = castle_i + 1
  1280.  
  1281.   /********************************************************************/
  1282.   /*                                                                  */
  1283.   /* Store the path to the response file for this product. If one is  */
  1284.   /* not found store a blank for the path.                            */
  1285.   /*                                                                  */
  1286.   /********************************************************************/
  1287.  
  1288.             if symbol('product.prod_cnt.rspdir') <> LIT
  1289.               then do
  1290.                 castle_cmd.data.castle_i = "x."prod_cnt".rspdir = ",
  1291.                    product.prod_cnt.rspdir
  1292.                 castle_i = castle_i + 1
  1293.               end
  1294.               else do
  1295.                 castle_cmd.data.castle_i = "x."prod_cnt".rspdir = """""
  1296.                 castle_i = castle_i + 1
  1297.               end
  1298.  
  1299.   /********************************************************************/
  1300.   /*                                                                  */
  1301.   /* Store the default response file name for this product. If one is */
  1302.   /* not found store a blank for the path.                            */
  1303.   /*                                                                  */
  1304.   /********************************************************************/
  1305.  
  1306.             if symbol('product.prod_cnt.default') <> LIT
  1307.               then do
  1308.                 castle_cmd.data.castle_i = "x."prod_cnt".default = ",
  1309.                    product.prod_cnt.default
  1310.                 castle_i = castle_i + 1
  1311.               end
  1312.               else do
  1313.                 castle_cmd.data.castle_i = "x."prod_cnt".default = """""
  1314.                 castle_i = castle_i + 1
  1315.               end
  1316.  
  1317.   /********************************************************************/
  1318.   /*                                                                  */
  1319.   /* Bump the counters and go to the next product.                    */
  1320.   /*                                                                  */
  1321.   /********************************************************************/
  1322.  
  1323.             castle_cmd.data.castle_i = ''
  1324.             castle_i = castle_i + 1
  1325.             prod_cnt = prod_cnt + 1
  1326.           end
  1327.  
  1328.   /********************************************************************/
  1329.   /*                                                                  */
  1330.   /* Insert the utility data into the output file. Keep processing    */
  1331.   /* the data for each utility until the name for a utility is a      */
  1332.   /* literal. This indicates the end of the utility array.            */
  1333.   /*                                                                  */
  1334.   /********************************************************************/
  1335.  
  1336.           do while symbol('utility.util_cnt.name') <> 'LIT'
  1337.  
  1338.   /********************************************************************/
  1339.   /*                                                                  */
  1340.   /* Assign a product number to the utility name.                     */
  1341.   /*                                                                  */
  1342.   /********************************************************************/
  1343.  
  1344.             castle_cmd.data.castle_i = "x."utility.util_cnt.util_name" = ",
  1345.                prod_cnt
  1346.             castle_i = castle_i + 1
  1347.  
  1348.   /********************************************************************/
  1349.   /*                                                                  */
  1350.   /* Store the utility name.                                          */
  1351.   /*                                                                  */
  1352.   /********************************************************************/
  1353.  
  1354.             castle_cmd.data.castle_i = "x."prod_cnt".name = ",
  1355.                '"'utility.util_cnt.name'"'
  1356.             castle_i = castle_i + 1
  1357.  
  1358.   /********************************************************************/
  1359.   /*                                                                  */
  1360.   /* assign the state variable for this utility and add it to the     */
  1361.   /* output file.                                                     */
  1362.   /*                                                                  */
  1363.   /********************************************************************/
  1364.  
  1365.             castle_cmd.data.castle_i = "x."prod_cnt".statevar = """""
  1366.             castle_i = castle_i + 1
  1367.  
  1368.   /********************************************************************/
  1369.   /*                                                                  */
  1370.   /* Store the utility install command and all of its parameters.     */
  1371.   /* Keep reading the parameters from the invoke array until a        */
  1372.   /* literal is returned.                                             */
  1373.   /*                                                                  */
  1374.   /********************************************************************/
  1375.  
  1376.             castle_cmd.data.castle_i = "x."prod_cnt".instprog = ",
  1377.                utility.util_cnt.invoke.1","
  1378.             castle_i = castle_i + 1
  1379.             invoke_cnt = 2
  1380.             do while symbol('utility.util_cnt.invoke.invoke_cnt') <> 'LIT'
  1381.               castle_cmd.data.castle_i = '                    'utility.util_cnt.invoke.invoke_cnt','
  1382.               castle_i = castle_i + 1
  1383.               invoke_cnt = invoke_cnt + 1
  1384.             end
  1385.             castle_i = castle_i - 1
  1386.             castle_cmd.data.castle_i = strip(castle_cmd.data.castle_i,'t',',')
  1387.             castle_i = castle_i + 1
  1388.  
  1389.   /********************************************************************/
  1390.   /*                                                                  */
  1391.   /* Store the path to the response file for this utility. If one is  */
  1392.   /* not found store a blank for the path.                            */
  1393.   /*                                                                  */
  1394.   /********************************************************************/
  1395.  
  1396.             if symbol('utility.util_cnt.rspdir') <> LIT
  1397.               then do
  1398.                 castle_cmd.data.castle_i = "x."prod_cnt".rspdir = ",
  1399.                    utility.util_cnt.rspdir
  1400.                 castle_i = castle_i + 1
  1401.               end
  1402.               else do
  1403.                 castle_cmd.data.castle_i = "x."prod_cnt".rspdir = """""
  1404.                 castle_i = castle_i + 1
  1405.               end
  1406.  
  1407.   /********************************************************************/
  1408.   /*                                                                  */
  1409.   /* Store the default response file name for this utility. If one is */
  1410.   /* not found store a blank for the path.                            */
  1411.   /*                                                                  */
  1412.   /********************************************************************/
  1413.  
  1414.             if symbol('utility.util_cnt.default') <> LIT
  1415.               then do
  1416.                 castle_cmd.data.castle_i = "x."prod_cnt".default = ",
  1417.                    utility.util_cnt.default
  1418.                 castle_i = castle_i + 1
  1419.               end
  1420.               else do
  1421.                 castle_cmd.data.castle_i = "x."prod_cnt".default = """""
  1422.                 castle_i = castle_i + 1
  1423.               end
  1424.             castle_cmd.data.castle_i = ''
  1425.  
  1426.   /********************************************************************/
  1427.   /*                                                                  */
  1428.   /* Bump the counters and go to the next product.                    */
  1429.   /* Prod_cnt used as index into product/utility array.               */
  1430.   /*                                                                  */
  1431.   /********************************************************************/
  1432.  
  1433.             castle_i = castle_i + 1
  1434.             prod_cnt = prod_cnt + 1
  1435.             util_cnt = util_cnt + 1
  1436.           end
  1437.  
  1438.   /********************************************************************/
  1439.   /*                                                                  */
  1440.   /* Store total number of products and utilities.                    */
  1441.   /*                                                                  */
  1442.   /********************************************************************/
  1443.  
  1444.             castle_cmd.data.castle_i = 'NUM_INSTALL_PROGS = 'prod_cnt-1
  1445.             castle_i = castle_i + 1
  1446.         end
  1447.  
  1448.   /********************************************************************/
  1449.   /*                                                                  */
  1450.   /* Create the install sequence.                                     */
  1451.   /*                                                                  */
  1452.   /********************************************************************/
  1453.  
  1454.       when translate(comment) = 'PUT INSTALLS HERE'
  1455.         then do
  1456.  
  1457.   /********************************************************************/
  1458.   /*                                                                  */
  1459.   /* Start with the first element in the first queue and set the      */
  1460.   /* overall state to 0.                                              */
  1461.   /*                                                                  */
  1462.   /********************************************************************/
  1463.  
  1464.           queue_cnt = 1
  1465.           element = 1
  1466.           overall_state = 0
  1467.  
  1468.   /********************************************************************/
  1469.   /*                                                                  */
  1470.   /* Keep processing until the queue element is a literal.            */
  1471.   /*                                                                  */
  1472.   /********************************************************************/
  1473.  
  1474.           do until symbol('queue.queue_cnt.element') = 'LIT'
  1475.  
  1476.   /********************************************************************/
  1477.   /*                                                                    */
  1478.   /* This queue is an install sequence.                                 */
  1479.   /* Create the "When OVERALL_STATE for this queue sequence.          */
  1480.   /*                                                                  */
  1481.   /********************************************************************/
  1482.  
  1483.             castle_cmd.data.castle_i = '    when OVERALL_STATE = 'overall_state,
  1484.                    'then do'
  1485.             castle_i = castle_i + 1
  1486.  
  1487.             do until symbol('queue.queue_cnt.element') = 'LIT'
  1488.               if translate(queue.queue_cnt.element) = "SEMAINT" then do
  1489.                 castle_cmd.data.castle_i = ,
  1490.                 '      if BootDriveIsDiskette() == YES then iterate'
  1491.                 castle_i = castle_i + 1
  1492.               end
  1493.               element = element + 1
  1494.             end
  1495.             element = 1
  1496.   /********************************************************************/
  1497.   /*                                                                  */
  1498.   /* Create the RunInstall statements for each product in this queue. */
  1499.   /*                                                                  */
  1500.   /********************************************************************/
  1501.  
  1502.             do until symbol('queue.queue_cnt.element') = 'LIT'
  1503.               select
  1504.                 when translate(substr(queue.queue_cnt.element,1,8)) = "SRVATTCH"
  1505.                   then do
  1506.                     castle_cmd.data.castle_i =  '      'substr(queue.queue_cnt.element,10)
  1507.                     castle_i = castle_i + 1
  1508.                     element = element + 1
  1509.                   end
  1510.  
  1511.                 when translate(substr(queue.queue_cnt.element,1,8)) = "USERLINE"
  1512.                   then do
  1513.                     castle_cmd.data.castle_i =  '      'substr(queue.queue_cnt.element,10)
  1514.                     castle_i = castle_i + 1
  1515.                     element = element + 1
  1516.                   end
  1517.  
  1518.           /*    when translate(queue.queue_cnt.element) = "SEMAINT"
  1519.                   then do
  1520.                     castle_cmd.data.castle_i = ,
  1521.                     '      if BootDriveIsDiskette() == YES then iterate'
  1522.                     castle_i = castle_i + 1
  1523.                     castle_cmd.data.castle_i = '      if RunInstall(x.',
  1524.                         ||queue.queue_cnt.element')  == BAD_RC then exit'
  1525.                     castle_i = castle_i + 1
  1526.                     element = element + 1
  1527.                   end     */
  1528.  
  1529.                 otherwise do
  1530.                   castle_cmd.data.castle_i = '      if RunInstall(x.',
  1531.                       ||queue.queue_cnt.element')  == BAD_RC then exit'
  1532.                   castle_i = castle_i + 1
  1533.                   element = element + 1
  1534.                 end
  1535.               end
  1536.             end
  1537.   /********************************************************************/
  1538.   /*                                                                  */
  1539.   /* Bump to the next queue and reset the element to 1.               */
  1540.   /*                                                                  */
  1541.   /********************************************************************/
  1542.  
  1543.                 queue_cnt = Queue_cnt + 1
  1544.                 element = 1
  1545.  
  1546.   /********************************************************************/
  1547.   /*                                                                  */
  1548.   /* If this is the last queue sequence then call Reboot, else call   */
  1549.   /* CheckBoot. CheckBoot will check to see if any product installs   */
  1550.   /* requested a reboot before rebooting. Reboot will do an           */
  1551.   /* unconditional reboot.                                            */
  1552.   /*                                                                  */
  1553.   /********************************************************************/
  1554.  
  1555.                 if symbol('queue.queue_cnt.element') = 'LIT'
  1556.                   then castle_cmd.data.castle_i = '      Call Reboot'
  1557.                   else castle_cmd.data.castle_i = '      Call CheckBoot'
  1558.  
  1559.   /********************************************************************/
  1560.   /*                                                                  */
  1561.   /* End the When statement and bump the OVERALL_STATE                */
  1562.   /*                                                                  */
  1563.   /********************************************************************/
  1564.  
  1565.                 castle_i = castle_i + 1
  1566.                 castle_cmd.data.castle_i = '    end'
  1567.                 castle_i = castle_i + 1
  1568.                 overall_state = overall_state + 1
  1569.           end
  1570.         end
  1571.  
  1572.       Otherwise
  1573.  
  1574.   /********************************************************************/
  1575.   /*                                                                  */
  1576.   /* If there was nothing for CASPREP to do with this line then just  */
  1577.   /* copy it from the base to the output file.                        */
  1578.   /*                                                                  */
  1579.   /********************************************************************/
  1580.  
  1581.         castle_cmd.data.castle_i = base_cmd.data.base_i
  1582.         castle_i = castle_i + 1
  1583.     end
  1584.   end
  1585.  
  1586.   /********************************************************************/
  1587.   /*                                                                  */
  1588.   /* Remember the length of the output file.                          */
  1589.   /*                                                                  */
  1590.   /********************************************************************/
  1591.  
  1592.   castle_cmd.data.0 = castle_i-1
  1593.  
  1594.   /************************************************************************/
  1595.   /*                                                                      */
  1596.   /* Erase the old output file and write the new one to disk.             */
  1597.   /*                                                                      */
  1598.   /************************************************************************/
  1599.  
  1600.   outputfile = outfn||'.'||outfext
  1601.   if stream(outputfile,'c','query exists') <> '' then do
  1602.      '@echo off'
  1603.      say 'Erasing existing' outputfile
  1604.      "ERASE" outputfile
  1605.      '@echo on'
  1606.   end
  1607.   say "Creating output file " outfn||'.'||outfext
  1608.   do line_ctr = 1 to castle_cmd.data.0
  1609.       rc = lineout(outputfile,castle_cmd.data.line_ctr)
  1610.   end
  1611.  
  1612.   /*lineout(outputfile) */
  1613.  
  1614. return (0)
  1615. exit (0)
  1616.  
  1617.  /************************************************************************/
  1618.  /************************************************************************/
  1619.  /**                                                                    **/
  1620.  /** Internal Procedures                                                **/
  1621.  /**                                                                    **/
  1622.  /************************************************************************/
  1623.  /************************************************************************/
  1624.  
  1625.  
  1626.   /********************************************************************/
  1627.   /*                                                                  */
  1628.   /* The fix_quotes procedure will modify a line to change the quotes */
  1629.   /* from denoting the variable (input file format) to denoting a     */
  1630.   /* string (REXX format). It also looks for a mismatched quote. If   */
  1631.   /* a unmatched quote is found. CASPREP will display a message with  */
  1632.   /* the line and stop processing. Both the (') and the (") quotes    */
  1633.   /* will be looked for. The 2 quote types can be mixed on a single   */
  1634.   /* line.                                                            */
  1635.   /*                                                                  */
  1636.   /********************************************************************/
  1637.  
  1638. fix_quotes: procedure EXPOSE client_i
  1639.   quote_cnt = 0
  1640.   charpos = 0
  1641.   fix_string = arg(1)
  1642.  
  1643.   /************************************************************************/
  1644.   /*                                                                      */
  1645.   /* Find all of the (") quotes.                                          */
  1646.   /*                                                                      */
  1647.   /************************************************************************/
  1648.  
  1649.   if pos('"',fix_string) <> 0
  1650.     then do
  1651.       do until charpos = lastpos('"',fix_string)
  1652.         charpos = pos('"',fix_string,charpos+1)
  1653.         quote_cnt = quote_cnt + 1
  1654.       end
  1655.     end
  1656.   charpos = 0
  1657.  
  1658.   /************************************************************************/
  1659.   /*                                                                      */
  1660.   /* Find all of the (') quotes.                                          */
  1661.   /*                                                                      */
  1662.   /************************************************************************/
  1663.  
  1664.   if pos("'",fix_string) <> 0
  1665.     then do
  1666.       do until charpos = lastpos("'",fix_string)
  1667.         charpos = pos("'",fix_string,charpos+1)
  1668.         quote_cnt = quote_cnt + 1
  1669.       end
  1670.     end
  1671.  
  1672.   /************************************************************************/
  1673.   /*                                                                      */
  1674.   /* Check for odd number of quotes.                                      */
  1675.   /*                                                                      */
  1676.   /* Quote_cnt is converted to hex and ORed with 'fffe'x to see if the    */
  1677.   /* low order bit is on (odd).                                           */
  1678.   /*                                                                      */
  1679.   /************************************************************************/
  1680.  
  1681.   if quote_cnt <> 0
  1682.     then do
  1683.       quote_len = length(quote_cnt)
  1684.       quote_cnt = substr(quote_cnt,quote_len,1)
  1685.       quote_cnt = c2x(quote_cnt)
  1686.  
  1687.   /************************************************************************/
  1688.   /*                                                                      */
  1689.   /* If the count is odd then display an error message with the line.     */
  1690.   /*                                                                      */
  1691.   /************************************************************************/
  1692.  
  1693.       if bitor('fffe'x,quote_cnt) = 'ffff'x
  1694.         then do
  1695.           say "Line number " client_i "has a mismatched quote. Processing has"
  1696.           say "stopped."
  1697.           say fix_string
  1698.           exit (1)
  1699.         end
  1700.     end
  1701.  
  1702.   /************************************************************************/
  1703.   /*                                                                      */
  1704.   /* If the first character in the string is a quote then remove it.      */
  1705.   /* If the first character in the string is not a quote then add one.    */
  1706.   /* If the last character in the string is a quote then remove it.       */
  1707.   /* If the last character in the string is not a quote then add one.     */
  1708.   /*                                                                      */
  1709.   /* Check for either type quote.                                         */
  1710.   /*                                                                      */
  1711.   /************************************************************************/
  1712.  
  1713.   if substr(fix_string,1,1) = '"' |,
  1714.      substr(fix_string,1,1) = ''''
  1715.     then do
  1716.       fix_string = strip(fix_string,'l','"')
  1717.       fix_string = strip(fix_string,'l',"'")
  1718.     end
  1719.     else do
  1720.       fix_string = """"||fix_string
  1721.     end
  1722.     str_len = length(fix_string)
  1723.     if substr(fix_string,str_len,1) = '"' |,
  1724.        substr(fix_string,str_len,1) = ''''
  1725.       then do
  1726.         fix_string = strip(fix_string,'t','"')
  1727.         fix_string = strip(fix_string,'t','''')
  1728.         quotes = yes
  1729.       end
  1730.       else do
  1731.         fix_string = fix_string||""""
  1732.       end
  1733. return(fix_string)
  1734.  
  1735.  
  1736.   /************************************************************************/
  1737.   /*                                                                      */
  1738.   /* The remove_comments procedure will remove the comments from the      */
  1739.   /* input string.                                                        */
  1740.   /*                                                                      */
  1741.   /************************************************************************/
  1742.  
  1743. remove_comments: procedure expose client_cmd. client_i
  1744.  
  1745.   newstr = arg(1)
  1746.   do while newstr = '' & client_i <> client_cmd.data.0
  1747.      client_i = client_i + 1
  1748.      newstr = client_cmd.data.client_i
  1749.   end
  1750.   do while pos('/*',newstr) <> 0
  1751.      newstr = strip(newstr)
  1752.      str_len = length(newstr)
  1753.      start_com = pos('/*',newstr)
  1754.      end_com = pos('*/',newstr)
  1755.  
  1756.      select
  1757.   /************************************************************************/
  1758.   /*                                                                      */
  1759.   /* If the whole line is a comment then get next line.                   */
  1760.   /*                                                                      */
  1761.   /************************************************************************/
  1762.  
  1763.        when start_com = 1 & end_com = str_len-1
  1764.          then do
  1765.            client_i = client_i + 1
  1766.            newstr = client_cmd.data.client_i
  1767.          end
  1768.  
  1769.   /************************************************************************/
  1770.   /*                                                                      */
  1771.   /* If only start of comment in this line look for end of comment        */
  1772.   /*                                                                      */
  1773.   /************************************************************************/
  1774.        when start_com = 1 & end_com = 0
  1775.          then do
  1776.            do until pos('*/', newstr) <> 0
  1777.              client_i = client_i + 1
  1778.              newstr = client_cmd.data.client_i
  1779.            end
  1780.            client_i = client_i + 1
  1781.            newstr = client_cmd.data.client_i
  1782.          end
  1783.  
  1784.        otherwise do
  1785.          if start_com <> 1 then newstr = strip(substr(newstr,1,start_com-1))
  1786.          else newstr = strip(substr(newstr,end_com+2))
  1787.        end
  1788.      end
  1789.  
  1790.      do while newstr = '' & client_i <> client_cmd.data.0
  1791.         client_i = client_i + 1
  1792.         newstr = client_cmd.data.client_i
  1793.      end
  1794.  
  1795.   end
  1796.  
  1797. return newstr
  1798.  
  1799.  
  1800.   /************************************************************************/
  1801.   /*                                                                      */
  1802.   /* The bump_inc procedure increments the index into the input file and  */
  1803.   /* removes the comments from that line.                                 */
  1804.   /*                                                                      */
  1805.   /************************************************************************/
  1806.  
  1807. bump_inc: procedure expose client_cmd. client_i
  1808.   client_i = client_i + 1
  1809.   client_cmd.data.client_i = remove_comments(client_cmd.data.client_i)
  1810.  
  1811. return
  1812.  
  1813.  
  1814.   /************************************************************************/
  1815.   /*                                                                      */
  1816.   /* The help procedure displays the command syntax when called           */
  1817.   /*                                                                      */
  1818.   /************************************************************************/
  1819.  
  1820. find_keyword: procedure expose client_cmd. client_i
  1821.   keyword_fnd = 0
  1822.   if pos('NAME', translate(strip(client_cmd.data.client_i))) <> 0 then
  1823.     keyword_fnd = 1
  1824.   if pos('RSPDIR', translate(strip(client_cmd.data.client_i))) <> 0 then
  1825.     keyword_fnd = 1
  1826.   if pos('DEFAULT', translate(strip(client_cmd.data.client_i))) <> 0 then
  1827.     keyword_fnd = 1
  1828. return keyword_fnd
  1829.  
  1830.  
  1831.   /************************************************************************/
  1832.   /*                                                                      */
  1833.   /* The help procedure displays the command syntax when called           */
  1834.   /*                                                                      */
  1835.   /************************************************************************/
  1836.  
  1837. help: procedure
  1838.   say "The CASPREP command syntax is"
  1839.   say "input file output file (base file)"
  1840.   say ""
  1841.   say "The base file name is optional."
  1842. return
  1843.