Console: abort Read or Readln - delphi

The console Read command does not recognize VK_ESCAPE. When using ReadConsoleInput, it is case insensitive. Is there something adequate to Read/Readln, which reports an abort?

The docs on Read() tell you it's for characters, not keys in general. It will also not help you to i.e. recognize PgUp or Print. That's also why it is so similar to Readln(), which unsurprisingly is for text, too, not separate keys being pressed.
A console process does not know by default what "abort" means. Common knowledge (even unbound to Windows) is that Ctrl+C and/or Ctrl+Break terminate the process.
Neither a ReadConsoleInput() nor is its KEY_EVENT record case insensitive: again you get keys, not characters. Which means you have to check if .dwControlKeyState has either SHIFT_PRESSED or CAPSLOCK_ON set to translate all the keys into an appropriate character (i.e. only Shift+S makes it an uppercase S).
It's up to you to decide when to interpret keys and when treating input as text/characters. Yes: recognizing Esc while using Readln() will never work - you'd have to reinvent your own Readln(), i.e. dealing with all the input, including your favorite keys, such as Esc. This will also help you discover which keys (that you type) lead to which VK constants.

Related

How do you quit a Forth environment?

If I am in a Forth environment, how do I leave, and how do I program a word to leave?
There are two ways to 'leave' Forth code, depending on what you need to do.
BYE
The Forth standard defines the word BYE to leave the Forth environment itself.
BYE ( -- )
Return control to the host operating system, if any.
This word gets a lot of creative interpretations when your Forth is not running as a program in an operating system. For example, on some systems where Forth is the operating system, BYE causes the system to restart instead, letting you load another OS.
BYE is part of the Programming-Tools Extensions word set.
QUIT
There is a word in the Core word set called QUIT, but it does not leave the environment. Instead, it leaves execution of a word and returns you back to the interpreter. This is why it is called 'QUIT', it is quitting in another sense.
QUIT ( -- ) ( R: i*x -- )
Empty the return stack, store zero in SOURCE-ID if it is present, make user input device the input source, and enter interpretation state. Do not display a message. Repeat the following:
Accept a line from the input source into the input buffer, set >IN to zero, and interpret.
Display the implementation-defined system prompt if in interpretation state, all processing has been completed, and no ambiguous condition exists.
Rather than defining QUIT as something like "this word returns you to the interpreter", instead QUIT is really defined as the interpreter itself in the Forth standard. In a factored Forth implementation, this makes sense: the word that puts you back in the interpreter and the interpreter itself can be the same word, they both can just clear the return stack and start interpreting.
And QUIT is the word you are more likely to see used in colon definitions, because it is a convenient way to break out of a stack of word executions, leaving the current contents of the data stack as-is, and returning to the interpreter. You can, of course, use BYE in a colon definition, for example in a custom interpreter or environment written in Forth to exit back to the operating system.

File status 23 on READ after START

