home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / languages / perl / scripts-osu / forms-1.0.shar.1 < prev    next >
Encoding:
Text File  |  1992-04-13  |  21.4 KB  |  591 lines

  1. Newsgroups: comp.lang.perl
  2. Path: cis.ohio-state.edu!zaphod.mps.ohio-state.edu!qt.cs.utexas.edu!cs.utexas.edu!uunet!snorkelwacker.mit.edu!bloom-picayune.mit.edu!math.mit.edu!drw
  3. From: drw@kronecker.mit.edu (Dale R. Worley)
  4. Subject: Forms-oriented input system, documentation
  5. Message-ID: <DRW.92Apr14115354@kronecker.mit.edu>
  6. Sender: news@athena.mit.edu (News system)
  7. Nntp-Posting-Host: kronecker.mit.edu
  8. Organization: MIT Dept. of Tetrapilotomy, Cambridge, MA, USA
  9. Date: Tue, 14 Apr 1992 16:53:54 GMT
  10. Lines: 578
  11.  
  12.                 Forms system
  13.                 version 1.0
  14.                   Design
  15.  
  16. 1. Form
  17.  
  18. A "form" consists of a sequence of "fields".  Each field contains the
  19. information necessary to display and input one value.
  20.  
  21. 2. Input commands
  22.  
  23. At any time, form input is either editing the value of a particular field
  24. ("in a field"), or it is transitting between fields ("out of a field").
  25. Entry into a field is done only when a command is executed which would change
  26. the value of the field; bringing the cursor to rest on a particular field is
  27. not sufficient to enter the field.  Conversely, exiting a field is done only
  28. when some command is executed which would transit to another field, or exit
  29. the form entirely.  However, exiting a field causes its value to be checked 
  30. for validity, and if the validity check fails, the command that caused exiting
  31. of the field is not performed.
  32.  
  33. The commands which are executed out of a field are:
  34.  
  35.     LFD    accept contents of form
  36.         (also C-j)
  37.     C-c    abort the form
  38.         (exits the current field, if any, with C-y, and thus never
  39.         fails)
  40.     RET    go to next field
  41.     TAB    go to previous field
  42.  
  43. The commands which are executed in a field are:
  44.  
  45.     C-y    restore previous value of the field and exit from field
  46.         (bypasses validity check on previous value)
  47.     C-v    perform validity check on field
  48.     C-v C-v exit from field, if it is valid
  49.  
  50.     C-u    clear field
  51.     C-k    clear to end of field
  52.     C-r    clear to beginning of field
  53.  
  54.     C-a    go to beginning of field
  55.     C-e    go to end of field
  56.  
  57.     C-b    go back one character
  58.     C-f    go forward one character
  59.  
  60.     C-d    delete next character
  61.     DEL    delete previous character
  62.         (also C-h)
  63.  
  64. The help commands are:
  65.  
  66.     C-p    give help on current field
  67.     C-p C-p    show help screen describing all commands
  68.  
  69. The help command (C-p) gives help on the field the cursor is in
  70. (whether or not it has been entered) by displaying its help_message
  71. attribute value in the field named MSG.  However, if there is no such
  72. attribute or no field named MSG, or if there is no current field
  73. (because no visible field is writeable), it behaves like C-p C-p.
  74.  
  75. In addition, all printing characters (SPC through ~) are commands to insert
  76. the character into the field value.  Note, however, that the exact meaning
  77. of the in-field commands is determined by the field definition.
  78.  
  79. The function keys can also be used as commands.  See the section
  80. titled "function keys".
  81.  
  82. 3.  Attributes
  83.  
  84. Each field is described by a set of "attributes".  A form is stored in
  85. an associative array, and the attributes of the fields are stored in
  86. elements of the associative array: The value of the attribute $attr of
  87. field $field in form $form is stored in $form{$field,$attr}.  Certain
  88. attributes are used by the forms system as a whole, and are stored with
  89. the null string as field name. 
  90.  
  91. The forms system reserves the package name "forms" for its data and
  92. subroutines.  In addition, the package "forms_user" is used for storing
  93. code and data used by user-written routines.  Names of the form
  94. "forms_generated_0000" are generated by the forms system, and so should
  95. be avoided, both in the two packages and as field names. 
  96.  
  97. 4.  Values
  98.  
  99. A value is represented in three distinct ways.  While this may seem
  100. excessively complicated, it appears to be the only general framework
  101. that handles the myriad possible ways of displaying and inputting field
  102. values in a reasonably extensible way.  The forms of a value are:
  103.  
  104. Attribute "value": The actual value of the field, considered the output
  105. of the form when it is successfully executed, and the input, when the
  106. fields are pre-loaded before the form is executed.  This value can be
  107. any Perl value that can be stored in a scalar. 
  108.  
  109. Attribute "displayed_value": The field, interpreted as a set of
  110. characters.  For example, if the value is to be a number, the displayed
  111. value may be a character representation of the number.  In addition, if,
  112. say, -1 is a special value of the number, the displayed value may code
  113. it as a particular character string, say, "Unknown". 
  114.  
  115. Attribute "displayed_field": The field, as displayed on the screen. 
  116. This attribute is always exactly as long as the field length (attribute
  117. "field"length"), and is what is displayed on the screen.
  118.  
  119. The translation between these forms is as follows:
  120.  
  121. The translation value -> displayed_value is done by the function stored
  122. in attribute construct_displayed_value.  It is called with two
  123. arguments, the field name and the value, and returns the displayed
  124. value.
  125.  
  126. The translation displayed_value -> displayed_field is done by the
  127. function stored in attribute initialize_displayed_field.  It is called
  128. with two arguments, the field name and the displayed value, and
  129. returns the displayed_field.  In addition, it sets the variable
  130. $forms'cursor_location to the correct initial location of the cursor.
  131. (Cursor locations are relative to the beginning of the field, which is
  132. location 0.)  This function is always called upon entry to a field,
  133. thus it may set additional attributes for the field for the user of
  134. the editing functions for the field.
  135.  
  136. The displayed value and displayed field are both edited by the
  137. function stored in attributes "edit" and "insert".  They are called
  138. with two arguments, the field name and the character typed.  The
  139. character is either a printing character (in which case "insert" is
  140. called) or a non-printing character that is not one of the out-field
  141. input command characters listed above (in which case "edit" is
  142. called).  The functions are responsible for updating the displayed
  143. value, the displayed field, and $forms'cursor_location appropriately,
  144. and must also report erroneous input characters.
  145.  
  146. When the field is exited, two further attribute functions are called:
  147. The attribute "validate_displayed_value" is called with two arguments,
  148. the field name and the displayed value.  It returns true if the value of
  149. the field is considered valid, and false if it is not.  If it returns
  150. false, exit from the field is blocked.  If it returns true, the function
  151. stored in attribute "interpret_displayed_value" is called with the field
  152. name and the displayed value as arguments.  It returns the value.  Since
  153. interpret_displayed_value is always called immediately after a
  154. successful call to validate_displayed_value, the latter may set global
  155. variables for the former.  (This is the only circumstance where user
  156. functions can safely set its own global variables.)
  157.  
  158. 5.  Formatting attributes
  159.  
  160. Attribute "label": The text of the label to be applied to the field.
  161.  
  162. Attribute "label_location": Two numbers, seperated by commas, giving the
  163. location of the first character of the label.  (Locations are always given
  164. in the order "row,column", both of which are 0-origin, with the 0 row being
  165. the top row and the 0 column the leftmost column.)
  166.  
  167. Attribute "field_length": The number of characters to be allocated to
  168. the field.  If this attribute is undefined or 0, the field has no
  169. input area, and only its label is relevant.
  170.  
  171. Attribute "field_location": The location of the field.
  172.  
  173. Attribute "read_only": If true, the field may not be entered in.  The
  174. RET and TAB commands skip over the field. 
  175.  
  176. Attribute "invisible": If true, the field and its label are not displayed
  177. and cannot be altered.
  178.  
  179. Attribute "initially_invisible":  Set from attribute "invisible" when
  180. the form array is constructed, and used to restore attribute "invisible".
  181.  
  182. Attribute "canonicalize": If true, when the field is exited, the value
  183. that was created is used to re-calculate the displayed value and the
  184. displayed field. 
  185.  
  186. Attribute "help_message": Displayed by the C-p command when the cursor
  187. is in the field.
  188.  
  189. In addition, there are several attributes that apply to the form as a whole:
  190.  
  191. Attribute "fields": A comma-separated list of the field names, in
  192. their natural order.  A field's position in the natural order is
  193. determined by the location in which it was first given an attribute.
  194. RET cycles through the fields in the natural order, and TAB cycles
  195. through them in the reverse of the natural order.
  196.  
  197. Attribute "initialize": A function to be executed once the form is set up
  198. but before any forms processing is performed.
  199.  
  200. Attribute "finalize": A function to be executed when the form is accepted
  201. with LFD.  If it returns false, the accept is rejected.
  202.  
  203. Attribute "forms_version": This attribute declares that the form
  204. structure conforms to a particular version of the forms package, and
  205. all upward-compatible extensions of it.  If provided, the forms system
  206. checks that it is capable of processing the given version of the forms
  207. structure.  This document describes version 1.0.
  208.  
  209. The field MSG is used to display help messages for fields (via the C-p
  210. command and the help_message attribute) and other messages (via the
  211. report_error and report_message functions).  If it is not present,
  212. these messages are not displayed.
  213.  
  214. 6.  Manipulating other fields
  215.  
  216. The edit_field function or other functions of a field may need to alter
  217. the value or visibility of a field.  If it does so, it should call the
  218. appropriate function:
  219.  
  220. $forms'changed_value($field) is used to signal that the value attribute of
  221. the given field has been changed, and the displayed value and displayed
  222. field should be updated.
  223.  
  224. $forms'changed_visibility($field) is used to signal that the invisible
  225. attribute of the given field has been changed, and the screen should
  226. be updated appropriately.  (It should not be called if the invisible
  227. attribute has not been changed, unless the user makes sure that no
  228. overlapping fields are visible.)  The user is responsible for making
  229. sure that the fields that are visible at a given moment do not
  230. overlap.  If a field that is being made invisible and a field that is
  231. being made visible overlap, the user should be sure to make the one
  232. field invisible before making the other field visible.
  233.  
  234. 7.  Input representation
  235.  
  236. A form can be represented as a sequence of lines of text, or more
  237. exactly, as an array of strings.  (Ending linefeeds on the strings are
  238. ignored.) The representation gives the values of the attributes in a
  239. straightforward way:
  240.  
  241.     field.attribute = value
  242.  
  243. Whitespace around the field and attribute names and the "=" are ignored; 
  244. leading and trailing whitespace around the value is also ignored.
  245. Lines that are entirely whitespace, or whose first non-whitespace character
  246. is "#" are ignored.
  247.  
  248. Attributes of the form as a whole are set in the expected manner:
  249.  
  250.     .attribute = value
  251.  
  252. A line of the form
  253.  
  254.     field:
  255.  
  256. is used to provide a default field name for succeeding attributes.  The
  257. default field name is invoked by omitting the "field." part of the
  258. attribute setting line:
  259.  
  260.     user_name:
  261.         field_location = 2,5
  262.         field_length = 8
  263.  
  264. A line of the form
  265.  
  266.     :
  267.  
  268. provides a generated field name as the default field name.  It is most often
  269. used for fields that have labels but no value.
  270.  
  271. Values are usually interpreted as character strings.  However, certain
  272. values are interpreted differently:
  273.  
  274.     &name
  275.  
  276. This value is interpreted as "*forms_user'name", which is the correct
  277. way to represent functions as attributes. 
  278.  
  279.     &package'name
  280.  
  281. This value is interpreted as "*package'name".
  282.  
  283.     @name
  284.  
  285. This value is interpreted as "*forms'name".  (More exactly, the three
  286. above forms are evaluated directly, after replacing the first
  287. character with "*".  If the first character is "&", it is evaluated in
  288. package forms_user; if it is "@", it is evaluated in package forms.
  289. Thus, "&" is used for functions defined by the user, and "@" is used
  290. for functions supplied by forms.
  291.  
  292.     * expression
  293.  
  294. This value is interpreted by evaluating "expression", in the package
  295. forms_user.
  296.  
  297.     "text"
  298.  
  299. This value is interpreted as "text", allowing characters that would
  300. otherwise be interpreted specially.
  301.  
  302.     field.attribute = {
  303.         text
  304.         };
  305.  
  306. This value is used to construct a subroutine in the forms_user package.
  307. The value itself is interpreted as "*forms_user'<subroutine_name>".
  308. The text of the subroutine is terminated by a line consisting of "};",
  309. possibly with leading and trailing whitespace.
  310.  
  311. Interspersed with the attribute values can be sets of lines with the format
  312.  
  313.     sub name {
  314.         text
  315.         };
  316.  
  317. These forms are used to define subroutines.  They are evaluated in the
  318. forms_user package. 
  319.  
  320. In addition, there can be lines with the format
  321.  
  322.     * expression
  323.  
  324. The expression is evaluated in the package forms_user.
  325.  
  326. Note that "* expression" constructions and subroutines defined in the
  327. forms description are evaluated in the order that they are in the
  328. forms description, at the time that the representation is processed by
  329. &forms'process_representation.
  330.  
  331. The input representation of a form is transformed into an array with
  332. the function:
  333.  
  334.     &forms'process_representation(*array, @representation)
  335.  
  336. where the form attributes will be stored in the associative array %array, 
  337. and the representation is taken from @representation.  The function returns
  338. true if no error is found and false if an error was found.  The error message
  339. is stored in $forms'error.
  340.  
  341. The function can be used to process input representations from files:
  342.  
  343.     &forms'process_representation(*array, <FILE>);
  344.  
  345. and from here-documents:
  346.  
  347.     &forms'process_representation(*array, split(/\n/, <<'EOF'))
  348.     text...
  349.     EOF
  350.  
  351. If the input representation is in a file, a more convenient form can be used:
  352.  
  353.     &forms'process_representation_from_file(*array, $file_name, $inc)
  354.  
  355. This function reads the representation from the given file and processes it.
  356. In addition, if $inc is true, @INC is searched for $file_name, just as require
  357. does.  If the file does not exist, the function aborts execution.
  358.  
  359. These functions set certain attributes in addition to those that are mentioned
  360. in the input representation:  "initially_invisible" is set from "invisible",
  361. and "fields" is set to be the list of fields in the form.
  362.  
  363. 8.  Processing forms
  364.  
  365. Several functions are used to process forms:
  366.  
  367.     &forms'clear_values(*array)
  368.  
  369. This function clears (sets to undef) all of the value attributes of the given
  370. form.  It is used to clear a form in preparation for further input.
  371.  
  372.     &forms'clear_values_and_redisplay
  373.  
  374. This function is used during forms input to clear all of the value
  375. attributes and force redisplay of all the fields (via
  376. &forms'changed_value).
  377.  
  378.     &forms'reset_visibility(*array)
  379.  
  380. This function sets the invisible attributes from the initially_invisible
  381. attributes. 
  382.  
  383.     &forms'process_form(*array)
  384.  
  385. This form displays the given form and gets the user's input.  Initially
  386. displayed values are obtained from the value attributes of the form, and
  387. the returned values are returned in the value attributes.  The function
  388. returns true if the form as accepted and false if it was aborted.  During
  389. execution of the form, %forms'form is aliased to %array.  &forms'process_form
  390. is not intended to be executed recursively.
  391.  
  392.     &forms'dump_form(*array, filehandle)
  393.  
  394. Prints out all of the attributes in a form.  If filehandle is omitted,
  395. STDOUT is used.
  396.  
  397. 9.  Service routines
  398.  
  399.     &forms'report_message(text)
  400.  
  401. is used to display a message in the field named MSG (if there is one).
  402.  
  403.     &forms'report_error(text)
  404.  
  405. is used to display an error message in the MSG field.  (It performs a
  406. report_message and then rings the bell.)
  407.  
  408. 10.  Function keys
  409.  
  410. The function keys can be used as commands if they are defined by a
  411. form.  Function keys are typed as:
  412.  
  413.     ESC
  414.     single optional 'O' or '['
  415.     zero or more characters in the range '!' to '?'
  416.     one character '@' or greater
  417.  
  418. (This should probably be changed to a more flexible system.)  They are
  419. translated into function key identifications (F1 through F10) by the
  420. table %forms'function_key.  The function key identifications for F1 to
  421. F9 are loaded from the 'k1' through 'k9' capabilities from the termcap
  422. entry, and the F10 identification is taken from the 'k;' capability
  423. (or if it is not present, the 'k0' capability).  In addition, several
  424. standard function key codes are loaded:
  425.  
  426.     Key     Sun     Sun     VT100   Manual typing    Termcap
  427.  
  428.     F1      \e[224z \e[11~  \eOP    \e1f    \e1F    k1
  429.     F2      \e[225z \e[12~  \eOQ    \e2f    \e2F     k2
  430.     F3      \e[226z \e[13~  \eOR    \e3f    \e3F     k3
  431.     F4      \e[227z \e[14~  \eOS    \e4f    \e4F     k4
  432.     F5      \e[228z \e[15~          \e5f    \e5F     k5
  433.     F6      \e[229z \e[17~          \e6f    \e6F     k6
  434.     F7      \e[230z \e[18~          \e7f    \e7F     k7
  435.     F8      \e[231z \e[19~          \e8f    \e8F     k8
  436.     F9      \e[232z \e[20~          \e9f    \e9F     k9
  437.     F10     \e[-1z  \e[21~          \e0f    \e0F     k; or k0
  438.                     \e10f   \e10F
  439.  
  440. A function key is considered "local" if the cursor is sitting in a
  441. field and that field has an attribute "F1" (or whatever).  A function
  442. key is considered "global" if it is not local and there is a global
  443. attribute "F1" (or whatever).  Escape sequences that are neither local
  444. nor global produce an error message.  If a local function key is
  445. given, the field is enterd (if it has not been) and the function named
  446. by the attribute is executed.  If a global function key is given, the
  447. field is exited (if it has not been) and the function named by the
  448. attribute is executed.
  449.  
  450. 11. Problem with curseperl
  451.  
  452. Curseperl has an ugly problem.  The following program does not do what
  453. is expected (clear the screen) when $ARGV[0] is true:
  454.  
  455.     $ENV{'TERM'} = 'vt100';
  456.     &initscr;
  457.     if ($ARGV[0]) {
  458.         &getcap('k1');
  459.         &getcap('k2');
  460.         &getcap('k3');
  461.         &getcap('k4');
  462.     }
  463.  
  464.     &clear;
  465.     &refresh;
  466.     &getch;
  467.  
  468. (This is using BSD curseperl on a Sun4 with SunOS 4.1.1)
  469.  
  470. getcap is just a wrapper for termcap's tgetstr, *using a fixed
  471. internal buffer to collect the results from tgetstr*.  It appears that
  472. this internal buffer has a finite size, and each successive return
  473. value is written after the previous one, so if you do a few too many
  474. getcap's, you write off the end of the buffer...
  475.  
  476. A solution which appears to work is to change the interface for
  477. &getcap to call tgetstr directly, but to supply a new buffer each
  478. time.  The patch for this is follows.  It is necessary to install this
  479. patch, because forms.pl uses getcap() when it is loaded.  If this
  480. patch can't be installed, you have to comment out the calls to
  481. &'getcap in subroutine load_function_keys.  This may disable the
  482. function keys defined in the termcap entry for the user's terminal.
  483.  
  484. *** bsdcurses.mus.old    Thu Apr  9 16:40:41 1992
  485. --- bsdcurses.mus    Thu Apr  9 16:41:18 1992
  486. ***************
  487. *** 476,484 ****
  488.   CASE int erasechar
  489.   END
  490.   
  491. ! CASE char* getcap
  492. ! I    char*        str
  493. ! END
  494.   
  495.       case US_getyx:
  496.       if (items != 3)
  497. --- 476,493 ----
  498.   CASE int erasechar
  499.   END
  500.   
  501. !     case US_getcap:
  502. !     if (items != 1)
  503. !         fatal("Usage: &getcap($str)");
  504. !     else {
  505. !         char* retval;
  506. !         char*    str =        (char*)        str_get(st[1]);
  507. !         char output[50], *outputp = output;
  508. !         retval = tgetstr(str, &outputp);
  509. !         str_set(st[0], (char*) retval);
  510. !     }
  511. !     return sp;
  512.   
  513.       case US_getyx:
  514.       if (items != 3)
  515.  
  516. 12. Standard field types
  517.  
  518. The forms system contains routines for inputting various standard
  519. field types.
  520.  
  521. - Ordinary text fields
  522.  
  523. Ordinary text fields can be implemented with the attributes:
  524.  
  525.     construct_displayed_value = @char_field
  526.     initialize_displayed_field = @id_cursor_after
  527.     validate_displayed_value = @true
  528.     interpret_displayed_value = @trim_trailing_space
  529.     insert = @text_insert
  530.     edit = @text_edit
  531.  
  532. When the field is entered, the cursor is placed after the first
  533. non-blank character of the value.  When the field is exited, the
  534. contents of the field have trailing spaces removed, and the remainder
  535. is the field vbalue.
  536.  
  537. - Hidden text fields
  538.  
  539. Hidden text fields are just like ordinary text fields, except that the
  540. field value is not displayed -- the characters of the value (up to the
  541. last non-blank character) are displayed as periods (".").  Hidden text
  542. fields are good for inputting passwords and similar things.  They can
  543. be implemented with the attributes:
  544.  
  545.     construct_displayed_value = @char_field
  546.     initialize_displayed_field = @id_cursor_after_hidden
  547.     validate_displayed_value = @true
  548.     interpret_displayed_value = @trim_trailing_space
  549.     insert = @text_insert_hidden
  550.     edit = @text_edit_hidden
  551.  
  552. - Enumerated fields
  553.  
  554. Enumerated fields allow one of a set of values to be selected.  Each
  555. value is represented by one of a set of "representations", which are
  556. what is displayed to the user and what the user types in the field to
  557. specify a value.  The set of permissible values and their
  558. representations are specified by the attribute "translate_table",
  559. which is a list of items of the form "representation=value", separated
  560. by backslashes ("\").  The representations and values are searched for
  561. in translate_table, so they may not contain backslashes or equal
  562. signs.  In addition, representations are recognized
  563. case-insensitively, while values are represented case-sensitively.
  564. When a value is translated to a representation, the first
  565. representation listed is chosen.  A value that does not have a
  566. representation should not be present.  A representation that does not
  567. have a value will be rejected as invalid.  An example of an enumerated
  568. field with the translation table
  569.  
  570.     Value    Representation
  571.     1    Yes    (preferred representation)
  572.     1    Y
  573.     0    No    (preferred representation)
  574.     0    N
  575.  
  576. is constructed by:
  577.  
  578.     construct_displayed_value = @enum_field
  579.     initialize_displayed_field = @id_cursor_after
  580.     validate_displayed_value = @enum_validate
  581.     interpret_displayed_value = @enum_interpret
  582.     translate_table = Yes=1\Y=1\No=0\N=0\=0
  583.     insert = @text_insert
  584.     edit = @text_edit
  585.     canonicalize = 1
  586.  
  587. In this case, "canonicalize" is set, so that upon field exit the
  588. value is displayed in the preferred representation.
  589.  
  590.