Kirjautuminen

Haku

Tehtävät

Koodit: PL/I: Heksadumppi tiedostosta

Kirjoittaja: jalski

Kirjoitettu: 23.08.2012 – 17.07.2014

Tagit: ohjelmointitavat, teksti, koodi näytille, vinkki

Välillä ongelmakohtaa etsiessä voi olla hyödyllistä tutkia tiedoston sisältöä tarkemmin. Verkosta voi tietysti ladata hienon heksaeditorin, mutta tarkoitukseen monesti riittävän heksadumpin tulostavan ohjelman kirjoittaa itsekin lähes valmiin ohjelman lataukseen menevässä ajassa:

*PROCESS MARGINS(1,120) LIBS(SINGLE,STATIC);
*PROCESS OPTIMIZE(2) DFT(REORDER);


 hexdump: proc(parms) options(main);
   dcl parms char(100) var;

   /* Union for easy character value conversion                    */
   dcl 1 char_byte union,
         2 ch char(1),
         2 byte fixed bin(8) unsigned;

   dcl i fixed bin;
   dcl offs fixed bin(32) unsigned init(0);
   dcl buffer character(16) var;
   dcl in file;

   /* If no filename specified, give info about usage              */
   on undefinedfile(in)
     begin;
       put skip
         list ('Usage: ' || procedurename() || ' /filename');
       stop;
     end;

   /* Open file for record input */
   open file(in)
     title ('/'||parms||',type(fixed), recsize(1)') record input;

   /* We test the endfile condition manually, so leave empty */
   on endfile(in);

  /* Next read and process file, one byte at a time                */
  read_bytes:
   do forever;
     buffer = '';
     read file(in) into(ch);
     if endfile(in) then leave read_bytes;

     /* First display offset field */
     put edit (trim(hex(offs)), ':') (a(8), a(2));

     /* After offset field, display hex values as                  */
     /* four groups of four bytes. Also build ASCII buffer         */

     /* Strip control character from input                         */
     /* and replace with dot.                                      */
     if byte > 31 & byte < 127 then buffer = buffer || ch;
     else buffer = buffer || '.';

     put edit (trim(hex(byte))) (a(3));
     do i = 2 to 4;
       read file(in) into(ch);
       if endfile(in) then leave read_bytes;
       /* Strip control characters from input                      */
       /* and replace with dot.                                    */
       if byte > 31 & byte < 127 then buffer = buffer || ch;
       else buffer = buffer || '.';
       put edit (trim(hex(byte))) (a(3));
     end;
     put edit (' ') (a);
     do i = 1 to 4;
       read file(in) into(ch);
       if endfile(in) then leave read_bytes;
       /* Strip control characters from input                      */
       /* and replace with dot.                                    */
       if byte > 31 & byte < 127 then buffer = buffer || ch;
       else buffer = buffer || '.';
       put edit (trim(hex(byte))) (a(3));
     end;
     put edit (' ') (a);
     do i = 1 to 4;
       read file(in) into(ch);
       if endfile(in) then leave read_bytes;
       /* Strip control characters from input                      */
       /* and replace with dot.                                    */
       if byte > 31 & byte < 127 then buffer = buffer || ch;
       else buffer = buffer || '.';
       put edit (trim(hex(byte))) (a(3));
     end;
     put edit (' ') (a);
     do i = 1 to 4;
       read file(in) into(ch);
       if endfile(in) then leave read_bytes;
       /* Strip control characters from input                      */
       /* and replace with dot.                                    */
       if byte > 31 & byte < 127 then buffer = buffer || ch;
       else buffer = buffer || '.';
       put edit (trim(hex(byte))) (a(3));
     end;
     /* Display ASCII presentation                                 */
     put edit ('|', buffer) (column(62), a(2), a);
     put skip;
     /* Update offset                                              */
     offs += 16;
   end;

   /* Endfile condition might have left some                       */
   /* ASCII values undisplayed                                     */
   if mod(length(buffer),16) ^= 0 then
     put edit ('|', buffer) (column(62), a(2), a);

 end hexdump;

Ohjelman esimerkkitulostus omasta kooditiedostostaan (lyhennetty):

00000000: 2A 50 52 4F  43 45 53 53  20 4D 41 52  47 49 4E 53 | *PROCESS MARGINS
00000010: 28 31 2C 31  32 30 29 20  4C 49 42 53  28 53 49 4E | (1,120) LIBS(SIN
00000020: 47 4C 45 2C  53 54 41 54  49 43 29 3B  0D 0A 2A 50 | GLE,STATIC);..*P
00000030: 52 4F 43 45  53 53 20 4F  50 54 49 4D  49 5A 45 28 | ROCESS OPTIMIZE(
00000040: 32 29 20 44  46 54 28 52  45 4F 52 44  45 52 29 3B | 2) DFT(REORDER);
00000050: 0D 0A 0D 0A  0D 0A 20 68  65 78 64 75  6D 70 3A 20 | ...... hexdump:
00000060: 70 72 6F 63  28 70 61 72  6D 73 29 20  6F 70 74 69 | proc(parms) opti
00000070: 6F 6E 73 28  6D 61 69 6E  29 3B 0D 0A  20 20 20 64 | ons(main);..   d
00000080: 63 6C 20 70  61 72 6D 73  20 63 68 61  72 28 31 30 | cl parms char(10
00000090: 30 29 20 76  61 72 3B 0D  0A 0D 0A 20  20 20 2F 2A | 0) var;....   /*
000000A0: 20 55 6E 69  6F 6E 20 66  6F 72 20 65  61 73 79 20 |  Union for easy
000000B0: 63 68 61 72  61 63 74 65  72 20 76 61  6C 75 65 20 | character value
000000C0: 63 6F 6E 76  65 72 73 69  6F 6E 20 20  20 20 20 20 | conversion
000000D0: 20 20 20 20  20 20 20 20  20 20 20 20  20 20 2A 2F |               */
....
00000E10: 20 20 20 20  20 20 20 20  20 20 2A 2F  0D 0A 20 20 |           */..
00000E20: 20 69 66 20  6D 6F 64 28  6C 65 6E 67  74 68 28 62 |  if mod(length(b
00000E30: 75 66 66 65  72 29 2C 31  36 29 20 5E  3D 20 30 20 | uffer),16) ^= 0
00000E40: 74 68 65 6E  0D 0A 20 20  20 20 20 70  75 74 20 65 | then..     put e
00000E50: 64 69 74 20  28 27 7C 27  2C 20 62 75  66 66 65 72 | dit ('|', buffer
00000E60: 29 20 28 63  6F 6C 75 6D  6E 28 36 32  29 2C 20 61 | ) (column(62), a
00000E70: 28 32 29 2C  20 61 29 3B  0D 0A 0D 0A  20 65 6E 64 | (2), a);.... end
00000E80: 20 68 65 78  64 75 6D 70  3B                       |  hexdump;

Kommentit

Metabolix [26.08.2012 11:48:22]

#

Tuli mieleen, että 8 tavun silmukka on turhaan kopioitu, kun sen voisi myös ajaa silmukalla kaksi kertaa peräkkäin, tai voisi käyttää 16 tavun silmukkaa ja tulostaa välilyönnin if-lauseella, kun i = 8. Lisäksi kohta on endfile(in) jää minusta vielä vähän epäselväksi: miksi rivi tarvitaan, vaikka mitään toimintoa ei aseteta?

Suomenkieliset kommentit olisivat plussaa. Julkaisen kuitenkin vinkin nyt.

Kirjoita kommentti

Muista lukea kirjoitusohjeet.
Tietoa sivustosta