home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_100 / 181_01 / cforum.1_2 < prev    next >
Text File  |  1986-01-09  |  8KB  |  164 lines

  1. Reprinted from: Micro/Systems Journal, Volume 1. No. 2. May/June 1985   
  2. -----------------------------------------------------------------
  3. Copy of back issue may be obtained for $4.50 (foreign $6) from:
  4. Subscriptions are $20/yr, $35/2yrs domestic (published bimonthly)
  5. Micro/Systems Journal
  6. Box 1192
  7. Mountainside NJ 07092
  8. -----------------------------------------------------------------
  9. Copyright 1986
  10. Micro/Systems Journal, Box 1192, Mountainside NJ 07092
  11. This software is released into the public domain for
  12.  non-commercial use only.
  13. -----------------------------------------------------------------
  14.  
  15. THE C FORUM  
  16.  
  17. by Don Libes
  18.  
  19. Writing a translation program in C
  20.  
  21.      This month, I would like discuss building a translation 
  22. program using the C language that is in the style of a UNIX 
  23. filter.  I mean it to be educational rather than practical, so I 
  24. have forsaken completeness and instead concentrated on ideas and 
  25. program readability.  My intent is that you should be able take 
  26. what I've given you here and build on it.
  27.      My example will be a program to "undecipher" WordStar 
  28. document files.  It's been a while since I've used WS, but for a 
  29. long time it was my primary tool for word processing.  More and 
  30. more, I find myself using other editors and text processors.  
  31. Some of the reasons are:
  32.  
  33. 1) WS doesn't support high quality devices such as laser 
  34. printers.
  35.  
  36. 2) WS doesn't support bitmapped screens.
  37.  
  38. 3) WS isn't as sophisticated as newer editors and text 
  39. processors.
  40.  
  41. 4) WS isn't integrated with other programs that use text files.
  42.  
  43.      WS's lack of integration is one of its more annoying traits.  
  44. If you're like me, you've probably typed in a good many documents 
  45. through WS.  Now, say we want to use a WS-text file as input to 
  46. another program or even another computer system to be integrated 
  47. into a non-WS document.  We've got problems.
  48.      If you've ever printed a raw WS document file on your screen 
  49. (without going through WS), you will have already noticed that 
  50. there is more in the file than just the text.  If you haven't, 
  51. try it.  You will notice that most of the text appears, but some 
  52. of the characters are wrong and there are a lot of non-printable 
  53. characters embedded in the file.
  54.      All the information is there, but WS uses the high-order bit 
  55. in the byte for information as well as including extra bytes for 
  56. print control characters.  Unfortunately, MicroPro will not give 
  57. out the format of their WS document files, but don't let that 
  58. disuade you.  It's not that difficult to decipher.
  59.      Due to space limitations, I simply can't cover all the 
  60. goodies in WS. I've restricted myself to the things you are most 
  61. likely to see, however, and following my lead, it should not be 
  62. hard to extend what I've given you.
  63.      If you want to probe your own files, try loading them into 
  64. the debugger and dumping the file so that you can see the byte 
  65. codes alongside the ASCII characters.  After some studying it 
  66. should become clear.  This is what I found:
  67.  
  68. 1. Some characters have their most significant bit (MSB) on.  
  69. This is used to denote several things (see below).
  70. 2. Lines are terminated with cr-lf sequences.
  71.  
  72. 3. Dot cmds (e.g. ".op") appear in the file verbatim.
  73.  
  74. 4. Blanks, with the MSB on, are soft, meaning they have been 
  75. added automatically by WS to pad out the line.
  76.  
  77. 5. Hyphens, with the MSB on, are soft, having been added by a 
  78. rejustify operation (although potentially with user guidance).
  79.  
  80. 6. Linefeeds, with the MSB on, are soft, having been added 
  81. automatically.  Hard linefeeds denote the end of a paragraph.
  82.  
  83. 7. WS print control characters (e.g. ^B) appear in the file 
  84. verbatim.
  85.  
  86. 8. Tabs do not appear in the file, but are stored as blanks.
  87.  
  88. 9. All other characters appear as themselves in the file.  
  89. Characters at the ends of words in paragraphs that have been 
  90. justified have their MSB on.
  91.      Assuming that we want to transfer this file to another 
  92. computer system, we must change the file so that it looks like an 
  93. ordinary text file.  This means that we have to do things like 
  94. get rid of the high-order bits and remove the WS-dependent 
  95. directives like the dot commands and the print control 
  96. characters.
  97.      Accompanying this column is a program I've written that 
  98. handles the basic problems of "unsofting" a WS document file.  
  99. Most of the more esoteric features aren't handled.  However, 
  100. given the start, you should be able to easily add the code to 
  101. handle any additional conditions you find really necessary.
  102.      You can also customize it to your application.  With some 
  103. simple changes it could be used to generate troff files, for 
  104. example.  The conventions I have chosen to use actually mimic 
  105. "wsconv", a public domain program from the PC/BLUE software 
  106. library (distributed without source, unfortunately), author 
  107. unknown.
  108.      I'll briefly go through some of the more interesting parts 
  109. of the program.  I will refer to source lines by the the numbers 
  110. running down the left hand side of the program listing.
  111.      The program is written in the style of a typical UNIX 
  112. filter.  It copies its input to its output with appropriate 
  113. modifications.  Internally, the program sits in a loop, reading 
  114. one character at a time.  Based on the character attributes and 
  115. the current state, the character is printed out and/or the state 
  116. is changed.
  117.      Lines 13-17 define and use #CONTROL.  This macro generates 
  118. control character values given the corresponding letter.
  119.      Lines 19-26 define the conventions for handling WS print 
  120. control characters.  For example, an underlined string will print 
  121. out as <_string_>.  We actually use this convention when sending 
  122. files to our typesetter.
  123.      Line 28: Anything declared as "boolean" should only have the 
  124. value TRUE or FALSE.  This is purely a semantic interpretation 
  125. since "boolean" is typedef'ed to "int".
  126.      Lines 33-46 define several state variables that will be used 
  127. to make decisions along with the next character.
  128.      Lines 53-56: Our first problem is turning off the 8th bit on 
  129. all characters.  This is done by #toascii, defines in <types.h>.  
  130. To remember that the bit was on, we use msb_was_set.
  131.      Lines 57-61: WS terminates lines with a crlf.  Assuming our
  132. system terminates lines with a nl (like a UNIX system), we can just
  133. disregard the cr.  If a hyphen added by a justify operation is
  134. encountered, we attempt to remove it by delaying line wrap until we see
  135. the real end of the current word.
  136.      Lines 62-64: For lack of space, I have chosen to ignore 
  137. handling dot commands.  They can be handled here without any 
  138. problems.
  139.      Lines 65-75: Spaces come in two flavors - soft and hard.  
  140. Hard ones are real, but soft ones have been added by a 
  141. justification operation.  Tabs are denoted by hard spaces, so 
  142. we'll try to undo that too.
  143.      Line 79 recognizes the start of a dot command.
  144.      Lines 82-85: Handle WS print control characters.  wscntrl() 
  145. does everything.  iswscntrl() just recognizes the characters.
  146.      Lines 86-88: Remove all the other ws control characters we 
  147. are too lazy to correctly handle.
  148.      Lines 89-104: If the character hasn't been handled at this 
  149. point, its got to be text, which is just passed through.  If 
  150. we're at the beginning of a word, we also perform the 
  151. translation of spaces back to tabs here by calling space_out().
  152.      Lines 108-130 define space_out().  This routine takes a 
  153. source and destination column, and prints out the least number 
  154. of tabs and spaces to move the cursor to the destination column.
  155.      Lines 152-180 define wscntrl().  This translates control 
  156. character directives into printable versions.
  157.  
  158.      I encourage readers to write to me about topics or problems 
  159. that you want to know about.  I want this column to reader 
  160. driven.  Write to me care of Micro/Systems Journal, Box 1192, 
  161. Mountainside NJ 07092.
  162.  
  163. Source code will be found in a separate file.
  164.