My question is pertaining to a file status 23, which according to MicroFocus means that upon my attempt to READ from a .DAT file:
"Indicates no record found."
or
"Indicates a duplicate key condition. Attempt has been made to store a
record that would create a duplicate key in the indexed or relative
file or a duplicate alternate record key that does not allow
duplicates."
I have eliminated the fact that the latter is my issue because I'm allowing duplicates in this case.
The reason I'm stumped is that I'm using a START to navigate to the record inside of my .DAT file, and when I execute a READ just after the START has positioned my file pointer, I get the file status 23.
Here is my code:
900-GET-INST-ID.
OPEN INPUT INST-MST.
MOVE FALL-IN-INST TO INST-NAME-REC.
START INST-MST
KEY EQUAL TO INST-NAME-REC
INVALID KEY
DISPLAY "RECORD NOT FOUND"
NOT INVALID KEY
READ INST-MST
MOVE INST-ID-REC TO WS-INST-ID
END-START.
CLOSE INST-MST.
So when I am running this code my START successfully runs and goes into the NOT INVALID KEY block, and then the very next line executes and my read is null. How can this be if my alternate key (INST-NAME-REC) is actually found inside the .DAT?
I have ensured that my FD picture clauses match exactly in the ISAM Build program and in this program (the reading program).
The second reason you show is excluded not because you allow duplicate keys, but because that error message with that file-status is for a WRITE, and your failure is on a READ.
Here's your problem:
READ INST-MST
Here's how you fix it:
READ INST-MST NEXT
In COBOL 85, the READ statement has two formats. Format 1 is for a sequential read and Format 2 is for a keyed (random) read.
Unfortunately, the minimum READ syntax for both sequential and keyed reads is:
READ file-name
Which means if you use READ file-name the compiler will implicitly treat it as Format 1 or Format 2 depending on your SELECT statement.
READ file-name NEXT RECORD is identical to READ file-name NEXT.
Consult your actual documentation for a full explanation and discovery of possible Language Extensions from the vendor. If you consult closely, the behaviour of READ file-name with no further option depends on the type of file. With a keyed file, the default is a keyed READ. You key field (luckily) does not contain a key that exists, so you get the 23.
Even if it didn't work like that, what would be the point of not using the word NEXT? The compiler always knows what you tell it (which sometimes is not what you think you tell it), but in a situation like this, the human reader can be very unsure. The last thing you want to do when bug-hunting is break off to look at the manual to discover exactly how that behaves, and then try to work it if that behaviour was the one sought by the original coder. The bug? A bug? Intended, but sloppy, code? No-one wants to spend that time, and look, even now, it is you.
A couple of comments on your code.
Look up the FILE STATUS clause of the SELECT. Use it. One field per file. Check after each IO. It'll save you grief.
Once using the FILE STATUS, ditch the imperative parts of the IO statements (the something/NOT something) and replace by tests of the file-status field (using 88s).
It looks like you are OPENing and CLOSEing your look-up file all the time. Please don't. OPEN and CLOSE can be very heavy and time-consuming, so do them once per program per file. If you've done that because of a problem, find a correct resolution to that problem, don't use a hack.
Drop the full-stops/periods except where they are needed. This is COBOL 85, which means for 30 years the number of full-stops/periods required in the PROCEDURE DIVISION have been greatly reduced. Get modern, and take advantage of that, it'll save you Gotcha!s as you copy/paste code, leaving the one which shouldn't be there and changing the way the program behaves.

Scheme - Can a Double-Quote Delimit a Number?

I'm currently implementing a web-based Scheme environment for the kicks and giggles. Whilst implementing the parser, I stumbled across an oddity: some Scheme implementations state that a number's digits are read until a delimiter is met, but they also claim a double-quote is a valid delimiter. Successfully evaluating 123"abc" seems odd to me, but Racket seems to do it, displaying 123 and "abc" sequentially.
Confused, I booted up Gimp and went into it's Script-Fu console, which is Guile Scheme underneath. Giving it the same expression, it complains about an unbound value; so it's trying to parse it as a symbol?
I tried out JScheme as a 'third opinion'. It also complained about an undefined variable.
TL;DR: What should Scheme's behaviour be here?
Side-note: given the latter two's complaints, I tried the following:
(define 123"abc" 10)
123"abc"
It evaluated as 10. I'm confused. Shouldn't the double-quotes mark cause the parser to bail out rather than assign the symbol?
Try this on your chosen Scheme implementation (you may need to load in SRFI 6 before string ports will work):
(call-with-input-string "(123\"abc\")" read)
On both Racket and Guile, this reads in as (123 "abc"), which is exactly as I expect. From a quick glance at R5RS's "Lexical structure" section, I believe that implementations that return something different, like (|123"abc"|), are probably non-conformant.

How to "disable" a file output stream

