home *** CD-ROM | disk | FTP | other *** search
/ Programmer's ROM - The Computer Language Library / programmersrom.iso / ada / tools / cbreak.src < prev    next >
Encoding:
Text File  |  1988-05-03  |  27.7 KB  |  765 lines

  1. with TEXT_IO;
  2. procedure CCC is
  3.   package INTEGER_IO is new TEXT_IO.INTEGER_IO(INTEGER);
  4.   use TEXT_IO;
  5.   use INTEGER_IO;
  6.   
  7.   type HELP_TYPE is array (1..20) of STRING(1..70);
  8.  
  9.   --  ############## S Y S T E M    D E P E N D E N C Y ##################
  10.   DEFAULT_INPUT_PREFIX_TERMINATOR : constant CHARACTER := ']';        --##
  11.   DEFAULT_EXTENSION : constant STRING := ".TXT;";               --##
  12.   --  ####################################################################
  13.  
  14.   PRE_FLAG : constant STRING :=
  15.     "--::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::";
  16.   FILE_SEPARATION_FLAG  : constant STRING := "--";
  17.   POST_FLAG : constant STRING :=
  18.     "--::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::";
  19.  
  20.   MAXIMUM_NAME_SIZE             : constant NATURAL := 140;
  21.   MAXIMUM_LINE_SIZE             : constant NATURAL := 250;
  22.  
  23.   SOURCE_FILE           : TEXT_IO.FILE_TYPE;
  24.   SOURCE_FILE_NAME      : STRING(1..MAXIMUM_NAME_SIZE);
  25.   SOURCE_FILE_NAME_LAST : INTEGER := 0;
  26.  
  27.   OUTPUT_FILE            : TEXT_IO.FILE_TYPE;
  28.   OUTPUT_FILE_NAME       : STRING(1..MAXIMUM_NAME_SIZE);
  29.   OUTPUT_FILE_NAME_LAST  : INTEGER := 0;
  30.  
  31.   LINE                  : STRING(1..MAXIMUM_LINE_SIZE);
  32.   LINE_LAST             : INTEGER := 0;
  33.  
  34.   FORMAT_ERROR          : exception;
  35.  
  36.   TARGET_FILE           : TEXT_IO.FILE_TYPE;
  37.   TARGET_FILE_NAME      : STRING(1..MAXIMUM_NAME_SIZE);
  38.   TARGET_FILE_NAME_LAST : INTEGER := 0;
  39.  
  40.   INPUT_FILE            : TEXT_IO.FILE_TYPE;
  41.   INPUT_FILE_NAME       : STRING(1..MAXIMUM_NAME_SIZE);
  42.   INPUT_FILE_NAME_LAST  : INTEGER := 0;
  43.  
  44.   FILE_OF_FILE_NAMES    : TEXT_IO.FILE_TYPE;
  45.  
  46.   BASIC_FILE_NAME_FIRST : INTEGER := 1;
  47.   BASIC_FILE_NAME_LAST  : INTEGER := 0;
  48.  
  49.   STATEMENTS            : NATURAL := 0;
  50.   LINE_COUNT            : NATURAL := 0;
  51.   COMMENTS              : NATURAL := 0;
  52.  
  53.   TOTAL_STATEMENTS      : NATURAL := 0;
  54.   TOTAL_LINE_COUNT      : NATURAL := 0;
  55.   TOTAL_COMMENTS        : NATURAL := 0;
  56.  
  57.  
  58.   --  ############## S Y S T E M    D E P E N D E N C Y ##################
  59.   procedure PROCESS_OUTPUT_FILE_NAME(OUTPUT_FILE_NAME : in out STRING;
  60.                                 OUTPUT_FILE_NAME_LAST : in out NATURAL) is
  61.   --  This procedure can embody a lot of intelligence about the two systems
  62.   --  It could determine if a default extension needs to be added
  63.   --  or if there is information about the file in the name (-SPEC) that
  64.   --  ought to be put in an extension in the new system (or vice versa)
  65.   --  or it may replace characters in one system (_) which the other rejects
  66.   --  This is therefore doubly system dependent
  67.   --  The present version just checks for existing extension signaled by '.'
  68.     DEFAULT_EXTENSION : constant STRING := ".TXT;";
  69.   begin
  70.     --  Add default extension if there is not an extension in the file name
  71.     for I in 1..OUTPUT_FILE_NAME_LAST  loop
  72.       if OUTPUT_FILE_NAME(I) = '.'  then
  73.         return;
  74.       end if;
  75.     end loop;
  76.     OUTPUT_FILE_NAME(1..OUTPUT_FILE_NAME_LAST+DEFAULT_EXTENSION'LENGTH) :=
  77.         OUTPUT_FILE_NAME(1..OUTPUT_FILE_NAME_LAST) & DEFAULT_EXTENSION;
  78.     OUTPUT_FILE_NAME_LAST := OUTPUT_FILE_NAME_LAST + DEFAULT_EXTENSION'LENGTH;
  79.     return;
  80.   end PROCESS_OUTPUT_FILE_NAME;
  81.   --  ####################################################################
  82.  
  83.   ----------------------------------------------------------------------------
  84.  
  85.   procedure EAT_LEADING_BLANKS(NAME : in out STRING; LAST: in out NATURAL) is
  86.   begin
  87.     while LAST >= 1  and NAME(1) = ' '  loop
  88.       NAME(1..LAST-1) := NAME(2..LAST);
  89.       LAST := LAST - 1;
  90.     end loop;
  91.   end EAT_LEADING_BLANKS;
  92.  
  93.   procedure TERMINATE_NAME_AT_THE_BLANK(NAME : in out STRING;
  94.                                         LAST : in out NATURAL) is
  95.   begin
  96.     for I in 2..LAST  loop
  97.       if NAME(I) = ' '  then
  98.         LAST := I - 1;
  99.         exit;
  100.       end if;
  101.     end loop;
  102.   end TERMINATE_NAME_AT_THE_BLANK;
  103.  
  104.   procedure GET_FILE_NAME(INPUT_FILE_NAME : in out STRING;
  105.                      INPUT_FILE_NAME_LAST : in out NATURAL;
  106.                                      HELP : in     HELP_TYPE) is
  107.   begin
  108.     PUT("File name =>");
  109.     loop    --  until a valid name, absorbing commments, file-of-files, '?'
  110.       if IS_OPEN(FILE_OF_FILE_NAMES)  then    --  Check input file is used
  111.         if END_OF_FILE(FILE_OF_FILE_NAMES)  then
  112.           CLOSE(FILE_OF_FILE_NAMES);          --  Have come to the end of a
  113.           SET_INPUT(STANDARD_INPUT);          --  file-of-files and want to
  114.         end if;                               --  return to keyboard input
  115.       end if;
  116.       GET_LINE(INPUT_FILE_NAME, INPUT_FILE_NAME_LAST);
  117.  
  118.       EAT_LEADING_BLANKS(INPUT_FILE_NAME, INPUT_FILE_NAME_LAST);
  119.       TERMINATE_NAME_AT_THE_BLANK(INPUT_FILE_NAME, INPUT_FILE_NAME_LAST);
  120.  
  121.       if INPUT_FILE_NAME_LAST = 1  and
  122.         INPUT_FILE_NAME(1) = '?'  then               --  Query for help
  123.         for I in HELP'FIRST..HELP'LAST  loop
  124.           PUT_LINE(HELP(I));
  125.         end loop;
  126.         PUT(""""); PUT(DEFAULT_EXTENSION);
  127.         PUT_LINE(""" is the current default extension");
  128.         PUT("File name =>");
  129.  
  130.       elsif INPUT_FILE_NAME_LAST >= 2  and
  131.          INPUT_FILE_NAME(1..2) = "--"  then          --  Skip comment lines
  132.         null;
  133.  
  134.       elsif INPUT_FILE_NAME_LAST >= 2 and
  135.             INPUT_FILE_NAME(1) = '@'  then           --  File of file names
  136.       TRY_FILE_OF_FILES:
  137.         begin
  138.           OPEN(FILE_OF_FILE_NAMES, IN_FILE,
  139.             INPUT_FILE_NAME(2..INPUT_FILE_NAME_LAST));
  140.           SET_INPUT(FILE_OF_FILE_NAMES);
  141.         exception
  142.           when NAME_ERROR  =>
  143.             PUT("NAME_ERROR in name given for file-of-files, give full name");
  144.  
  145.         end TRY_FILE_OF_FILES;
  146.         NEW_LINE;
  147.         PUT("File name =>");
  148.  
  149.       elsif INPUT_FILE_NAME_LAST = 0  then           --  Use a blank line to
  150.         NEW_LINE;                                    --  quit the program
  151.         exit;
  152.  
  153.       else                                           --  Regular file name
  154.         exit;
  155.       end if;
  156.     end loop;
  157.   exception
  158.   when END_ERROR  =>
  159.     SET_INPUT(STANDARD_INPUT);
  160.   end GET_FILE_NAME;
  161.  
  162.   procedure OPEN_INPUT_FILE_NAME_MAYBE_ADD_EXTENSION
  163.                (INPUT_FILE : in out FILE_TYPE;
  164.            INPUT_FILE_NAME : in out STRING;
  165.       INPUT_FILE_NAME_LAST : in out NATURAL) is
  166.   begin
  167.     OPEN(INPUT_FILE, IN_FILE,
  168.       INPUT_FILE_NAME(1..INPUT_FILE_NAME_LAST));
  169.   exception
  170.     when NAME_ERROR  =>
  171.       INPUT_FILE_NAME_LAST := INPUT_FILE_NAME_LAST + 
  172.                               DEFAULT_EXTENSION'LAST;
  173.       INPUT_FILE_NAME(1..INPUT_FILE_NAME_LAST) :=
  174.       INPUT_FILE_NAME(1..
  175.               INPUT_FILE_NAME_LAST - DEFAULT_EXTENSION'LAST) &
  176.           DEFAULT_EXTENSION;
  177.       OPEN(INPUT_FILE, IN_FILE,
  178.           INPUT_FILE_NAME(1..INPUT_FILE_NAME_LAST));
  179.   end OPEN_INPUT_FILE_NAME_MAYBE_ADD_EXTENSION;
  180.         
  181. ----------------------------------------------------------------------------
  182.  
  183.   procedure COPY_FILE_AND_COUNT is
  184.     NEXT_CHAR    : NATURAL := 1;
  185.     C            : CHARACTER := ' ';
  186.     LEVEL        : INTEGER := 0;
  187.     HALF_COMMENT : BOOLEAN := FALSE;
  188.   
  189.  
  190.     procedure FETCH (CH : out CHARACTER) is
  191.     begin
  192.         if NEXT_CHAR > LINE_LAST  then
  193.             loop
  194.                 if END_OF_PAGE(INPUT_FILE)  then
  195.                   SKIP_PAGE(INPUT_FILE);
  196.                   NEW_PAGE(TARGET_FILE);
  197.                 end if;
  198.                 TEXT_IO.GET_LINE(INPUT_FILE, LINE, LINE_LAST);
  199.                 TEXT_IO.PUT_LINE(TARGET_FILE, LINE(1..LINE_LAST));
  200.                 LINE_COUNT := LINE_COUNT + 1;
  201.                 NEXT_CHAR := 1;
  202.                 exit when NEXT_CHAR <= LINE_LAST;
  203.             end loop;
  204.         end if;
  205.         CH := LINE (NEXT_CHAR);
  206.         NEXT_CHAR := NEXT_CHAR + 1;
  207.     exception 
  208.       when END_ERROR  =>
  209.         LINE_LAST := 0;
  210.         CH := ' ';
  211.         raise;
  212.     end FETCH;
  213.  
  214.   
  215.     procedure QUOTES is
  216.     --  If a quote appears, run out the line until closed
  217.     begin
  218.       --  Check for string brackets of either kind, " or %
  219.       if C = '"' or C = '%' then
  220.         --  Treat them in parallel, one must lead off
  221.         if C = '"' then
  222.           loop
  223.             FETCH (C);
  224.             --  Loop until the close comes
  225.             --  If there is a doubled character it just starts again
  226.             exit when C = '"';
  227.             if NEXT_CHAR = (LINE_LAST + 1)  then
  228.               --  The quote has gone over a line boundry
  229.               PUT_LINE(LINE(1..LINE_LAST));
  230.               PUT(""" missing on line ");
  231.               PUT(LINE_COUNT);
  232.               NEW_LINE;
  233.               exit;  --  anyway
  234.             end if;
  235.           end loop;
  236.         --  The '%' is handled exactly the same way as '"'
  237.         elsif C = '%' then
  238.           loop
  239.             FETCH (C);
  240.             exit when C = '%';
  241.             if NEXT_CHAR = (LINE_LAST + 1)  then
  242.               --  The quote has gone over a line boundry
  243.               PUT_LINE(LINE(1..LINE_LAST));
  244.               PUT("% missing on line ");
  245.               PUT(LINE_COUNT);
  246.               NEW_LINE;
  247.               exit;  --  anyway
  248.             end if;
  249.           end loop;
  250.         end if;
  251.       end if;
  252.     end QUOTES;
  253.  
  254.     procedure COMMENT_CHECK is
  255.     begin
  256.       --  Check for comments and skip to the end of line
  257.       if C = '-' then
  258.         if HALF_COMMENT and (NEXT_CHAR /= 2)  then
  259.           --  The last character was a '_', therefore HALF_COMMENT is TRUE
  260.           --  And this is not the first character of a line with a '-' left
  261.           --  Then just skip the rest of the line and go to the next
  262.           NEXT_CHAR := LINE_LAST + 1;    --  So FETCH will go to next line
  263.           COMMENTS := COMMENTS + 1;
  264.           HALF_COMMENT := FALSE;
  265.         else
  266.           --  This '-' is the first and may signal the begining of a comment
  267.           HALF_COMMENT := TRUE;
  268.         end if;
  269.       else
  270.         HALF_COMMENT := FALSE;
  271.         end if;
  272.       end COMMENT_CHECK;
  273.   
  274.     begin
  275.       STATEMENTS := 0;
  276.       LINE_COUNT := 0;
  277.       COMMENTS   := 0;
  278.   
  279.       --Scan the file character at a time
  280.       loop
  281.         FETCH (C);
  282.   
  283.         --  Check for one of the characters which introduce code constructs
  284.         --  like string or character literal or formal parameter list
  285.         --  within which a ';' does not terminate a "Ada statement"
  286.         if C = '(' or C = '"' or C = '%' or C = ''' then
  287.   
  288.           --If there is a quote this superceeds everything until ended
  289.           QUOTES;
  290.   
  291.           --Elsif look for parentheses and count the levels until they close
  292.           --  Check for opening parentheses
  293.           --  ';' within is most likely in a formal parameter list
  294.           if C = '(' then
  295.             --  Count the number of levels of parentheses
  296.             LEVEL := LEVEL + 1;
  297.             --  Read ahead until the whole construct is closed, LEVEL = 0
  298.             while LEVEL > 0 loop
  299.               FETCH (C);
  300.               QUOTES;
  301.               COMMENT_CHECK;
  302.               if C = '(' then
  303.                 --  Increase the level if another '(' is found
  304.                 LEVEL := LEVEL + 1;
  305.               elsif C = ')' then
  306.                 --  Decrease the level if a ')' is found
  307.                 LEVEL := LEVEL - 1;
  308.               end if;
  309.             end loop;
  310.   
  311.           --Check for the ; being a character literal in '
  312.           --  Character literals are just three characters long including '
  313.           elsif C = ''' then
  314.             FETCH (C);
  315.             FETCH (C);
  316.           end if;
  317.         end if;
  318.   
  319.           COMMENT_CHECK;
  320.           
  321.         --Now the rest is regular so we look for ;
  322.         --  Any ';' that can be found at this point after all exclusions
  323.         --  must be a valid "Ada statement" terminator
  324.         --  (We could check back to see if it follows a reasonable place)
  325.         if C = ';' then
  326.             --Then it must be an Ada statement terminator
  327.             STATEMENTS := STATEMENTS + 1;
  328.         end if;
  329.   
  330.       end loop;
  331.   
  332.   end COPY_FILE_AND_COUNT;
  333.  
  334. ------------------------------------------------------------------------------
  335.  
  336. procedure CHECK_FILE_NAMES is
  337.  
  338.   --type HELP_TYPE is array (1..20) of STRING(1..70);
  339.   
  340.   HELP : HELP_TYPE :=  (
  341.     "                                                                      ",
  342.     "                                                                      ",
  343.     "                                                                      ",
  344.     "                                                                      ",
  345.     "                                                                      ",
  346.     "                                                                      ",
  347.     "                                                                      ",
  348.     "                                                                      ",
  349.     "                                                                      ",
  350.     "                                                                      ",
  351.     "                                                                      ",
  352.     "                                                                      ",
  353.     "This procedure checks the validity of a series of file names          ",
  354.     "so that such a list may confidently be submitted to other programs    ",
  355.     "It just asks for the file names in order or a '@' followed by a file  ",
  356.     "containing the names of files (maybe with leading blanks),            ",
  357.     "terminated by a blank, or comments preceded by the Ada -- comment flag",
  358.     "The @ file may NOT NOW contain '@' and the names of other @ files     ",
  359.     "The list or the program is terminated by an empty line                ",
  360.     "A default extension will automatically be tried if the name fails     " );
  361.  
  362.  
  363. begin
  364.   PUT_LINE("CHECK_FILE_NAMES: (or '@' and a file of file names, ? for help)");
  365.  
  366.   loop                  --  on the processing of the series of files
  367.     GET_FILE_NAME(INPUT_FILE_NAME, INPUT_FILE_NAME_LAST, HELP);
  368.     
  369.     exit when INPUT_FILE_NAME_LAST = 0;                --  Finished
  370.   
  371.   PROCESS_REGULAR_FILE_NAME: 
  372.     begin  
  373.       OPEN_INPUT_FILE_NAME_MAYBE_ADD_EXTENSION(INPUT_FILE, 
  374.           INPUT_FILE_NAME, INPUT_FILE_NAME_LAST);
  375.  
  376.     PROCESS_OPEN_FILE:
  377.       begin
  378.         CLOSE(INPUT_FILE);
  379.         if not IS_OPEN(FILE_OF_FILE_NAMES)  then
  380.           PUT("            ");
  381.         end if;
  382.         PUT(INPUT_FILE_NAME(1..INPUT_FILE_NAME_LAST));
  383.         PUT_LINE(" found");
  384.       end PROCESS_OPEN_FILE;
  385.     
  386.     exception
  387.       when NAME_ERROR  =>
  388.         PUT("########  NAME_ERROR in checking file name " &
  389.             INPUT_FILE_NAME(1..INPUT_FILE_NAME_LAST));
  390.         NEW_LINE; 
  391.       when STATUS_ERROR  =>
  392.         PUT("########  STATUS_ERROR in checking file name " &
  393.             INPUT_FILE_NAME(1..INPUT_FILE_NAME_LAST));
  394.         NEW_LINE; 
  395.       when USE_ERROR  =>
  396.         PUT("########  USE_ERROR in checking file name " &
  397.             INPUT_FILE_NAME(1..INPUT_FILE_NAME_LAST));
  398.         NEW_LINE; 
  399.     end PROCESS_REGULAR_FILE_NAME;
  400.  
  401.   end loop;
  402.  
  403.   PUT_LINE("Quit");
  404.  
  405. exception
  406.   when others  =>
  407.     PUT_LINE("Unexpected exception raised in CHECK_FILE_NAMES");
  408.     CLOSE(INPUT_FILE);
  409. end CHECK_FILE_NAMES;
  410.  
  411. procedure COMBINE_FILES is
  412.   --type HELP_TYPE is array (1..20) of STRING(1..70);
  413.  
  414.   HELP : HELP_TYPE := (
  415.     "This procedure reads file names from STANDARD_INPUT and copies those  ",
  416.     "files onto another separated by two rows of commented colons and the  ",
  417.     "basic name of the file, so that they may be automatically separated   ",
  418.     "The file name may be preceded by a directory name which is stripped   ",
  419.     "to make the basic name, and the procedure will affix a default        ",
  420.     "extension to the input name if the input named file does not exist    ",
  421.     "The directory format and default extension are system dependent       ",
  422.     "                                                                      ",
  423.     "USAGE:                                                                ",
  424.     "A target file name is requested,                                      ",
  425.     "Target file for combined text file <RETURN> =>                        ",
  426.     "then the files to be combined together                                ",
  427.     "File to be appended =>DBA4:[WHITAKER]COMBINE                          ",
  428.     "A default extension will be added if required e.g. COMBINE.TXT;       ",
  429.     "or the files may be referenced in a file of files preceded by '@'     ",
  430.     "and copy that file preceded by the header                             ",
  431.     "--::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::",
  432.     "--COMBINE                                                             ",
  433.     "--::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::",
  434.     "                                                                      ");
  435.  
  436. begin
  437.   PUT_LINE("COMBINE_FILES : (or '@' and a file of file names, ? for help)");
  438.   
  439.   loop                  --  To create a target file
  440.     PUT("Target file for combined text file <RETURN> =>");
  441.     GET_LINE(TARGET_FILE_NAME, TARGET_FILE_NAME_LAST);
  442.     if TARGET_FILE_NAME_LAST = 1  and
  443.       TARGET_FILE_NAME(1) = '?'  then               --  Query for help
  444.       for I in HELP'FIRST..HELP'LAST  loop
  445.         PUT_LINE(HELP(I));
  446.       end loop;
  447.     else
  448.     CREATE_TARGET_OR_RAISE_EXCEPTION:
  449.       begin
  450.         CREATE(TARGET_FILE, OUT_FILE,
  451.                TARGET_FILE_NAME(1..TARGET_FILE_NAME_LAST));
  452.       exception                 --  Checking for the prior existance of the file
  453.  
  454.         when NAME_ERROR  =>
  455.           PUT("########  NAME_ERROR in creating file name " &
  456.               INPUT_FILE_NAME(1..INPUT_FILE_NAME_LAST));
  457.               NEW_LINE;
  458.         when STATUS_ERROR  =>
  459.           PUT("########  STATUS_ERROR in creating file name " &
  460.               INPUT_FILE_NAME(1..INPUT_FILE_NAME_LAST));
  461.               NEW_LINE;
  462.         when USE_ERROR  =>
  463.           PUT("########  USE_ERROR in creating file name " &
  464.               INPUT_FILE_NAME(1..INPUT_FILE_NAME_LAST));
  465.               NEW_LINE; 
  466.       end CREATE_TARGET_OR_RAISE_EXCEPTION;
  467.     end if;
  468.     if IS_OPEN(TARGET_FILE)  then
  469.       exit;
  470.     end if;
  471.   end loop;
  472.  
  473.   PUT_LINE("Files to be combined:");
  474.   
  475.   loop                  --  on the processing of the series of files
  476.  
  477.     GET_FILE_NAME(INPUT_FILE_NAME, INPUT_FILE_NAME_LAST, HELP);
  478.     
  479.     exit when INPUT_FILE_NAME_LAST = 0;                --  Finished
  480.       
  481.     --  Count off the prefix from the basic file name
  482.     BASIC_FILE_NAME_FIRST := 1;
  483.     for I in 1..INPUT_FILE_NAME_LAST-1  loop
  484.       if INPUT_FILE_NAME(I) = DEFAULT_INPUT_PREFIX_TERMINATOR  then
  485.         BASIC_FILE_NAME_FIRST := I + 1;
  486.         exit;
  487.       end if;
  488.     end loop;
  489.       
  490.     BASIC_FILE_NAME_LAST := INPUT_FILE_NAME_LAST;
  491.     --  Count back to the last ';' over any version number (for VAX/VMS)  #####
  492.     for I in reverse BASIC_FILE_NAME_FIRST..INPUT_FILE_NAME_LAST  loop
  493.       if INPUT_FILE_NAME(I) = ';'  then
  494.         BASIC_FILE_NAME_LAST := I - 1;
  495.         exit;
  496.       end if;
  497.     end loop;
  498.     
  499.     --  Check if the ending is the default extension, remove for basic name
  500. --    if BASIC_FILE_NAME_LAST > DEFAULT_EXTENSION'LAST  and then
  501.     if BASIC_FILE_NAME_LAST > DEFAULT_EXTENSION'LAST  then
  502. if
  503.        INPUT_FILE_NAME(BASIC_FILE_NAME_LAST - DEFAULT_EXTENSION'LAST..
  504.                        BASIC_FILE_NAME_LAST) = DEFAULT_EXTENSION  then
  505.       BASIC_FILE_NAME_LAST := BASIC_FILE_NAME_LAST - DEFAULT_EXTENSION'LAST;
  506.     end if;
  507. end if;
  508.  
  509.     OPEN_INPUT_FILE_NAME_MAYBE_ADD_EXTENSION(INPUT_FILE, 
  510.         INPUT_FILE_NAME, INPUT_FILE_NAME_LAST);
  511.     
  512.     if IS_OPEN(INPUT_FILE)  then      --  If we were successful opening file
  513.       PUT_LINE(INPUT_FILE_NAME(1..INPUT_FILE_NAME_LAST));
  514.       --  Put out the interfile flags
  515.       PUT(TARGET_FILE, PRE_FLAG); NEW_LINE(TARGET_FILE);
  516.       PUT(TARGET_FILE, FILE_SEPARATION_FLAG);
  517.       PUT_LINE(TARGET_FILE, 
  518.                INPUT_FILE_NAME(BASIC_FILE_NAME_FIRST..BASIC_FILE_NAME_LAST));
  519.       PUT(TARGET_FILE, POST_FLAG); NEW_LINE(TARGET_FILE);
  520.       
  521.     TRANSFER_FILE:
  522.       --  Assuming that it is a text file of reasonable lines
  523.       begin
  524.           COPY_FILE_AND_COUNT;
  525.       exception
  526.         when END_ERROR  =>
  527.           null;
  528.       end TRANSFER_FILE;
  529.       
  530.       CLOSE(INPUT_FILE);
  531.       PUT("STATEMENTS = "); PUT(STATEMENTS);
  532.       PUT("   LINE_COUNT = "); PUT(LINE_COUNT);
  533.       PUT("   COMMENTS = "); PUT(COMMENTS);
  534.       NEW_LINE;
  535.       NEW_LINE;
  536.       TOTAL_STATEMENTS := TOTAL_STATEMENTS + STATEMENTS;
  537.       TOTAL_LINE_COUNT := TOTAL_LINE_COUNT + LINE_COUNT;
  538.       TOTAL_COMMENTS   := TOTAL_COMMENTS   + COMMENTS;
  539.  
  540.     end if;
  541.  
  542.   end loop;
  543.  
  544.   CLOSE(TARGET_FILE);
  545.   if (STATEMENTS = TOTAL_STATEMENTS) and (LINE_COUNT = TOTAL_LINE_COUNT)  then
  546.     null;
  547.   else
  548.     NEW_LINE; NEW_LINE;
  549.     PUT_LINE("TOTALS");
  550.     NEW_LINE;
  551.     PUT("STATEMENTS = "); PUT(TOTAL_STATEMENTS);
  552.     PUT("   LINE_COUNT = "); PUT(TOTAL_LINE_COUNT);
  553.     PUT("   COMMENTS = "); PUT(TOTAL_COMMENTS);
  554.     NEW_LINE;
  555.     NEW_LINE;
  556.   end if;
  557.  
  558. exception
  559.   when others  =>
  560.     PUT_LINE("Unexpected exception raised in COMBINE");
  561.     CLOSE(TARGET_FILE);
  562. end COMBINE_FILES;
  563.  
  564. procedure BREAK_DOWN_FILE is
  565.  
  566.   --type HELP_TYPE is array (1..20) of STRING(1..70);
  567.   
  568.   HELP : HELP_TYPE := (
  569.     "                                                                      ",
  570.     "                                                                      ",
  571.     "                                                                      ",
  572.     "                                                                      ",
  573.     "                                                                      ",
  574.     "                                                                      ",
  575.     "                                                                      ",
  576.     "                                                                      ",
  577.     "                                                                      ",
  578.     "                                                                      ",
  579.     "                                                                      ",
  580.     "                                                                      ",
  581.     "This procedure takes a file made up of several files separated by     ",
  582.     "a header and breaks it down into the constituent files                ",
  583.     "Presumably the combined file was constructed for transport or         ",
  584.     "archiving by a COMBINE_FILES program                                  ",
  585.     "The separating flag encloses the basic name of the file to be created ",
  586.     "The program will add a system dependent extension if there is no      ",
  587.     "extension in the basic file name                                      ",
  588.     "This version takes a full line of colons flag or the UNIX 10 colons   ");
  589.   
  590.   PRE_FLAG : constant STRING :=
  591.     "--::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::";
  592.   FILE_SEPARATION_FLAG  : constant STRING := "--";
  593.   POST_FLAG : constant STRING := 
  594.     "--::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::";
  595.  
  596.  
  597.         
  598. begin
  599.  
  600.   loop
  601.         
  602.   PUT_LINE("BREAK DOWN A FILE : (or '@' and a file of file names, ? for help)");
  603.  
  604.   
  605.   loop                  --  To open a source file
  606.     PUT_LINE("Source file to break down into individual files:");
  607.     GET_FILE_NAME(SOURCE_FILE_NAME, SOURCE_FILE_NAME_LAST, HELP);
  608.     
  609.     exit when SOURCE_FILE_NAME_LAST = 0;                --  Finished
  610.   
  611.     OPEN_SOURCE_OR_RAISE_EXCEPTION:
  612.       begin
  613.         OPEN(SOURCE_FILE, IN_FILE, SOURCE_FILE_NAME(1..SOURCE_FILE_NAME_LAST));
  614.       exception                 --  Checking for the existance of the file
  615.         when NAME_ERROR  =>
  616.           PUT("########  NAME_ERROR in opening file name " &
  617.               SOURCE_FILE_NAME(1..SOURCE_FILE_NAME_LAST));
  618.           NEW_LINE;
  619.         when STATUS_ERROR  =>
  620.           PUT("########  STATUS_ERROR in opening file name " &
  621.               SOURCE_FILE_NAME(1..SOURCE_FILE_NAME_LAST));
  622.           NEW_LINE;
  623.         when USE_ERROR  =>
  624.           PUT("########  USE_ERROR in opening file name " &
  625.               SOURCE_FILE_NAME(1..SOURCE_FILE_NAME_LAST)); 
  626.           NEW_LINE;
  627.       end OPEN_SOURCE_OR_RAISE_EXCEPTION;
  628.     if IS_OPEN(SOURCE_FILE)  then
  629.       exit;
  630.     end if;
  631.   end loop;
  632.   
  633.   exit when SOURCE_FILE_NAME_LAST = 0;
  634.   
  635.   loop
  636.     if END_OF_FILE(SOURCE_FILE)  then
  637.       raise FORMAT_ERROR;
  638.     end if;
  639.     GET_LINE(SOURCE_FILE, LINE, LINE_LAST);
  640.     if LINE_LAST >= 10 and PRE_FLAG'LENGTH >= 10  then
  641.       if LINE(3..10) = PRE_FLAG(3..10)   then    --  Accomadates mine or UNIX 
  642.         exit;
  643.       end if;
  644.     end if;
  645.   end loop;
  646.  
  647.   loop
  648.   
  649.   GET_OUTPUT_FILE_NAME:
  650.     begin
  651.       GET_LINE(SOURCE_FILE, LINE, LINE_LAST);
  652.       if LINE(1..FILE_SEPARATION_FLAG'LAST) = FILE_SEPARATION_FLAG  then
  653.         OUTPUT_FILE_NAME_LAST := LINE_LAST - FILE_SEPARATION_FLAG'LAST;
  654.         OUTPUT_FILE_NAME(1..OUTPUT_FILE_NAME_LAST) :=
  655.             LINE(FILE_SEPARATION_FLAG'LAST+1..LINE_LAST);
  656.         GET_LINE(SOURCE_FILE, LINE, LINE_LAST);
  657.         if LINE_LAST >= 10 and PRE_FLAG'LENGTH >= 10  then
  658.           if LINE(3..10) /= POST_FLAG(3..10)  then  --  UNIX
  659.             raise FORMAT_ERROR;
  660.           end if;
  661.         end if;
  662.       else
  663.         raise FORMAT_ERROR;
  664.       end if;
  665.     end GET_OUTPUT_FILE_NAME;
  666.  
  667.     EAT_LEADING_BLANKS(OUTPUT_FILE_NAME, OUTPUT_FILE_NAME_LAST);
  668.     TERMINATE_NAME_AT_THE_BLANK(OUTPUT_FILE_NAME, OUTPUT_FILE_NAME_LAST);
  669.  
  670.     PROCESS_OUTPUT_FILE_NAME(OUTPUT_FILE_NAME, OUTPUT_FILE_NAME_LAST);
  671.  
  672.     CREATE(OUTPUT_FILE, OUT_FILE, 
  673.            OUTPUT_FILE_NAME(1..OUTPUT_FILE_NAME_LAST));
  674.     PUT("Creating file ");
  675.     PUT(OUTPUT_FILE_NAME(1..OUTPUT_FILE_NAME_LAST));
  676.  
  677.     if IS_OPEN(OUTPUT_FILE)  then      --  If we were successful opening file
  678.  
  679.     TRANSFER_FILE:
  680.       --  Assuming that it is a text file of reasonable lines
  681.       loop
  682.         if END_OF_FILE(SOURCE_FILE)  then
  683.           exit;
  684.         end if;
  685.         GET_LINE(SOURCE_FILE, LINE, LINE_LAST);
  686.         if LINE_LAST >= 10 and PRE_FLAG'LENGTH >= 10  then
  687.           if LINE(3..10) = PRE_FLAG(3..10)   then    --  Accomadates UNIX 
  688.             exit;
  689.           end if;
  690.         end if;
  691.         PUT_LINE(OUTPUT_FILE, LINE(1..LINE_LAST));
  692.       end loop TRANSFER_FILE;
  693.  
  694.       CLOSE(OUTPUT_FILE);
  695.       PUT("      --  Finished");
  696.       NEW_LINE;
  697.  
  698.     end if;
  699.   
  700.     if END_OF_FILE(SOURCE_FILE)  then
  701.       exit;
  702.     end if;
  703.  
  704.   end loop;
  705.  
  706.   CLOSE(SOURCE_FILE);
  707.   end loop;
  708.  
  709.   PUT_LINE("Quit");
  710.  
  711. exception
  712.   when FORMAT_ERROR  =>
  713.     PUT_LINE("FORMAT_ERROR raised in BREAK_DOWN_FILE");
  714.     CLOSE(SOURCE_FILE);
  715.     CLOSE(OUTPUT_FILE);
  716.   when others  =>
  717.     PUT_LINE("Unexpected exception raised in BREAK_DOWN_FILE");
  718.     CLOSE(SOURCE_FILE);
  719.     CLOSE(OUTPUT_FILE);
  720. end BREAK_DOWN_FILE;
  721.  
  722.   function UPPER_CASE(S : STRING) return STRING is
  723.     UP : STRING(1..S'LAST);
  724.  
  725.     function UPPER_CASE(C : CHARACTER) return CHARACTER is
  726.     begin
  727.       if C in 'a'..'z'  then
  728.         return CHARACTER'VAL(CHARACTER'POS(C) - 32);
  729.       else 
  730.         return C;
  731.       end if;
  732.     end UPPER_CASE;
  733.  
  734.   begin
  735.     for I in 1..S'LAST  loop
  736.       UP(I) := UPPER_CASE(S(I));
  737.     end loop;
  738.     return UP;
  739.   end UPPER_CASE;
  740.  
  741. begin
  742.  
  743.   GET_COMMAND:
  744.   declare
  745.     RESPONSE : STRING(1..MAXIMUM_LINE_SIZE);
  746.     RESPONSE_LAST : NATURAL := 0;
  747.   begin
  748.     PUT_LINE("Do you want to Check file names, Combine, Break, or Quit?  =>");
  749.     GET_LINE(RESPONSE, RESPONSE_LAST);
  750.     if UPPER_CASE(RESPONSE(1..2)) = "CH"  then
  751.       CHECK_FILE_NAMES;
  752.     elsif UPPER_CASE(RESPONSE(1..2)) = "CO"  then
  753.       COMBINE_FILES;
  754.     elsif UPPER_CASE(RESPONSE(1..1)) = "B"  then
  755.       BREAK_DOWN_FILE;
  756.     elsif UPPER_CASE(RESPONSE(1..1)) = "Q"  then
  757.       null;
  758.     end if;
  759.   end GET_COMMAND;
  760.  
  761. end CCC;
  762.  
  763.  
  764.  
  765.