home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / GET10.ZIP / GET.DOC next >
Encoding:
Text File  |  1988-11-09  |  73.1 KB  |  1,780 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9.  
  10.  
  11.                                 THE GET UTILITIES
  12.  
  13.  
  14.                                    Version 1.0
  15.                                 9th Novemer, 1988
  16.  
  17.                          Copyright (c) 1988 Paul O'Nolan
  18.  
  19.  
  20.  
  21.  
  22.  
  23.  
  24.  
  25.  
  26.             ┌──────────────────────────────────────────────────────┐
  27.             │ All you can take with you is what you've given away. │
  28.             └──────────────────────────────────────────────────────┘
  29.                                  Old Arab saying
  30.  
  31.  
  32.  
  33.  
  34.                                 Table of Contents
  35.  
  36.         Preface ....................................................... 2
  37.  
  38.         Distribution of this package .................................. 4
  39.  
  40.         Acknowledgements .............................................. 4
  41.  
  42.         Introduction .................................................. 5
  43.  
  44.         Units used by GET ............................................. 8
  45.  
  46.         The GET unit procedures ....................................... 9
  47.  
  48.         GETCHAR ....................................................... 9
  49.  
  50.         GETRESPONSE ................................................... 9
  51.  
  52.         GETBOOLEAN ................................................... 10
  53.  
  54.         GETDIGIT ..................................................... 10
  55.  
  56.         GETSTRING .................................................... 11
  57.  
  58.         GETNUM ....................................................... 19
  59.  
  60.         GETREAL ...................................................... 20
  61.  
  62.         GETDATESTRING ................................................ 23
  63.  
  64.         GETTIMESTRING ................................................ 25
  65.  
  66.         GETATTR ...................................................... 25
  67.  
  68.         DATES IN GENERAL ............................................. 26
  69.  
  70.         ADDENDUM ..................................................... 28
  71.  
  72.         RELEASE NOTES ................................................ 28
  73.  
  74.  
  75.                                  IMPORTANT NOTE
  76.  
  77.         This software uses the copyrighted QWIK routines from Eagle
  78.         Performance Software which have been included, in the form of a
  79.         TPU file, by permission. Those who want to use this product must
  80.         be registered for QWIK.  Registration can be obtained from:
  81.  
  82.            Eagle Performance Software
  83.            TP products
  84.            Attn: James H. Le May
  85.            P.O. Box 122237
  86.            Ft. Worth, TX  76121
  87.  
  88.  
  89.  
  90.  
  91.  
  92.  
  93.                                                     GET utilities  Page 1
  94.  
  95.  
  96.         Preface
  97.  
  98.         To European readers
  99.  
  100.         Ever been tempted to pay for some American shareware with a
  101.         cheque dated in mm/dd/yy format -- knowing that it would bounce
  102.         as result? I hope not, but I wouldn't be surprised. It would be a
  103.         mean way of making a point even if it needs making badly. Our
  104.         support is expected without much effort to earn it.
  105.  
  106.         Have you decided against supporting certain programs that are
  107.         shareware in the US and sold as cut down commercial rip offs in
  108.         Europe? I hope so.
  109.  
  110.         American shareware authors are aggrieved at our lack of support.
  111.         In general, they are unaware of the reasons for this. Write to
  112.         them.
  113.  
  114.         You may register as a user of this package by sending me the
  115.         equivalent of US $1.
  116.  
  117.  
  118.         To American readers:
  119.  
  120.         I have an admission to make. Although I use many US originated
  121.         shareware programs, I have registered as a user of only a few --
  122.         and all when I lived in the US recently (as a graduate student)
  123.         and had a $ check book. With your help I'd like to remedy this.
  124.  
  125.  
  126.         Excuses, Excuses
  127.  
  128.         I have excuses for not registering ALL the US shareware I use.
  129.         It's overpriced, it's a hassle logistically, I hardly ever use
  130.         some programs etc. You know the score. If we (this means you too)
  131.         paid the asking price for all of what we use we'd be much poorer,
  132.         though not as impoverished as we'd be if shareware disappeared.
  133.         There's no denying that Vern Buerg -- whose LIST program I have
  134.         not registered -- ought to be a millionaire from the popularity
  135.         of LIST. I don't know anyone who doesn't use it and I don't know
  136.         anyone who's paid for it. There's something wrong here! Have YOU
  137.         paid for it? Are you using it? Right now?!
  138.  
  139.         I'd like to see software authors do well out of programs as
  140.         popular as LIST. Most of us would. I'd have given Dando Shaft a
  141.         $1 but I'd have baulked at $25. With so many aspiring
  142.         millionaires attaching importunate messages to their programs
  143.         it's all too easy to ignore the requests for support from those
  144.         that deserve it. This is not to deny anyone's right to ask for
  145.         what they want or our debt to the software authors whose work we
  146.         use. I think part of the problem is that we are spoiled for
  147.         choice and don't always agree that a program is worth what the
  148.         author asks for it.
  149.  
  150.         I'd be a lot happier and I think a lot of shareware authors would
  151.         be richer if they asked for no more than they would get from the
  152.         royalty on a book. I'd cheerfully register as a user of any
  153.         number of programs costing as much as, say, a magazine. Agreed?
  154.  
  155.  
  156.         GET utilities  Page 2
  157.  
  158.  
  159.         And More Excuses
  160.  
  161.         Now for my logistic excuses. It's not EASY for a European user to
  162.         become a registered user of an American shareware program. Why?
  163.         How'd you like to send me a check for £5? You don't have a
  164.         sterling bank account?! Sorry, I can't do it by credit card.
  165.  
  166.         Let's suppose I couldn't sleep at night until I'd sent you $15. I
  167.         have a choice. I can take time off work, visit a bank to organise
  168.         a foreign currency draft (would you do this?). Alternatively, I
  169.         can just send you a check. Your bank would send it for collection
  170.         and keep most of the money. Knowing this I might decide it was a
  171.         waste of time. I might not even bother to write and say "nice
  172.         program" (and "pity about your banking system").
  173.  
  174.  
  175.         Here's the beef
  176.  
  177.         What do I suggest? If you like this package and use it I ask you
  178.         to send me a dollar bill. I will use it to register American
  179.         shareware I use.
  180.  
  181.         If you have any other ideas on how Europeans can better support
  182.         American shareware drop me a line.
  183.  
  184.  
  185.         To American Shareware Authors
  186.  
  187.         Don't treat your international users with the same apparent
  188.         contempt as some of the "big names" in the software business.
  189.         Europe could account for much of your business if you play it
  190.         right. It's a bigger market than the US and growing faster.
  191.  
  192.         There's an argument, an excuse for bad service or no service,
  193.         that European users are hard to support. Oh sure there's a time
  194.         difference, ok. In fact, European software users are not SO much
  195.         more difficult to support than users in, say, Alaska. Most speak
  196.         English. Federal Express, Purolator, DHL etc. (all but UPS)
  197.         deliver here. Then there's the mail. We also have telephones,
  198.         packet switching systems and many of us use services like
  199.         CompuServe. If you can't support your European users directly (by
  200.         mail even) consider charging them less.
  201.  
  202.         Try to make your software language independent so that the user
  203.         interface can be adapted without too much hassle and do support
  204.         international date formats and alternative currency symbols.
  205.  
  206.         First you must make people WANT to pay for your software.
  207.  
  208.         Next you could try to make it easier for them to pay you. THIS is
  209.         the biggest hassle and the insular American banking system
  210.         doesn't help. Until this problem disappears, as it will, you'll
  211.         have to be creative. I hope to send CASH very soon!
  212.  
  213.  
  214.  
  215.  
  216.  
  217.  
  218.                                                     GET utilities  Page 3
  219.  
  220.  
  221.         Distribution of this package
  222.  
  223.         This package may not be sold under any circumstances. It may not
  224.         be distributed by PC-Sig or any organisation that operates in a
  225.         substantially similar manner, including the Turbo User Group of
  226.         Poulsbo, Washington. User groups who publish annual accounts and
  227.         have elected officers may distribute this software for a nominal
  228.         charge to cover the costs of such distribution. This package must
  229.         be distributed without changes to the software or accompanying
  230.         documentation.
  231.  
  232.  
  233.         Acknowledgements
  234.  
  235.         This modest contribution to the "many hands make light work"
  236.         school of programming would not have been possible without the
  237.         work of others. Much as I have yet to learn (I'm working on it),
  238.         I have gleaned a lot from reading source code unselfishly made
  239.         available for public scrutiny by all of the following
  240.  
  241.  
  242.         David Bennett
  243.         Scott Bussinger
  244.         David Dubois
  245.         Ted Lassagne
  246.         Jim Le May
  247.         Carley Phillips
  248.         Richard Sadowsky
  249.         Juan Vegerra
  250.  
  251.  
  252.         I thank them all, Jim LeMay and Richard Sadowsky in particular.
  253.  
  254.         If you do any serious Turbo Pascal programming should obtain and
  255.         register a copy of Jim Le May's QWIK screen utilities. You cannot
  256.         buy a better package. I couldn't imagine working without it and I
  257.         think it's important that people like Jim are sufficiently
  258.         rewarded for their work to go on making it so readily available.
  259.  
  260.  
  261.         Paul O'Nolan
  262.         Newstead,
  263.         Forbes Place,
  264.         Hatton of Fintray,
  265.         Aberdeen AB2 0YB
  266.         Scotland, UK
  267.  
  268.         CompuServe 72007,242
  269.         c/o EDAS BBS (Aberdeen) 0224-624264
  270.  
  271.  
  272.  
  273.  
  274.         The GET utilities are copyright by Paul O'Nolan 1988.
  275.  
  276.  
  277.  
  278.  
  279.  
  280.         GET utilities  Page 4
  281.  
  282.  
  283.                          GET UTILITIES v1.0 October 1988
  284.  
  285.         Introduction
  286.  
  287.         The GET utilities consist of a number of Turbo Pascal procedures
  288.         for getting input from the screen, with dynamic validation where
  289.         possible. The procedures are written to make screen painting and
  290.         editing straightforward, as well as enabling the provision of
  291.         field dependent prompts and context sensitive help.
  292.  
  293.         As my use of borrowed code illustrates I hate reinventing wheels.
  294.         Nevertheless, I knew I was going to have to write this set of
  295.         procedures when I purchased a copy of the otherwise excellent
  296.         Turbo Professional package from Turbo Power Software and sat down
  297.         to look at it's data entry routines. The idea that one could
  298.         enter "abc" in a numeric field and not know about it until one
  299.         pressed <return> was not acceptable to me. I wanted keystroke by
  300.         keystroke validation where possible, just for starters.
  301.  
  302.         After a couple of evening's work I came up with
  303.  
  304.  
  305.         GETBOOLEAN    Get a boolean value
  306.         GETCHAR        Get a character
  307.         GETDIGIT    Get a numeric digit
  308.         GETSTR(ING)    Get a string
  309.         GETBYTE        Get an integer, type byte
  310.         GETSHORTINT    Get an integer, type shortint
  311.         GETINTEGER    Get an integer
  312.         GETWORD        Get an integer, type word
  313.         GETLONGINT    Get an integer, type longint
  314.         GETREAL        Get a real number
  315.         GETDATESTR(ING)    Get a date string (variable format)
  316.         GETTIMESTR(ING)    Get a time string
  317.         GETATTR        Get a color attribute
  318.  
  319.  
  320.         ... a list of procedures I thought I should, and did, write.
  321.         Writing them took a little longer.
  322.  
  323.         Next I spent several weekends adding or fixing "one more thing"
  324.         so I could call them "finished." Then, to my delight, Borland
  325.         announced Turbo Pascal v5.0 and I thought I really ought to get
  326.         this out the door before they actually delivered. In the UK this
  327.         meant several months grace because Borland, like Microsoft,
  328.         treats the European customer as a second class customer (pourquoi
  329.         Philippe?) -- something Compaq and IBM make a point of not doing.
  330.         Back to my story...
  331.  
  332.         All except GETATTR are part of the GET unit. In addition to the
  333.         above, GETRESPONSE, which is similar to GETCHAR but which is not
  334.         intended for data entry, is included. Procedures ending in (ING)
  335.         have two versions, with the shorter procedure name corresponding
  336.         to a version having an abbreviated parameter list, with default
  337.         values used for the omitted parameters.
  338.  
  339.         Some supporting software is used and recommended:
  340.  
  341.         A unit of functions GETFNS used by the GET procedures is required
  342.  
  343.                                                     GET utilities  Page 5
  344.  
  345.  
  346.         and included. Jim LeMay's QWIK screen procedures (shareware,
  347.         v4.2) and Richard Sadowsky's TOOLS4 procedures (public domain,
  348.         v1.0) are used extensively in this package. These are essential
  349.         if you wish to make changes to this package, but are not
  350.         otherwise required. Mark Van Kekerix's QHELP program is useful
  351.         but not essential. The GETATTR procedure requires Jim LeMay's
  352.         WNDW package. If subsequent versions of this package do not make
  353.         additional use of WNDW I may alter GETATTR to work without it.
  354.  
  355.  
  356.         The files in this package are:
  357.  
  358.  
  359.         GETTHIS.DOC     A READ.ME file by another name
  360.         GETDEMO.PAS     Demonstration program for this package
  361.         GETDEMO.DOC     Notes on GETDEMO
  362.         GET.DOC         This file
  363.         GETFNS.PAS      A unit of functions used by GET unit
  364.         GETFNS.TPU      Compiled GETFNS unit
  365.         GETOBJ.ARC      Archive of OBJ files used by GETFNS unit
  366.         GETVARS.PAS     Global variable unit used by GET unit
  367.         GET.PAS         Compile this file to produce GET.TPU
  368.         GETSTR.PAS      Source
  369.         GETNUM.PAS        code
  370.         GETREAL.PAS         for
  371.         GETDATE.PAS           GET
  372.         GETTIME.PAS             procedures {included by GET.PAS}
  373.         GETCOLOR.EXE    Program demonstrating GETATTR procedure
  374.         GETCOLOR.PAS    Source code for above
  375.         GETHELP         Help file for this package for use with QHELP
  376.         QWIK.TPU        Jim LeMay's QWIK screen unit, used by GET
  377.  
  378.  
  379.         Suggestions, enhancements and problem reports are all welcome.
  380.  
  381.         Few things are more exasperating for a BBS user than seeing a new
  382.         version of a package, with bug fixes, within days of downloading
  383.         an earlier version. There will not be another version of GET for
  384.         a while. I wrote it in order to write some other programs, which
  385.         I'm now going to write! GET will be updated in a few months, when
  386.         I catch up with Turbo Pascal v5.0 etc.
  387.  
  388.         If anyone cares for the job, there's an obvious application
  389.         waiting to be written using GET: a screen design program that
  390.         generates source code for screen based data entry. There are a
  391.         number of commercial programs that generate Turbo Pascal code
  392.         from screen designs but none, to my knowledge, that are shareware
  393.         or public domain. Drop me a line before undertaking this, I'll
  394.         advise you if anyone else has volunteered/started. Of course, the
  395.         GET procedures themselves could be used to help with the job.
  396.  
  397.         Since the preceding paragraph was written a package called OASIS
  398.         has been uploaded to CompuServe which fits the bill marginally
  399.         better than a mirage. Source code is not available.
  400.  
  401.  
  402.  
  403.  
  404.  
  405.         GET utilities  Page 6
  406.  
  407.  
  408.         Why QuickHelp?
  409.  
  410.         Mark Van Kekerix's QHELP program (in IBMSW on CompuServe) is a
  411.         useful tool for use when programming calls to GET procedures.
  412.         Even though I wrote GET I can't remember all the parameters for
  413.         all the procedures or the order of them. However, with QHELP all
  414.         I need to do is enter the name of the procedure, hit the hot key,
  415.         and read. It's even better than the built in help for Turbo
  416.         Pascal. QuickHelp is an excellent program and well worth having.
  417.  
  418.  
  419.                                 UNITS USED BY GET
  420.  
  421.         GETFNS
  422.  
  423.         This unit contains a number of functions used in GET and some
  424.         others that I use frequently, often in conjunction with GET. It's
  425.         a convenient repository for functions that are used in "higher
  426.         level" units. The functions here are all straightforward and
  427.         should be adequately documented in the code. This unit makes
  428.         extensive use of assembly language procedures written by Jim
  429.         Le May and Richard Sadowsky. Several of their routines replaced
  430.         code of mine and sometimes of others. I try to be an honest
  431.         magpie and have acknowledged my sources where possible.
  432.  
  433.  
  434.         GETVARS.PAS
  435.  
  436.         This unit contains the type definitions, typed constants (incl.
  437.         error messages), global variable declarations and code for the
  438.         smaller procedures and functions used in the GET package.
  439.  
  440.  
  441.         Global variables
  442.  
  443.         Numerous global variables are defined and initialised in GETVARS.
  444.         The meaning and use of most will be apparent from their names.
  445.         E.g:
  446.  
  447.         PasswordChar is set to a space, meaning that spaces are output
  448.         for each character entered using the get string routine when
  449.         PasswordField is true. An alternative value might be an asterisk.
  450.  
  451.         If AutoTab is true then fields are completed automatically on
  452.         entering the last possible character, otherwise the user must
  453.         enter a carriage return to complete the field.
  454.  
  455.         etc.
  456.  
  457.         A quick look at the code should suffice for any variables not
  458.         described in this document.
  459.  
  460.  
  461.         Error messages
  462.  
  463.         The text of all error messages is stored in the GETVARS unit. If
  464.         you wish to change a message you need only alter it in
  465.         GETVARS.PAS. Messages are stored as variables not constants to
  466.         minimise the impact on the stack of passing them to procedures
  467.  
  468.                                                     GET utilities  Page 7
  469.  
  470.  
  471.         (only the address of a variable is passed) and reduce code size
  472.         (constants are embedded in the code at each occurrence).
  473.  
  474.         All error messages are output on either of the two lines at the
  475.         bottom of the screen. Ordinarily the last line is used. The
  476.         penultimate and last lines are written to using the procedures
  477.         error and error2 respectively. To prevent the issuance of
  478.         multiple error messages, error messages are suppressed if the
  479.         appropriate error line is not blank (monitored using boolean
  480.         variables: ErrorLineClear and Error2LineClear). A consequence is
  481.         that the appropriate procedure, clearerror or clearerror2, should
  482.         be executed to clear any outstanding error messages and reset the
  483.         corresponding boolean variable prior to accepting keyboard input.
  484.  
  485.  
  486.         Other messages
  487.  
  488.         Informational messages (status information, acknowledgements,
  489.         warnings etc.) are also rendered on the bottom two lines of the
  490.         screen, using the procedures info and info2. These procedures do
  491.         not ring any bells, they are otherwise identical to error and
  492.         error2.
  493.  
  494.         The bell procedure may be used to give discretionary beeps to
  495.         wake the user up. Sound is made only if SoundOn is true, this is
  496.         a variable over which the user should have control. The beep
  497.         procedure sounds a bell regardless of the status of SoundOn.
  498.  
  499.         The AltWrite procedure displays text in one or two attributes
  500.         alternated by means of a switch passed as a parameter and
  501.         embedded within text. The procedure then pads the rest of the
  502.         line with spaces using the attribute in effect at the end of the
  503.         string (so that "reverse video" messages don't end abruptly half
  504.         way across the screen). A typical string to be displayed with
  505.         this procedure might be:
  506.  
  507.           Delete ^ALL^ files? ^Y^/^N^?
  508.  
  509.         It is not necessary to hard code the switch character into the
  510.         message. The brighten procedure can be used to embed text in a
  511.         pair of switches:
  512.  
  513.             error(text + brighten(text) + text);
  514.  
  515.         This procedure uses the value of DefaultAltSwitch for the switch
  516.         character.
  517.  
  518.  
  519.  
  520.  
  521.  
  522.  
  523.  
  524.  
  525.  
  526.  
  527.  
  528.  
  529.  
  530.         GET utilities  Page 8
  531.  
  532.  
  533.                                   THE GET UNIT
  534.  
  535.         GET procedures
  536.  
  537.         It is expected that GET procedures will ordinarily be called
  538.         twice to gather information from fields. On the first occasion,
  539.         with the global variable PaintingFields set to true, each GET
  540.         procedure will simply display the field contents and exit. This
  541.         makes screen painting fairly easy. EditingField is another
  542.         boolean variable -- the logical negative of PaintingFields -- it
  543.         was created for readability. If EditingField is true then the
  544.         active GET procedure will seek input. By default, a field prompt
  545.         is not redisplayed on the second call to the relevant get
  546.         procedure. This may be changed by changing the value of the
  547.         boolean global variable RediplayPrompts to true.
  548.  
  549.         All GET procedures get input into a nominated variable at
  550.         specified screen co-ordinates following a prompt string or
  551.         fieldname. The prompt string may be blank; if it is too long to
  552.         allow the field to fit on the screen it will be left-shifted
  553.         automatically until the field can fit on the screen. If it is
  554.         still too big it will be truncated as required.
  555.  
  556.         Notes
  557.  
  558.         Always ensure that you initialise all variables passed to get
  559.         procedures. If you use get procedures independently, i.e. outside
  560.         the context of a form make sure that you set PaintingFields to
  561.         false and RedisplayPrompts to true.
  562.  
  563.  
  564.         GETCHAR
  565.  
  566.         This procedure gets a single character in the variable
  567.         'response'.The character entered is validated against a set of
  568.         characters passed as a parameter (valid_keys). If possible, an
  569.         appropriate error message is issued when an invalid key is
  570.         pressed: "Numeric input expected" e.g. The input type expected is
  571.         deduced if the set of valid characters corresponds to one of the
  572.         predefined sets. No such message can be issued if some other set
  573.         of characters is passed as the set of valid characters (the bell
  574.         procedure is executed however). In such cases you should
  575.         highlight the valid options in the prompt or display them
  576.         elsewhere on the screen.
  577.  
  578.         Note: the field will not be highlighted during data entry using
  579.         the parameter cursor_attr unless FieldCursor is 0 (i.e. the
  580.         global variable FieldCursor has precedence over the parameter).
  581.  
  582.  
  583.         GETRESPONSE
  584.  
  585.         Like GETCHAR, this procedure gets a single character in the
  586.         variable 'response'.
  587.  
  588.         The prompt string is displayed using the AltWrite procedure
  589.         described above, so DefaultAltSwitch characters may be embedded
  590.         in it to emphasise particular words if necessary. The default
  591.         normal and bold video attributes, attrNM and attrBO, are passed
  592.  
  593.                                                     GET utilities  Page 9
  594.  
  595.  
  596.         to AltWrite. Validation is accomplished as per GETCHAR.
  597.  
  598.         If the value entered for 'response' is y or Y and 'makesure' is
  599.         true then the response to 'Sure Y/N' is elicited via a recursive
  600.         call. This is handy for getting answers to questions such as
  601.         'Delete all files.' Confirmation of responses other than y/Y is
  602.         not possible with this procedure.
  603.  
  604.         Whereas GETCHAR is intended for entry of data, this procedure is
  605.         intended for getting answers to questions, typically outside the
  606.         data area and using default values for display attributes. Fewer
  607.         parameters are needed as result.
  608.  
  609.  
  610.         GETBOOLEAN
  611.  
  612.         This is essentially a call to GETCHAR with the redundant
  613.         parameters taken out and the result translated to the appropriate
  614.         type. There can be no default value parameter for this procedure,
  615.         i.e. one entered in the event of the field being left "blank",
  616.         since a boolean value must be true or false.
  617.  
  618.         The grey plus and minus keys on the numeric keypad are probably
  619.         the most convenient keys to set the value of a boolean variable
  620.         to true or false. The following keys may be used:
  621.  
  622.         True:  T, t, +, Y, y, 1
  623.         False: F, f, -, N, n, 0, <space>
  624.  
  625.  
  626.         GETDIGIT
  627.  
  628.         This procedure is used to get a numeric character, decimal point,
  629.         plus or minus sign and certain editing characters at a designated
  630.         screen position. GETDIGIT is not intended to be called by the
  631.         user but by other GET procedures.
  632.  
  633.         This procedure has a feature it shouldn't have: hard coded
  634.         bindings between certain ASCII characters and commands (e.g. ^J
  635.         is tested for instead of the enter_default command). This is
  636.         inconsistent with the way the rest of the code is intended to
  637.         work and this discrepancy should be / will be fixed. I'm pointing
  638.         it out just to indicate that I know about it. It needn't affect
  639.         you unless you wish to alter the commands used to accomplish
  640.         certain things, in which case you'll need to edit this procedure
  641.         as well as the get_edit procedure (in GETFNS.PAS).
  642.  
  643.         This procedure should be implemented by a call to GETCHAR!
  644.  
  645.  
  646.  
  647.  
  648.  
  649.  
  650.  
  651.  
  652.  
  653.  
  654.  
  655.         GET utilities  Page 10
  656.  
  657.  
  658.         GETSTR
  659.  
  660.         This procedure is used to get a string fom the screen. It is,
  661.         effectively, a line editor and may be used to edit a series of
  662.         lines in a window. It may also be used for routine data entry
  663.         purposes, collecting and validating information from string
  664.         fields.
  665.  
  666.         Why bother with a line editor? Surely a full screen editor, such
  667.         as the binary editor provided with the Turbo Editor Toolbox,
  668.         would be more useful? If you wish to edit some text in a window
  669.         on its own, i.e., without reference to the contents of other
  670.         windows, this may well be the case. If, however, you have a need
  671.         for an application in which data in separate windows are linked,
  672.         then adapting a line editor to do the job is often a lot simpler
  673.         than reprogramming a text editor. A very trivial example in this
  674.         package is the GETTIME procedure, where the separate windows
  675.         amount to no more than two subfields.
  676.  
  677.         How it works
  678.  
  679.         Attributes:
  680.  
  681.         The string is displayed at the co-ordinates passed using the
  682.         attribute parameter attr. The value of attr is considered the
  683.         native attribute for the field, however this may be overridden by
  684.         the global variable FieldCursor (if FieldCursor is not zero and
  685.         the field is being edited rather than just displayed).
  686.  
  687.         FieldCursor is used to highlight the field the cursor is on and,
  688.         as you would expect, it moves around from field to field with the
  689.         ordinary cursor. The ordinary blinking underline cursor is a
  690.         fairly miserable specimen. I prefer a non-blinking block cursor
  691.         myself, so I've given GETSTR the ability to use one -- "faked"
  692.         using a video cursor.
  693.  
  694.         To make a video cursor the blinking underline is switched off and
  695.         a block cursor is simulated using the attribute byte of the
  696.         appropriate screen location. This byte is set to the value of the
  697.         parameter cursor_attr. This value should be different from attr
  698.         if you wish to use this kind of cursor -- you don't have to of
  699.         course. Arguably, cursor_attr should be a global variable, like
  700.         FieldCursor, since it's not very likely that you'd change it
  701.         between calls to GETSTR. In overwrite mode the cursor will change
  702.         to include a blinking underline.
  703.  
  704.         If you elect not to use a non-blinking block cursor, in the
  705.         colour of your choice, a blinking block cursor will be used
  706.         instead, and overwrite mode will be indicated by a blinking
  707.         underline cursor. If you find this blinking discourse hard to
  708.         follow the following table summarizes everything.
  709.  
  710.                              Insert                 Overwrite
  711.  
  712.         cursor_attr =  attr  blinking block*        blinking underline
  713.         cursor_attr <> attr  non-blinking block** + blinking underline
  714.  
  715.          * black
  716.         ** any colour
  717.  
  718.                                                    GET utilities  Page 11
  719.  
  720.  
  721.  
  722.         The extent of the field is indicated, even if it is blank, if the
  723.         attribute used to display it differs in background colour from
  724.         the rest of the screen -- spaces are output to clear to the end
  725.         of the field when the string is displayed.
  726.  
  727.  
  728.         The PICTURE
  729.  
  730.         The picture parameter controls how the string is to be disposed
  731.         on the screen and controls how individual characters are to be
  732.         validated. In other words, it provides for a degree of formatted
  733.         input. Suppose, for the sake of illustration, that you wished to
  734.         get a 6 character date from the screen. The following picture
  735.         would help:
  736.  
  737.                                  '99/99/99'
  738.  
  739.         The 9's indicate that only numeric input will be accepted in the
  740.         corresponding positions. The slashes are field markers and will
  741.         not be part of the string returned by GETSTR.
  742.  
  743.         Characters in specific positions may be constrained to belong to
  744.         particular character sets: numeric, alphabetic, alphanumeric and
  745.         printable are provided by default (you can add sets of your own).
  746.         The picture descriptors for these sets are as follows:
  747.  
  748.  
  749.         picture character          character set
  750.  
  751.                 A                  alphabetic
  752.                 C                  alphanumeric
  753.                 P                  printable
  754.                 9                  numeric
  755.                 X                  any character
  756.                 any other          any character
  757.  
  758.  
  759.         These picture characters may be entered in the picture string in
  760.         upper or lower case. Upper case picture characters will cause
  761.         characters entered at the corresponding screen position to be
  762.         converted to upper case. Thus a picture beginning 'Aa' could be
  763.         convenient for entering names, with the initial character
  764.         automatically converted on entry to upper case.
  765.  
  766.         If more than one character set is employed in validating a
  767.         string, the string is edited in overwrite mode and the Ins key
  768.         has no effect. The last mode (overwrite or insert) will be
  769.         resumed at the next field if appropriate. When character
  770.         validation is position dependent it makes no sense to allow
  771.         characters to be displaced by the insertion or deletion of other
  772.         characters, this is why insert mode is temporarily disabled.
  773.  
  774.         If you wish to edit a field 5 characters long, without any
  775.         constraints on what characters are entered, you do not need to
  776.         pass GETSTR a picture of 'xxxxx'. A picture of just 'x' will do.
  777.         In mapping the correspondences between the picture and data
  778.         strings GETSTR will apply the last picture character repeatedly
  779.         all the way to the end of the data string. If you wish to get 3
  780.  
  781.         GET utilities  Page 12
  782.  
  783.  
  784.         digits followed by 20 alphabetic characters a picture of '999a'
  785.         will suffice. The number of a's to the end of the string will be
  786.         controlled by the value passed for maxstrlen. However, if you
  787.         wish to get 79 alphanumeric characters followed by a digit you
  788.         would need to pass a string of 79 a's and a 9 (if you were
  789.         determined to do it like that). There is a shortcut however, see
  790.         RepeatCharacter below.
  791.  
  792.         The parameters instr and picture are both of type string, meaning
  793.         that they cannot exceed 256 characters in length. This should not
  794.         cause you any difficulty. I just wish to point out here that, as
  795.         you have already seen, their lengths need not correspond. The
  796.         picture string can actually be longer than the data string, since
  797.         it can contain embedded field markers.
  798.  
  799.  
  800.         Field Markers
  801.  
  802.         Field markers are characters which are output at designated
  803.         positions on the screen within the string field but which are not
  804.         actually returned as part of the string. GETSTR uses a predefined
  805.         set of field markers which you can change if you wish to (see
  806.         GETVARS). The default set includes most punctuation characters
  807.         and special symbols. You are in no way debarred from entering
  808.         these in the string by virtue of their being employed as field
  809.         markers. Field markers can be strung together in succession as
  810.         well as being entered individually. One special field marker
  811.         deserves mention.
  812.  
  813.         The letter 'B' used in the picture is used to denote a blank
  814.         character in the input field over which the cursor will skip.
  815.         Thus, a picture of
  816.  
  817.                               '(999)B999-9999'
  818.  
  819.         would leave a blank on the screen between the area code and the
  820.         rest of the telephone number. The value of maxstrlen (following
  821.         picture string in the parameter list) should, of course, be 10.
  822.         There are 10 digits in the string. You could render the picture
  823.         as '(999)B999-9' if you wanted to, and let GETSTR fill in the
  824.         last few characters automatically, however your code would not be
  825.         quite as readable. Note, B is used instead of a space to make
  826.         counting field markers easier.
  827.  
  828.  
  829.         Switches
  830.  
  831.         Special characters or switches may be embedded in the picture
  832.         string to control how it is interpreted by GETSTR. Naturally,
  833.         aone of these should appear in the predefined set of field
  834.         markers, or they will be ignored in any picture string. You may
  835.         change the switch characters if you wish.
  836.  
  837.  
  838.         DefaultAltSwitch
  839.  
  840.         First is the constant DefaultAltSwitch (type char). It's default
  841.         value is a tilde. It's name derives from the fact that this
  842.         character is the default switch for the AltWrite procedure which
  843.  
  844.                                                    GET utilities  Page 13
  845.  
  846.  
  847.         is used to display text using either of two video attributes,
  848.         with this character toggling between them. It is used to trigger
  849.         the copying of text from the picture to the screen as if the
  850.         characters following the switch were field markers. Thus, if an
  851.         asterisk was the switch character, the following picture would
  852.         allow you to get a date with '19' displayed on the screen for the
  853.         first two digits of the year
  854.  
  855.  
  856.                                 '99-99-*19*99'
  857.  
  858.         Note that GETSTR will not return the '19' as part of the string
  859.         (unless you modify the code!).
  860.  
  861.  
  862.         ShiftCharacter
  863.  
  864.         The second switch is the constant ShiftCharacter, with a default
  865.         value of "\". This character is used to force GETSTR to treat the
  866.         string parameter (instr) as one or more string segments which,
  867.         although they belong together, are not displayed contiguously.
  868.         This switch can be used to get GETSTR to break a 240 character
  869.         comment string into three 80 character lines, e.g. Alternatively,
  870.         it could be used to facilitate collection of input from a few, or
  871.         even a few dozen, apparently separate text fields into one string
  872.         (edits could be accepted or aborted collectively). Of course
  873.         there would still be only one field prompt provided by GETSTR.
  874.  
  875.         The character following the ShiftCharacter controls how GETSTR
  876.         breaks the string; the shift character itself is merely a flag
  877.         indicating that the string is to be broken. If the next picture
  878.         character is an "N" then the string is wrapped so that the next
  879.         data string character is located beneath the first character in
  880.         that string. Thus, using the default value of ShiftCharacter, the
  881.         sequence "\N" embedded in the picture string connotes a new line.
  882.         A picture of
  883.  
  884.                                  'xxx\Nxxx\Nxxx'
  885.  
  886.         will correspond to 3 x 3 block of characters on the screen.
  887.  
  888.         If the character following the ShiftCharacter is anything other
  889.         than an "N" then GETSTR displaces the next data string character
  890.         by the ordinal value of that character. Thus, a picture of
  891.  
  892.                             'xxx\' + chr(10) + 'xxx'
  893.  
  894.         could be used for two three character fields separated by 10
  895.         screen positions. Note that this picture is not equivalent to
  896.  
  897.                                'xxxBBBBBBBBBBxxx'
  898.  
  899.         The B in the picture will cause the corresponding screen location
  900.         to be blanked and displayed using an attribute controlled by
  901.         GETSTR. This will not happen using the first picture above.
  902.  
  903.         If you wish to effect a displacement of ord('N') or one in excess
  904.         of 255 locations simply use two or more successive displacements.
  905.         Note: All displacements must be positive.
  906.  
  907.         GET utilities  Page 14
  908.  
  909.  
  910.  
  911.  
  912.         RepeatCharacter
  913.  
  914.         The third switch is the RepeatCharacter (default value: "@").
  915.         This is used in a similar manner to the ShiftCharacter, except
  916.         that the character following the RepeatCharacter represents a
  917.         repeat value rather than a displacement. The picture character
  918.         repeated is the last one used. The RepeatCharacter allows long
  919.         picture strings to be specified conveniently (no miscounting and
  920.         a reduced impact on code size and stack space). Thus, returning
  921.         to the previous example, a picture of
  922.  
  923.         'x@' + chr(79) + '\N' + 'x@' + chr(79) + '\N' + 'x@' + chr(79)
  924.  
  925.         or
  926.  
  927.         'x@' + #79 + '\N' + 'x@' + #79 + '\N' + 'x@' + #79
  928.  
  929.         corresponds to a 240 character string broken into three lines of
  930.         80 characters each. This could be rendered more economically as
  931.         'x@O\Nx@O\Nx@O' or even 'x@O\N@P\N@P'. Note that #n may be used
  932.         instead of chr(n).
  933.  
  934.         As an aside, # is a hash character, or if you want to be exactly
  935.         correct, an octothorpe. It is not, repeat not, a pound character.
  936.  
  937.         Note: the display_prompt procedure takes account of the fact that
  938.         the string may be broken. It would not necessarily be appropriate
  939.         to left shift the prompt and a long string field if the string
  940.         was split into, say, two segments and enough room was allowed for
  941.         these. However, it is assumed that string segments following the
  942.         first will be on succeeding lines and no check is made to ensure
  943.         that there is enough room for these.
  944.  
  945.         If you are silly and ask GETSTR to get data from a field whose
  946.         picture string doesn't provide for anything other than embedded
  947.         (marker) text and field markers you, and the field, will be
  948.         ignored. GETSTR will display what it can and exit.
  949.  
  950.         Naturally, GETSTR allows you to display embedded text and field
  951.         markers in strings using a different attribute from the rest of
  952.         the string. If the field is being edited these characters will be
  953.         displayed using the value of the constant PicCursor. If PicCursor
  954.         has a value greater than 0 it will be used instead of the
  955.         prevailing attribute.
  956.  
  957.  
  958.         Other parameters
  959.  
  960.         The status parameter is used to pass a single byte bit map which
  961.         controls the variables 'mandatory' and 'fixed_length' (bits 1 and
  962.         2 respectively). These control whether or not a blank field is an
  963.         acceptable input and whether that input must, if not zero
  964.         characters long, be a fixed number of characters (value of
  965.         maxstrlen) in length.
  966.  
  967.  
  968.  
  969.                                                    GET utilities  Page 15
  970.  
  971.  
  972.         WordStar editing
  973.  
  974.         The GETSTR editor understands the following commands:
  975.  
  976.  
  977.         Home          beginning of string        ^QS
  978.         End           end of string              ^QD
  979.         Ins           toggle insert/overwrite    ^V
  980.                       left word                  ^A
  981.         right arrow   right 1 character          ^D
  982.         left arrow    left 1 character           ^S
  983.         up arrow      up 1 character             ^E
  984.         down arrow    down 1 character           ^X
  985.         <tab>         insert tab (if allowed)    ^I
  986.         <ret>         enter the string           <ret> / ^M
  987.                       insert literal             ^P followed by any char
  988.                       oops (undo)                ^QL / ^U
  989.                       delete string              ^Y
  990.                       delete to start of string  ^Q<del> / ^QH
  991.                       delete to end of string    ^QY
  992.                       delete next word           ^T
  993.         <esc>         abandon changes to field
  994.         <del>         delete character           ^G
  995.  
  996.  
  997.         Many other commands are passed through to the calling program.
  998.  
  999.         <Tab> will either enter a "<tab>" or, if the global variable
  1000.         tabsize is set to 0, move to the next field. If tabsize is not 0
  1001.         (default is 8) then the appropriate number of spaces is entered.
  1002.  
  1003.         The up arrow and down arrow commands are acted upon by GETSTR
  1004.         only if appropriate, i.e., if the string is broken into two or
  1005.         more segments -- these would normally be displayed on separate
  1006.         lines.
  1007.  
  1008.         The following are worthy of note
  1009.  
  1010.         ALT-R  Reset -- disable validation (temporarily only)
  1011.         ALT-Y  Delete a block (all subfields with a string)
  1012.         ALT-U  Restore (undo) a block -- e.g subfields in dates and times
  1013.         ALT-X  Exit: abort changes to current field and finish data entry
  1014.         ^J     Enter default -- described below
  1015.  
  1016.  
  1017.         Enter Default
  1018.  
  1019.         The GETSTR procedure does not enter a default value in response
  1020.         to the enter default command, instead it returns to the calling
  1021.         procedure which may then take the appropriate action. This is
  1022.         done for two reasons: 1. to avoid passing an additional parameter
  1023.         (whether string, address or pointer) and 2. because it would not
  1024.         help in situations where strings were linked to make up a larger
  1025.         field -- how does one enter a default date, say 10 characters in
  1026.         a 2 character day field?
  1027.  
  1028.  
  1029.  
  1030.  
  1031.         GET utilities  Page 16
  1032.  
  1033.  
  1034.         Disabling Validation
  1035.  
  1036.         Validation may be disabled, on a field by field basis only,
  1037.         provided the user has the appropriate privilege. The privilege is
  1038.         controlled by the boolean variable ValidationOverride. In the
  1039.         case of the GETSTR procedure, bad data will not be displayed
  1040.         using asterisks (as is done to indicate overflow, e.g., in the
  1041.         procedure GETNUM). However, attempts to move the cursor to
  1042.         another field will be trapped, on the offending character, until
  1043.         validation is turned off, <escape> or ALT-X is pressed, or the
  1044.         data is corrected.
  1045.  
  1046.  
  1047.         Global variables affecting string editing
  1048.  
  1049.         PaintingFields (boolean) controls whether, having displayed the
  1050.         string 'instr', GETSTR should allow the user to edit this string
  1051.         or exit. At the moment this variable is global to all fields,
  1052.         however it could easily be set for particular fields using a bit
  1053.         map -- enabling write protected (display only) fields to be used.
  1054.  
  1055.         Top_n_tail (boolean) controls whether or not strings returned by
  1056.         GETSTR have leading and trailing blanks removed.
  1057.  
  1058.         ForceUppercase (boolean) controls whether all text is to be set
  1059.         to upper case regardless of the value of picture characters.
  1060.  
  1061.         PasswordField (boolean) controls how characters entered are
  1062.         echoed. If true then the character PasswordChar (default value is
  1063.         a space) is output in place of all characters entered and all
  1064.         validation is suspended -- no point in issuing messages like
  1065.         "numeric character expected"!
  1066.  
  1067.  
  1068.         Variables affecting cursor movement
  1069.  
  1070.         Fieldwrap (boolean) controls whether the cursor moves from the
  1071.         last field to the first on field completion/next field command or
  1072.         or vice versa when directed to the previous field. If Fieldwrap
  1073.         is false it is expected that the value of the variable 'field'
  1074.         will, in your program, eventually exceed the number of fields on
  1075.         the screen and that data entry can be terminated without
  1076.         requiring the user to enter an exit command.
  1077.  
  1078.         Cursor movement between fields effected using the horizontal
  1079.         arrow keys may be controlled directly by a lookup table in your
  1080.         application.
  1081.  
  1082.         StringFieldWrap (boolean) controls whether the cursor will
  1083.         respond to the left and right arrow keys when positioned in the
  1084.         first or last character positions in a string. If StringFieldWrap
  1085.         is set, GETSTR will attempt to move the cursor to the next or
  1086.         previous field if asked to do so, moving to the start or end of a
  1087.         string if appropriate -- i.e., from the end of one string to the
  1088.         start of the next and v.v.
  1089.  
  1090.         This variable can be set to enable the use of linked subfields
  1091.         within what appears to be a string but is in reality a series of
  1092.         strings. E.g.
  1093.  
  1094.                                                    GET utilities  Page 17
  1095.  
  1096.  
  1097.  
  1098.         Getting a date using an apparent PIC '99/99/99'
  1099.  
  1100.         oldStringFieldWrap := StringFieldWrap;
  1101.         StringFieldWrap := true;
  1102.  
  1103.         now get 3 date subfields
  1104.  
  1105.         StringFieldWrap := oldStringFieldWrap;
  1106.  
  1107.  
  1108.         Other notes
  1109.  
  1110.         It is possible to include a field prompt in the picture string if
  1111.         you wish to do so. Simply embed it using DefaultAltSwitch as
  1112.         previously described; it may be displayed using the same
  1113.         attribute as the input field however. Alternatively, the
  1114.         following would work:
  1115.  
  1116.         promptstr := 'fieldname: ';
  1117.         picture := brighten(promptstr) + 'x';
  1118.  
  1119.         Getstr(....,picture,...);
  1120.  
  1121.         The brighten procedure adds the switches for you, so you don't
  1122.         need to hard code them into the code.
  1123.  
  1124.         You may care to consider using RedAttr to display characters not
  1125.         matching the picture specified for them* (at the moment there is
  1126.         nothing to draw attention to 'abc' displayed in a field with a
  1127.         picture of '999' until the user attempts to leave the field).
  1128.         Alternatively, one could use a reserved graphics character for
  1129.         each bad character, perhaps with the reset validation command
  1130.         (currently Alt-R) enabling a display of the offending characters.
  1131.  
  1132.         * Some commented out code can be taken as a starting point.
  1133.  
  1134.         The GETFNS unit incorporates routines which could be used to add
  1135.         search or search and replace functions to GETSTR. Other routines
  1136.         could easily be added: change the case of the current character
  1137.         etc.
  1138.  
  1139.  
  1140.  
  1141.  
  1142.  
  1143.  
  1144.  
  1145.  
  1146.  
  1147.  
  1148.  
  1149.  
  1150.  
  1151.  
  1152.  
  1153.  
  1154.  
  1155.  
  1156.         GET utilities  Page 18
  1157.  
  1158.  
  1159.         GETNUM
  1160.  
  1161.         This procedure should never be called directly. It is intended to
  1162.         be called by one of the following procedures:
  1163.  
  1164.                   GETBYTE
  1165.                   GETSHORTINT
  1166.                   GETWORD
  1167.                   GETINTEGER
  1168.                   GETLONGINT
  1169.  
  1170.         Each of these procedures indicates to GETNUMBER what the maximum
  1171.         value of a returnable number should be. This is accomplished
  1172.         using a longint parameter (maxvalue) having one of a restricted
  1173.         set of values, each of which is used to imply the required type
  1174.         of the returnable number. When you use one of the above
  1175.         procedures the appropriate value of maxvalue is set
  1176.         automatically.
  1177.  
  1178.         The parameter list includes the variables 'low' and 'high' which
  1179.         may be used for controlling range checking. Range checking is
  1180.         dynamic -- i.e., mistakes are caught immediately -- if the range
  1181.         does not exclude the number 0. If dynamic validation is not
  1182.         possible then numbers are validated after the user has finished
  1183.         entering them.
  1184.  
  1185.         If low and high are equal then range checking is turned off. If
  1186.         the value of either low or high is not appropriate for the
  1187.         implied type (e.g., a range of 0 to 999 with a maxvalue of 255)
  1188.         then the range is adjusted to the maximum permissible if the type
  1189.         is correct (in this case the range would become 0 to 255);
  1190.  
  1191.         Field size is determined in the first instance by the required
  1192.         number of digits for the implied type (3 for a byte, 5 for a word
  1193.         etc.). Validation criteria may constrain this further (a byte in
  1194.         range 0..99 will require a field size of only 2 digits), unless
  1195.         the user has ValidationOverride privilege in which case the
  1196.         nominal (full) field size is used. ValidationOverride is a
  1197.         boolean variable used to control whether or not a user may
  1198.         disable validation. Note that it may be turned on or off between
  1199.         fields. Naturally, if the user has this privilege for a field,
  1200.         the field needs to be the maximum size allowable for the type of
  1201.         data expected (3 digits for a byte etc.) regardless of what
  1202.         validation criteria are in effect.
  1203.  
  1204.         If the number passed is too big to be displayed in the field
  1205.         allowed then the field is asterisk filled. The delete_line
  1206.         command (default: ^Y) blanks the field for fresh input. Pressing
  1207.         <ret> sets a blank field to a default value if one has been
  1208.         specified. <esc> and ALT-X exit the field leaving it unchanged,
  1209.         as does moving to another field before terminating entry or
  1210.         editing of the field's contents. The enter_default command
  1211.         (default: ^J) forces entry of the default value. A default value
  1212.         may lie outside the validation range if the user has
  1213.         ValidationOverride privilege.
  1214.  
  1215.  
  1216.  
  1217.  
  1218.                                                    GET utilities  Page 19
  1219.  
  1220.  
  1221.         Global variables
  1222.  
  1223.         RightJustifyNumbers (boolean) controls whether numbers are
  1224.         displayed right justified after entry.
  1225.  
  1226.         RightJustifyNumberEntry (boolean) controls whether numbers are
  1227.         right justified in the input field during data entry. If true
  1228.         they are, otherwise they are entered left justified. Note that
  1229.         RIghtJustifyNumbers controls how numbers are displayed AFTER they
  1230.         have been edited.
  1231.  
  1232.         If ZeroAsBlank is true then fields having a value of zero are
  1233.         displayed as blank.
  1234.  
  1235.         If ZeroFillNumbers is true then fields are displayed so that each
  1236.         field is filled with a right justified number preceded by zeros.
  1237.  
  1238.  
  1239.         Other notes
  1240.  
  1241.         Editing of a number always takes place at the end of the field.
  1242.         Because the cursor is not constrained to remain within the field,
  1243.         even when editing the last character in a full field (as it is in
  1244.         GETSTR), a real cursor is always used rather than a simulated
  1245.         one. If this were not done it would be necessary to save and
  1246.         restore the video attribute byte immediately following each
  1247.         field. Because a real cursor is used then, SetCursor(CursorOn) is
  1248.         executed at the start of the routine and SetCUrsor(CursorOff) at
  1249.         the end of it.
  1250.  
  1251.  
  1252.         GETREAL
  1253.  
  1254.         This procedure is broadly similar to GETNUM, having the same
  1255.         general parameters, but the parameter decimal_places is used
  1256.         instead of maxvalue to determine the maximum range of possible
  1257.         input.
  1258.  
  1259.         The larger field size required for low or high controls how big
  1260.         the field for the entry of 'number' is, unless low = high then
  1261.         the nominal field size of 13 digits is used (11 significant
  1262.         digits, plus sign and decimal point). The value of decimal_places
  1263.         constrains the maximum range of the input as follows:
  1264.  
  1265.  
  1266.           implied_lowest  implied_highest  decimal_places
  1267.  
  1268.           -2147483648     217483647               0
  1269.           -2147483648.0   217483647.0             1
  1270.           -999999999.99   99999999.99             2
  1271.           -99999999.999   9999999.999             3
  1272.  
  1273.           -9.9999999999   9.999999999            10
  1274.  
  1275.  
  1276.         The ranges indicated above will be used for the corresponding
  1277.         number of decimal places if user specified range checking is not
  1278.         in effect (i.e., if low = high) or if the range specified is not
  1279.         appropriate for the number of decimal places specified.
  1280.  
  1281.         GET utilities  Page 20
  1282.  
  1283.  
  1284.  
  1285.         The range may be constrained further by the parameters low and
  1286.         high and the field size will be affected accordingly -- provided
  1287.         ValidationOverride is not true. Field size may be further
  1288.         affected if any user defined formats are used. As many additional
  1289.         characters as are required to cater for the maximum number of
  1290.         commas, e.g., in a number may be added to the field size.
  1291.  
  1292.         As with GETNUM, dynamic validation is not attempted unless the
  1293.         validation range includes the number 0.
  1294.  
  1295.         A decimal point is added automatically during data entry when the
  1296.         maximum number of digits for the integer part of a number has
  1297.         been entered.
  1298.  
  1299.  
  1300.         User Defined Formats
  1301.  
  1302.         It would be possible to add several parameters to the GETREAL
  1303.         procedure to control how real numbers were to be displayed after
  1304.         they had been entered. I thought it would be a better idea to
  1305.         collapse a number of parameters into one: the parameter
  1306.         decimal_places can have a negative value. Ordinarily, this would
  1307.         be nonsensical. However, this provides a means for passing
  1308.         additional information to the GETREAL procedure without expanding
  1309.         the parameter list.
  1310.  
  1311.         If the value of decimal_places is negative GETREAL uses its
  1312.         absolute value to index into an array of user specified display
  1313.         formats (in GETVARS.PAS). GETREAL uses the information obtained
  1314.         from this array to set the values of the several variables
  1315.         controlling number display. The first entry in this array looks
  1316.         like this:
  1317.  
  1318.  
  1319.         (UnitSymbol: '$'; places: 2; UnitFormat: SymbolFirst_Commas)
  1320.  
  1321.  
  1322.         If the value of decimal_places is -1 then 'number' is displayed
  1323.         to two places of decimals with a dollar in front of a comma
  1324.         punctuated amount. No problem? However, remembering to use -1 for
  1325.         one format and minus something else for another would be a little
  1326.         tedious, so I've set up some constants to make it simple; you
  1327.         should modify the list of these and the corresponding formats to
  1328.         suit your own purposes.
  1329.  
  1330.         The predefined values are as follows:
  1331.  
  1332.           Dollars      = -1;
  1333.           Pounds       = -2;
  1334.           FrenchFrancs = -3;
  1335.           SwissFrancs  = -4;
  1336.           Kmpersec     = -5;
  1337.           MHz          = -6;
  1338.  
  1339.  
  1340.         All you have to do is write "Dollars", "SwissFrancs", "Pounds"
  1341.         etc. instead of a number of decimal places in the parameter list
  1342.         for GETREAL.
  1343.  
  1344.                                                    GET utilities  Page 21
  1345.  
  1346.  
  1347.  
  1348.         The variable UnitFormat in the array of format descriptors is
  1349.         itself a composite variable. It is a byte whose bits are set or
  1350.         reset to indicate how the number should be displayed. Some
  1351.         constants are defined to make manipulating these bits easier:
  1352.  
  1353.  
  1354.           Unformatted = $00;
  1355.           SymbolFirst = $01;
  1356.           Commas      = $02;
  1357.           Parentheses = $04; {display negative numbers in parentheses}
  1358.           Financial   = $06; {shorthand for commas + parentheses}
  1359.           SIdisplay   = $08; {Système International format}
  1360.  
  1361.           SymbolFirst_Commas      = $03;
  1362.           SymbolFirst_Parentheses = $05;
  1363.           SymbolFirst_Financial   = $07;
  1364.  
  1365.  
  1366.         To add your own format all you need do is:
  1367.  
  1368.         1. Decide how you wish the number to be displayed
  1369.         2. Increment the constant TotalUserFormats (also in GETVARS.PAS)
  1370.         3. Add a record to the array of formats (UserFormatArray)
  1371.  
  1372.  
  1373.         You may add a constant to the list shown above (after MHz) so
  1374.         that you don't need to remember where in the table the
  1375.         appropriate format is defined. A further advantage of doing this
  1376.         lies in the fact that the table may be reordered without the need
  1377.         to make changes to every invocation of the procedure; the values
  1378.         of the appropriate constants (dollars, pounds etc.) may be
  1379.         changed instead.
  1380.  
  1381.         Find the appropriate value of UnitFormat by inspection of the
  1382.         table above.
  1383.  
  1384.  
  1385.         Système International
  1386.  
  1387.         Real numbers displayed in compliance with the conventions of the
  1388.         SI standard are shown with a comma delimiting the mantissa and
  1389.         the characteristic part of the number, with thousands delimited
  1390.         by either a space or a period. GETREAL supports the SI standard
  1391.         by means of its facilities for handling user-defined formats.
  1392.  
  1393.         If SIdisplay in the appropriate UnitFormat record is true then
  1394.         the real is displayed according to the conventions of the SI
  1395.         standard. A global character variable, SIThousandsDelimiter, with
  1396.         a default value of a period, is used to punctuate the integer
  1397.         part of the real. This variable can be set to a space if desired.
  1398.  
  1399.         Numbers entered with SIdisplay set true or false in their
  1400.         UnitFormat records will be displayed with a "decimal comma" or
  1401.         decimal point respectively during data entry, although either
  1402.         character may be entered as the decimal delimiter. Range values
  1403.         will be correspondingly affected in the text of any error
  1404.         messages issued during data entry (decimal comma if SIdisplay).
  1405.  
  1406.  
  1407.         GET utilities  Page 22
  1408.  
  1409.  
  1410.         GETDATESTRING
  1411.  
  1412.         This routine gets a date string from the screen using successive
  1413.         calls to the GETSTR procedure to accumulate an aggregate string.
  1414.         The description of that procedure's operation applies to the each
  1415.         of the day, month and year subfields comprising a date.
  1416.  
  1417.         The primary purpose of this procedure is to provide flexible date
  1418.         format control and to provide validated dates in a string format.
  1419.         The user may then convert dates using a preferred Julian
  1420.         conversion routine if desired. I believe that quite a few people
  1421.         will be happy to store dates as ASCII strings, particularly in
  1422.         cases where all other data are being stored as ASCII. In such
  1423.         cases the dates need only be temporarily converted to Julian
  1424.         format for arithmetic purposes.
  1425.  
  1426.         Date format control is accomplished by means of simple global
  1427.         variable assignments such as:
  1428.  
  1429.  
  1430.         DateFormat := European;
  1431.         YearFormat := YY;
  1432.  
  1433.  
  1434.         GETDATESTRING returns an 8 or a 10 character string with 2
  1435.         subfield separators. The global variables DateFormat and
  1436.         YearFormat control the interpretation of the subfields in any
  1437.         string passed to this procedure (i.e., their order and implied
  1438.         nature -- month, day or year) and the number of characters in a
  1439.         year field. Thus, for a DateFormat of American, dates are
  1440.         expected in mm/dd/[yy]yy order.
  1441.  
  1442.         The date field separators, i.e. the characters between month, day
  1443.         and year subfields, are either those in the appropriate positions
  1444.         in the string being edited or the globally specified default (for
  1445.         blank dates).
  1446.  
  1447.         Unlike the field markers which appear in picture strings, date
  1448.         subfield separator are part of the string -- although they are
  1449.         skipped over during data entry or editing. In practice the
  1450.         content of these bytes is irrelevant, their position is more
  1451.         significant. Any separator character may be used, each will be
  1452.         displayed during date entry using the separator_attr attribute
  1453.         passed to the procedure.
  1454.  
  1455.         Valid date formats are:
  1456.  
  1457.  
  1458.         DateFormat  date string format
  1459.  
  1460.         American    mm/dd/[yy]yy
  1461.         European    dd/mm/[yy]yy
  1462.         Japanese    [yy]yy/mm/dd
  1463.  
  1464.  
  1465.  
  1466.  
  1467.  
  1468.  
  1469.                                                    GET utilities  Page 23
  1470.  
  1471.  
  1472.         Valid year formats are:
  1473.  
  1474.  
  1475.         YearFormat   year string subfield                overall length
  1476.  
  1477.         YYYY         4 digits: 0000-9999 to be returned         10
  1478.         YY           2 digits: 00-99                             8
  1479.         NY           as above                                    8
  1480.  
  1481.  
  1482.         The difference between NY and YY is that dates with a YearFormat
  1483.         of NY are displayed with a "19" prefacing a two character year
  1484.         subfield. This "19" is NOT returned as part of the date string.
  1485.         In determining what years are leap years ALL dates with effective
  1486.         field sizes of two characters for data entry are assumed to be
  1487.         20th century dates, and 1900 is added to each.
  1488.  
  1489.         Dates entered are validated to ensure that the number of days in
  1490.         the month and number of months in the year are legal values.
  1491.         Because GETDATESTRING allows dates to be entered in a variable
  1492.         manner it also validates dates in the subfield order in which
  1493.         they are displayed.
  1494.  
  1495.         No validation is performed on the year subfield of any date other
  1496.         than to ensure that it is filled with numeric characters, though
  1497.         of course whether or not the year is a leap year will affect the
  1498.         validation of the day subfield.
  1499.  
  1500.         The following definition of a leap year is used: any year
  1501.         divisible by four except centuries divisible by four hundred and
  1502.         millennia by four thousand are leap years.
  1503.  
  1504.         Because the date string used by this procedure needs to be
  1505.         capable of being either 8 or 10 characters long the appropriate
  1506.         var parameter is a string (0 to 255 characters long). This means
  1507.         that any old rubbish can be passed to it without difficulty, it
  1508.         is your responsibility to see that this doesn't happen.
  1509.         GETDATESTRING doesn't do much to recover the situation if the
  1510.         string passed is simply not a date in the format expected.
  1511.  
  1512.         To blank a date field enter the del_block command (default Alt-Y)
  1513.         and to restore a date field enter the restore_block command
  1514.         (default Alt-U).
  1515.  
  1516.         The enter_default command (^J) enters the current system date.
  1517.         This command may be entered on the first subfield of a blank date
  1518.         field or on any completed date subfield. Pressing <return> on a
  1519.         blank date field will enter the system time if SystemDefault is
  1520.         set true (2nd bit in 'status' parameter). Blank dates will be
  1521.         displayed as blanks or zeros if the global boolean
  1522.         DateZeroAsBlank is true or false respectively.
  1523.  
  1524.         Short version: GETDATESTR
  1525.  
  1526.  
  1527.  
  1528.  
  1529.  
  1530.  
  1531.         GET utilities  Page 24
  1532.  
  1533.  
  1534.         GETTIMESTRING
  1535.  
  1536.         This routine gets a string time from the screen using successive
  1537.         calls to the GETSTR procedure. It is similar to but considerably
  1538.         simpler than GETDATESTRING because all times are returned in a
  1539.         fixed 24 hour format with, invariably, a colon between the hour
  1540.         and minute subfields.
  1541.  
  1542.         The enter_default command (^J) enters the current system time.
  1543.         Pressing <return> on a blank time field will enter the system
  1544.         time if SystemDefault is set true (2nd bit in 'status'
  1545.         parameter). Blank times will be displayed as blanks or zeros if
  1546.         the global boolean TimeZeroAsBlank is true or false respectively.
  1547.  
  1548.         Short version: GETTIMESTR
  1549.  
  1550.         Possible changes:
  1551.  
  1552.         Add minimum and maximum parameters (like GETNUM), ALT-R to
  1553.         disable this validation.
  1554.  
  1555.         Allow use of 12 hour times with A.M. / P.M. indicator (like DOS).
  1556.  
  1557.         If minimum and maximum time parameters are added and a given call
  1558.         to this procedure excluded 00:00 as a valid time, bit 1 of status
  1559.         could be used to control whether entry of a time was mandatory.
  1560.         Alternatively, if an AM/PM indicator were added this could take a
  1561.         null/blank value to indicate that a blank time was not 00:00
  1562.         (midnight) but a blank field.
  1563.  
  1564.  
  1565.         GETATTR
  1566.  
  1567.         This procedure displays a palette of attributes similar to that
  1568.         used by Turbo Pascal's TINST program and allows the user to
  1569.         select one. The boolean parameter display_value controls whether
  1570.         or not the decimal value of the attribute is displayed at the
  1571.         bottom of the window.
  1572.  
  1573.         <Ret> selects foreground & background colours (attribute)
  1574.         <Esc> aborts leaving the attribute variable passed unchanged
  1575.  
  1576.         NOTE:
  1577.  
  1578.         The procedure InitWindow in Jim LeMay's WNDW unit should be run
  1579.         BEFORE this procedure is executed, preferably at the start of the
  1580.         program within which this procedure is used.
  1581.  
  1582.         GETATTR is not part of the GET unit.
  1583.  
  1584.  
  1585.  
  1586.  
  1587.  
  1588.  
  1589.  
  1590.  
  1591.  
  1592.  
  1593.                                                    GET utilities  Page 25
  1594.  
  1595.  
  1596.         DATES IN GENERAL
  1597.  
  1598.              There's an old joke about the computer industry liking
  1599.              standards so much that it's got hundreds of them. How
  1600.              old? Let's see, which date routine are you using?
  1601.  
  1602.  
  1603.         There are a plethora of "date procedures" available. Scott
  1604.         Bussinger, Ted Lassagne, Carley Phillips, David Dubois and others
  1605.         have contributed useful routines. All of them have their
  1606.         advantages and all suffer from one or more disadvantages.
  1607.  
  1608.         In general, the readily available date routines offer one or more
  1609.         flavours of Julian/Gregorian date conversion.
  1610.  
  1611.  
  1612.         Background
  1613.  
  1614.         Some of the shortcomings of the so-called Julian date routines
  1615.         currently available are discussed below.
  1616.  
  1617.         Most commonly these routines allow a word (2 bytes) for the
  1618.         Julian day number, enough for 64k serial numbered days -- or a
  1619.         range of 179 years (65,535 / 365) . DOS stores dates in this
  1620.         fashion and has such a range, as does Lotus 1-2-3 and many other
  1621.         programs. There are a few problems with this approach.
  1622.  
  1623.         BY DEFINITION a Julian date is a number of days from an agreed
  1624.         base date: 1/1/4713 B.C. This date was fixed by the astronomer
  1625.         Joseph Scaliger, after whose father Julius the Julian date scheme
  1626.         is named, to facilitate conversion between the Gregorian and
  1627.         earlier calendars.
  1628.  
  1629.         Microsoft's DOS dates are numbered from midnight on the last day
  1630.         of 1979. They are not true Julian dates because this additional
  1631.         information is required to decode them properly. Similarly, dates
  1632.         with other bases -- such as Smithsonian dates -- are not true
  1633.         Julian dates. (Smithsonian day 0 was 17 November, 1858. This is
  1634.         the base date used in date calculations on many computers, DEC's
  1635.         VAX machines e.g. The conversion factor, according to Ted
  1636.         Lassagne, is Smithsonian = Julian - 2400001).
  1637.  
  1638.         Note that it is not necessary for the user of date conversion
  1639.         routines to know the base date to use them. David Dubois'
  1640.         FASTDATE routine is based on a day 0 = "a magic number". So far
  1641.         as I can tell, this derives from his birthday. Unfortunately, his
  1642.         assembler code isn't as accurate as one might hope for under the
  1643.         circumstances.
  1644.  
  1645.         However, if one decides to expand the day range to encompass the
  1646.         agreed starting point for true Julian dates one runs into other
  1647.         problems. The generally employed Julian to Gregorian inter-
  1648.         conversion procedures derive from the published work of Tantzen
  1649.         (Algorithm No. 398, Communications of the ACM, August 1963,
  1650.         Vol. 6 No. 8). These calculations are valid for dates between
  1651.  
  1652.                      15 October 1572 and 28 February 4000 AD
  1653.  
  1654.         The former is the date the starting date of the Gregorian system,
  1655.  
  1656.         GET utilities  Page 26
  1657.  
  1658.  
  1659.         established by Papal Bull in March 1572. The Bull suppressed the
  1660.         5th to the 14th of October 1572, inclusive, in order to restore
  1661.         the vernal equinox to March 21st.
  1662.  
  1663.         Tantzen's routines are not valid after the latter date because
  1664.         they do not take into account the fact that years divisible by
  1665.         4,000 are not leap years.
  1666.  
  1667.         The applicability of the calculations to dates prior 15 October,
  1668.         1572 is at least debatable (Pope Gregory was not the first to
  1669.         eliminate days). Mathematically, the procedures are purportedly
  1670.         valid from the 1st of March, year 0. However, there was no year
  1671.         0! The Christian calendar went from 1 BC to 1 AD. It's better not
  1672.         to worry if Jesus Christ was on earth for a week or so BC,
  1673.         because we almost certainly don't know the true date of his
  1674.         birth. If the 1st of March following the birth of Christ is taken
  1675.         to be day number 0 we are not dealing with a Julian date. Some
  1676.         date routines treat the first day as day 1 (W. Madison's e.g.).
  1677.  
  1678.         No problem, we can add a constant number of days to it -- the
  1679.         number of days in January and February of the first year would be
  1680.         one option. To do this we need to know if the year was a leap
  1681.         year. That depends on whether you call it year 0 or year 1.
  1682.         However, we really ought to add the number of days between the
  1683.         1st of January 4713 BC and the 1st of March following Christ's
  1684.         birth. In calculating this total we need to bear in mind that
  1685.         years divisible by 4000 are not leap years and that there was no
  1686.         year zero (Are you with me? Sigh. I don't think I am!).
  1687.  
  1688.         I have yet to see any code which addresses this properly (Carley
  1689.         Phillips' routines are closest). To an extent the issue is
  1690.         academic, though it would be nice to have a(nother) standard for
  1691.         computing purposes. Days were dropped periodically prior to, and
  1692.         upon the introduction of, the Gregorian calendar to bring the
  1693.         calendar into line with the earth's astronomical calendar. Should
  1694.         date conversion routines know about the effects of these changes?
  1695.         I would argue against it, given that the Gregorian calendar was
  1696.         not adopted simultaneously all over the western world and we
  1697.         already have the confusion of different countries adopting it on
  1698.         different dates (Britain in 1752, Russia in 1918 and Turkey as
  1699.         recently as 1928 e.g.).
  1700.  
  1701.         Anyway...
  1702.  
  1703.         The whole business of date arithmetic requires either relatively
  1704.         adjacent dates or an agreed standard means of calculation (the
  1705.         actual base date is not particularly important). In the absence
  1706.         of a universally agreed procedure the GET procedures will have
  1707.         nothing to do with date arithmetic, for now anyway. You may
  1708.         select your own procedures (e.g. Ted Lassagne's EXDATE.PAS). For
  1709.         what it's worth, my preference is for the most recent popular
  1710.         base date (Smithsonian) because using it eliminates most of the
  1711.         problems, however it may not suit everybody.
  1712.  
  1713.  
  1714.  
  1715.  
  1716.  
  1717.  
  1718.                                                    GET utilities  Page 27
  1719.  
  1720.  
  1721.                                     Addendum
  1722.  
  1723.         It's a small world so please, if you disseminate documents for
  1724.         printing, bear the following recommendations in mind.
  1725.  
  1726.         Use 66 line pages (not 70 line A4, unprintable in N.America).
  1727.         Use formfeeds not linefeeds at the end of a page -- A MUST!
  1728.         Set the right margin so that the total width does not exceed 77
  1729.         characters -- the maximum the HP LaserJet II will print in
  1730.         Courier 10.
  1731.  
  1732.  
  1733.         RELEASE NOTES
  1734.  
  1735.         Since the beta distribution (October 1st) the following changes
  1736.         have been made:
  1737.  
  1738.         1. Minor bug in display of time and date fixed (wrong attribute
  1739.            for separator character).
  1740.         2. GETSTR display speed improved slightly.
  1741.         3. Support for SI format reals added to GETREAL.
  1742.  
  1743.  
  1744.         During the month:
  1745.  
  1746.         UPS began delivering all over the UK; there's a depot in Aberdeen
  1747.         not far from where I live (hey hey!). Borland laid off staff,
  1748.         started looking for dealers to handle technical support, and
  1749.         still didn't deliver Turbo Pascal v5.0 -- now expected in the UK
  1750.         in December (1988). Blaises! What Kahn a poor boy do? Will it be
  1751.         Wirth waiting for? We shall C, perhaps.
  1752.  
  1753.  
  1754.  
  1755.  
  1756.  
  1757.  
  1758.  
  1759.  
  1760.  
  1761.  
  1762.  
  1763.  
  1764.  
  1765.  
  1766.  
  1767.  
  1768.  
  1769.  
  1770.  
  1771.  
  1772.  
  1773.  
  1774.  
  1775.  
  1776.  
  1777.  
  1778.  
  1779.  
  1780.         GET utilities  Page 28