I'm working on some legacy code in which there are a lot of WriteLn(F, '...') commands scattered pretty much all over the place. There is some useful information in these commands (what information variables contain, etc), so I'd prefer not to delete it or comment it out, but I want to stop the program from writing the file.
Is there any way that I can assign the F variable so that anything written to it is ignored? We use the console output, so that's not an option.
Going back a long long time to the good old days of DOS - If you assign 'f' to the device 'nul', then there should be no output.
assign (f, 'nul')
I don't know whether this still works in Windows.
Edit:
You could also assign 'f' to a file - assignfile (f, 'c:\1.txt') - for example.
Opening the null device and letting output go there would probably work. Under DOS, the performance of the NUL device was astonishingly bad IIRC (from what I understand, it wasn't buffered, so the system had to look up NUL in the device table when processing each byte) but I would not be at all surprised if it's improved under newer systems. In any case, that's probably the easiest thing you can do unless you really need to maximize performance. If performance is critical, it might in theory be possible to override the WriteLn function so it does nothing for certain files, but unfortunately I believe it allows syntax forms that were not permissible for any user-defined functions.
Otherwise, I would suggest doing a regular-expression find/replace to comment out the WriteLn statements in a fashion that can be mechanically restored.

Tex command which affects the next complete word

Is it possible to have a TeX command which will take the whole next word (or the next letters up to but not including the next punctuation symbol) as an argument and not only the next letter or {} group?
I’d like to have a \caps command on certain acronyms but don’t want to type curly brackets over and over.
First of all create your command, for example
\def\capsimpl#1{{\sc #1}}% Your main macro
The solution to catch a space or punctuation:
\catcode`\#=11
\def\addtopunct#1{\expandafter\let\csname punct#\meaning#1\endcsname\let}
\addtopunct{ }
\addtopunct{.} \addtopunct{,} \addtopunct{?}
\addtopunct{!} \addtopunct{;} \addtopunct{:}
\newtoks\capsarg
\def\caps{\capsarg{}\futurelet\punctlet\capsx}
\def\capsx{\expandafter\ifx\csname punct#\meaning\punctlet\endcsname\let
\expandafter\capsend
\else \expandafter\continuecaps\fi}
\def\capsend{\expandafter\capsimpl\expandafter{\the\capsarg}}
\def\continuecaps#1{\capsarg=\expandafter{\the\capsarg#1}\futurelet\punctlet\capsx}
\catcode`\#=12
#Debilski - I wrote something similar to your active * code for the acronyms in my thesis. I activated < and then \def<#1> to print the acronym, as well as the expansion if it's the first time it's encountered. I also went a bit off the deep end by allowing defining the expansions in-line and using the .aux files to send the expansions "back in time" if they're used before they're declared, or to report errors if an acronym is never declared.
Overall, it seemed like it would be a good idea at the time - I rarely needed < to be catcode 12 in my actual text (since all my macros were in a separate .sty file), and I made it behave in math mode, so I couldn't foresee any difficulties. But boy was it brittle... I don't know how many times I accidentally broke my build by changing something seemingly unrelated. So all that to say, be very careful activating characters that are even remotely commonly-used.
On the other hand, with XeTeX and higher unicode characters, it's probably a lot safer, and there are generally easy ways to type these extra characters, such as making a multi (or compose) key (I usually map either numlock or one of the windows keys to this), so that e.g. multi-!-! produces ¡). Or if you're running in emacs, you can use C-\ to switch into TeX input mode briefly to insert unicode by typing the TeX command for it (though this is a pain for actually typing TeX documents, since it intercepts your actual \'s, and please please don't try defining your own escape character!)
Regarding whitespace after commands: see package xspace, and TeX FAQ item Commands gobble following space.
Now why this is very difficult: as you noted yourself, things like that can only be done by changing catcodes, it seems. Catcodes are assigned to characters when TeX reads them, and TeX reads one line at a time, so you can not do anything with other spaces on the same line, IMHO. There might be a way around this, but I do not see it.
Dangerous code below!
This code will do what you want only at the end of the line, so if what you want is more "fluent" typing without brackets, but you are willing to hit 'return' after each acronym (and not run any auto-indent later), you can use this:
\def\caps{\begingroup\catcode`^^20 =11\mcaps}
\def\mcaps#1{\def\next##1 {\sc #1##1\catcode`^^20 =10\endgroup\ }\next}
One solution might be setting another character as active and using this one for escaping. This does not remove the need for a closing character but avoids typing the \caps macro, thus making it overall easier to type.
Therefore under very special circumstances, the following works.
\catcode`\*=\active
\def*#1*{\textsc{\MakeTextLowercase{#1}}}
Now follows an *Acronym*.
Unfortunately, this makes uses of \section*{} impossible without additional macro definitions.
In Xetex, it seems to be possible to exploit unicode characters for this, so one could define
\catcode`\•=\active
\def•#1•{\textsc{\MakeTextLowercase{#1}}}
Now follows an •Acronym•.
Which should reduce the effects on other commands but of course needs to have the character ‘•’ mapped to the keyboard somewhere to be of use.

Resources