[comp.sys.handhelds] HP28: HPREAD Utility Programs

jdg@hpqtdla.HP.COM (James Gentles) (03/16/90)

  
  Is anyone out there still using Mark Adler's HPREAD1.3 to get data into your
  PC from your HP28? Here are two C programs that enhance Mark's excellent   
  efforts. 

  The HPREAD1.3 output on the PC is a little strange with the 28's special
  characters mapping to some strange characters in the PC's extended character
  set. I have written some code to decypher the characters and then format
  the output a little better. These are my first two programs written in C
  so please forgive the style. Also they are not bomb proof.
  
  My main use of HPREAD is for printing, archiving and posting programs on
  notes / email. My notes / email system is a HP mainframe, and its best to
  use 7bit ASCII with it, so my need for HPTRANS. HPTRANS replaces all the
  HP28 special characters (128 to 255) with strings of standard characters.
  The common characters like not equals are replaced with <> but the more
  obscure characters are replaced with strings with $ at the end as a clue
  to the reader that a character has been replaced. e.g. e acute is "e/$".
  All 128 characters from 128 to 255 are replaced with the corresponding string
  in a data file HPTABLE.ASC. The program also constructs a table of strings
  used at the end of the output. Stdin and Stdout are used. By modifying the
  HPTABLE.ASC file it should be possible to map HP28 ASCII to MS-DOS ASCII
  if you wanted to keep your files on the MS_DOS machine.
  
  HPFORMAT takes the output of HPTRANS and tidies it up. This is not perfect,
  but it does cut down the work required to produce a 'pretty' output. It
  maintains the hp28's indenting structure with the following rules.
  1. Line length is between 40 and 50 ( NOT 23). The line will end on a
     space, ', ), *, +, or when the line is 50 characters long.
  2. The output maintains the indent when it scrolls onto the next line, unlike
     the HP28 which starts at the beginning of the next line
  Possible Bugs: The indenting should be clamped to be less than the line
                 length, this is easy to fix, I havent got round to it yet.
                 It is sometimes unclear whether the input c/r is because of
                 wrap-around or because it wants a c/r. Currently this criterion
                 is used - IF more than 18 chars into the line then its a wrap-
                 around, else its a c/r. This is open to errors, a better 
		 solution is conceivable but the code begins to get more complex
                 The un-indenting is wrong, this is not a problem as very few
                 HP28 programs have commands during this period >> >> >>.
  Again HPFORMAT uses stdin and stdout
 

 
  Sample input and output:
  
  The following HP28 program "FMTTIME" was uploaded using HPREAD
  FMTTIME
  S RCLF 58 CHR Y t f
  c
    S t 10000 * IP
  10000 / 't' STO
      IF t 12 I
      THEN t 12 - 't'
  STO " pm"
      ELSE " am"
      END
      IF t 1 <
      THEN t 12 + 't'
  STO
      END t IP STD
  YSTR c + t FP 4 FIX
  YSTR DUP 3 4 SUB c +
  SWAP 5 6 SUB + +
  SWAP + f STOF
    B
  B
  
  Notice the short line length, poor indentation and illegible characters. Put
  this through HPTRANS to get: 
  FMTTIME
  << RCLF 58 CHR -> t f
  c
    << t 10000 * IP
  10000 / 't' STO
      IF t 12 >=
      THEN t 12 - 't'
  STO " pm"
      ELSE " am"
      END
      IF t 1 <
      THEN t 12 + 't'
  STO
      END t IP STD
  ->STR c + t FP 4 FIX
  ->STR DUP 3 4 SUB c +
  SWAP 5 6 SUB + +
  SWAP + f STOF
    >>
  >>
   
   
   
  SYMBOL KEY:
   
  >=  138:-Greater_than_&_equal_to
   
  ->  141:-Right_hand_arrow
   
  <<  146:-Start_program_construct
   
  >>  147:-End_program_construct
  
  
  Note that all the special characters have been replaced and a SYMBOL TABLE
  added. Finally put this through HPFORMAT
  FMTTIME
  << RCLF 58 CHR -> t f c
    << t 10000 * IP 10000 / 't' STO
      IF t 12 >=
      THEN t 12 - 't' STO " pm"
      ELSE " am"
      END
      IF t 1 <
      THEN t 12 + 't' STO
      END t IP STD ->STR c + t FP 4 FIX ->STR 
      DUP 3 4 SUB c + SWAP 5 6 SUB + + SWAP 
      + f STOF
    >>
  >>
   
   
   
  SYMBOL KEY:
   
  >=  138:-Greater_than_&_equal_to 
  ->  141:-Right_hand_arrow 
  <<  146:-Start_program_construct 
  >>  147:-End_program_construct *
  
  Thats the final output.
  
  There now follows 2 C source files and an ascii file which you can compile
  to do the above. I hope this has been of interest, comments by email/notes 
  appreciated.

  Many Thanks   
  James Gentles
  
  ---------------------------------------------------------------------
        I have no professional connection with Hewlett-Packard's 
      calculator operations other than as a user of their products.
  ---------------------------------------------------------------------
  Opinions expressed are my own, and are not intended to be an official
                statement by Hewlett-Packard Company
  ---------------------------------------------------------------------
  Name:         James Gentles   GM4WZP
  Organization: Hewlett-Packard  Queensferry Telecomunications Division
  Email:        jdg@hpqtdla.hp.com                               hp-sdd 
  Address:      Station Road, South Queensferry, West Lothian, Scotland
  ---------------------------------------------------------------------
  ------------HPTRANS.C-----------cut_here_and_disgard_this_line--------------
  
  /*
  HPTRANS   Revision 1.0   James Gentles   27th Feb 1990   jdg@hpqtdla.hp.com
   
  This program accepts from stdinput a file created by the HPREAD program from
  the HP28's IR link. This file is coded in the HP28 version of ASCII which
  has special characters in locations 128-255. This program takes a file of
  replacement characters (HPTABLE.ASC) and replaces the special HP28 characters.
  The output to stdoutput is a file with all the special characters replaced
  with a string of 1 or more characters from the look up table.
  */
   
  #include <stdio.h>
   
  main()
  {
  int c;
  int i;
  int j;
   
  char string[128][10];
  int  keyflag[128];
  char keychar[128][60];
   
  FILE  *fopen(), *tableF;
   
  tableF = fopen("HPTABLE.ASC" , "r");
   
  i=1;
  while (i <= 128)
      {
      fscanf(tableF, "%s", string[i] );    /* Suck in 128 sets of 2 strings   */
      fscanf(tableF, "%s", keychar[i]);    /* from HPTABLE.ASC                */
      Skeyflag[i]=0;
      i+=1;
      }
  while ((c = getchar()) != EOF)
       if (c <= 127)                    /* CHR 0 to 127 pass straight through */
            putchar(c);
       else
            {
            printf("%s" , string[(c-127)]);/* ELSE replace with string from   */
            keyflag[(c-127)] = 1;          /* HPTABLE.ASC and set keyflag     */
            }
  printf("\n \nSYMBOL KEY:\n");            /* Print Heading for Table         */
  i=1;                                     /* then print strings that have    */
  while (i <=128)                          /* been used in listing.           */
        {
        if(keyflag[i] ==1) printf("\n%s  %s\n" , string[i], keychar[i] );
        i+=1;
        }
  }
  ------------HPTABLE.ASC---------cut_here_and_disgard_this_line--------------
  space$ 128:-Blank
  div$ 129:-Division_line&dots
  mul$ 130:-Multiply_cross
  SQRT 131:-Square_root_symbol
  int$ 132:-Integral
  sig$ 133:-Sigma
  |>$ 134:-Triangular_right_arrow
  pi 135:-Symbolic_constant
  delta$ 136:-Greek_delta
  <= 137:-Less_than_&_equal_to
  >= 138:-Greater_than_&_equal_to
  <> 139:-Not_equal_to
  alpha$ 140:-Greek_alpha
  -> 141:-Right_hand_arrow
  <- 142:-Left_hand_arrow
  micro$ 143:-10E-6
  lf$ 144:-L/F_symbol
  deg$ 145:-Degree_symbol
  << 146:-Start_program_construct
  >> 147:-End_program_construct
  |-$ 148:-T_on_side
  1 149:-Subscript_1
  2 150:-Subscript_2
  2 151:-Superscript_2
  3 152:-Superscript_3
  ; 153:-Subscript/inverse_;
  j 154:-Subscript_j
  .. 155:-Double_dot
  ; 156:-Superscript/inverse_;
  ; 157:-Superscript_j
  k 158:-Superscript_k
  n 159:-Superscript_n
  ang$ 160:-Angle_from_horizontal
  A\$ 161:-A_grave
  A^$ 162:-A_circumflex
  E\$ 163:-E_grave
  E^$ 164:-E_circumflex
  E..$ 165:-E_umlaut
  I^$ 166:-I_circumflex
  I..$ 167:-I_umlaut
  /$ 168:-acute
  \$ 169:-grave
  ^ 170:-circumflex
  ..$ 171:_umlaut
  ~ 172:-tilde
  u\$ 173:-u_grave
  u^$ 174:-u_circumflex
  pnd$ 175:-UK_pounds
  - 176:-High_underscore
  v/$ 177:-v_acute
  y/$ 178:-y_acute
  deg$ 179:-Degree_symbol
  C,$ 180
  c,$ 181
  Nv$ 182
  n~$ 183:-n_tilde
  i 184:-Italic_i
  ?$ 185:-Inverted_?
  XO$ 186
  pnd2$ 187:-pound,only_1_bar
  YT$ 188
  sect$ 189:-Section_mark
  f 190:-Italic_f
  c|$ 191:-
  a^$ 192:-a_circumflex
  e^$ 193:-e_circumflex
  o^$ 194:-o_circumflex
  u^$ 195:-u_circumflex
  a/$ 196:-a_acute
  e/$ 197:-e_acute
  o/$ 198:-o_acute
  u/$ 199:-u_acute
  a\$ 200:-a_grave
  e\$ 201:-e_grave
  o\$ 202:-o_grave
  u\$ 203:-u_grave
  a..$ 204:-a_umlaut
  e..$ 205:-e_umlaut
  o..$ 206:-o_umlaut
  u..$ 207:-u_umlaut
  Ao$ 208:-
  i^$ 209:-i_circumflex
  /O$ 210:-Greek_PHI
  AE$ 211:-
  ao$ 212:-
  i/$ 213:-i_acute
  /o$ 214:-Greek_phi
  /x$ 215:-
  A 216:-A_umlaut
  i\$ 217:-i_grave
  U..$ 218:-U_umlaut
  u..$ 219:-u_umlaut
  E/$ 220:-E_acute
  i..$ 221:-i_umlaut
  beta$ 222:-Greek_beta
  o^ 223:-o_circumflex
  A/$ 224:-A_acute
  A~$ 225:-A_tilde
  a~$ 226:-a_tilde
  -D$ 227:-
  delta+$ 228:-
  I/$ 229:-I_acute
  I\$ 230:-I_grave
  o/$ 231:-o_acute
  o\$ 232:-o_grave
  O~$ 233:-O_tilde
  o~$ 234:-o_tilde
  Sv$ 235:-
  sv$ 236:-
  U/$ 237:-U_acute
  Y/$ 238:-Y_acute
  y..$ 239:-y_umlaut
  P 240:-
  |o$ 241:-
  . 242:-Dot
  micro$ 243:-1E-6
  ||$ 244:-
  3/4$ 245:-Fraction_3/4
  - 246:-Long_minus
  1/4$ 247:-Fraction_1/4
  1/2$ 248:-Fraction_1/2
  a_$ 249:-
  o_$ 250:-
  << 251:-Start_program_construct
  [] 252:-Solid_block
  >> 253:-End_program_construct
  +-$ 254:-Plus/minus
  space$ 255:-Blank
  -----------------------------------------------
  HPTABLE.ASC Look-up Table for HPTRANS Programme
  Revision 1.0  27th Feb 1990  jdg@hpqtdla.hp.com
   
  The first  128 lines of  this file  contain two
  strings per line,  representing a look-up table
  to translate 8bit HP28 characters to 7bit ASCII.
  The 128 lines represent character codes 128-255,
  string one is the ASCII replacement string, and
  string two is a description used in a key table.
  ------------HPFORMAT.ASC--------cut_here_and_disgard_this_line--------------
  /*
  HPFORMAT  Revision 1.0  James Gentles  27th Feb 1990  jdg@hpqtdla.hp.com
   
  This program is used to format the output from a HP28 calculator via
  its IR link via HPREAD. It is suggested that the text be put through
  HPTRANS first to remove any special characters.
  The program takes the input on stdinput and sends the formatted output
  to stdoutput. The 23 column input is changed to approximately 45 column,
  and the HP28's indenting is maintained.i
  This program will only work with computers using the ASCII code
   
  This source is written in C
   
  */
   
  #include <stdio.h>
   
  main()
  {
  int c;
  int i;
  int tindent;
  int indent;
  int linelength;
  int linepos;
  int iplinepos;
  int tiplpos;
   
  iplinepos = 0;
  tiplpos = 0;
  linepos = 1;
  indent = 0;
  tindent= 0;
  linelength=40;
  while ((c = getchar()) != EOF)
       {
       iplinepos+=1;             /* Keep track of stdinput column */
       if (c == '\n')
            {
            tiplpos = iplinepos;
            iplinepos=0;
            tindent = 0;
            do
                 {
                 c = getchar();  /* if c/r count number of spaces (indent) */
                 iplinepos+=1;   /* at beginning of the next line          */
                 if (c == 32)
                      tindent+=1;
                 }
             while (c == 32);
             if (tindent != 0)   /* set up new indent and send it to stdop */
                 {
                 indent = tindent;
                 putchar('\n');
                 for (i =1; i <= indent; i+=1)
                      putchar(32);
                 linepos = indent + 1;
                 }
             else
                 if (tiplpos < 15)
                      putchar('\n'); /* if no indnet and near beginning of  */
                                     /* line then start new line            */
                 else
                      putchar(32);   /* ignore c/r and replace with space   */
             putchar(c);
             if (c!='\n')
                  linepos+=1;        /* Increment output column unless c/r  */
             else
                  linepos =1;
             }
        else
             {
             putchar(c);
             linepos+=1;
             }
        if ((linepos >= linelength) && ((c==32) || (c==39) || (c==41) ||
                         (c==42) || (c==43) || (linepos>= (linelength + 10)) ))
            {      /* at convenient point at end of output line do a c/r */
            putchar('\n');
            for (i = 1; i <= indent; i+=1)
                 putchar(32);
            linepos = indent + 1;
            }
       }
   
  }