Infinite loop that reads stdin in JScript - while-loop

I'm trying to create an infinite loop to poll for midi input. The loop I have here is technically infinite but I think what's happening is it's getting stuck on the WScript.StdIn.ReadLine() method. It seems that it waits each time for the user to enter something before it continues. I think this because when I enter a character, any midi input in that instance will get routed and the WScript.Echo message will go off.
How can I get it to not wait but check in that instance if there's a character or not? so that the loop doesn't get stopped waiting for input. Is there another ReadLine() method that would work for what I'm looking for?
Here's the code:
while (true) {
str = WScript.StdIn.ReadLine();
if (str == 'q')
break;
// WScript.StdOut.Write("the while loop continues..."
WScript.Echo("the while loop continues...")
msgStr = mox.GetMidiInput()
if (msgStr !== "") {
msgArray = msgStr.split(",")
tStamp = msgArray[0]
port = msgArray[1]
stat = msgArray[2]
data1 = msgArray[3]
data2 = msgArray[4]
mox.OutputMidiMsg( 3, stat, data1, data2);
} else {
continue;
}
}
EDIT:
Right now I just got rid of the ReadLine() because I read on MSDN that it waits for an enter keypress before it returns and I don't think there are any arguments to change that... so I have an infinite loop like I want but I have to resort to ctrl+c to exit it. Anybody have any ideas for a construct that would allow me to quit via the keyboard somehow?
EDIT 2:
I found out that midiox actually provides a method to be polled to exit the script and it works great.

Related

readLine() returns with nothing after a while loop with a readLine() as its condition

I'm trying to write a code that prints out whatever the user inputted into the console, but when I insert a while loop that use the readLine() function as its condition before it, the code would always return with nothing even if the user inputted something into the console. The code is here below:
fun main() {
while(readLine()=="A") print("A is inputted")
print(readLine()+" 123")
}
My intention was for when the user inputted (into the first readLine()) anything besides "A", the code would proceed to the next line, then prints out the next string inputted (into the second readLine()) joined with " 123".
For example: "asdfasdfaf 123", but in actuality it would just prints " 123" instead
Can anyone tell me why this is the case? And what would be the code that'll get the expected behavior? Any help will be appreciated since I'm new to this, thanks :)
EDIT:
I've found the solution a while after posting this and it's kind of weird.
fun main(args: Array<String>) {
while(readln()=="A") print("A is inputted")
readLine() // throwaway readLine()
print("${readLine()} 123")
}
I might be wrong but from what I've gathered here, after the while loop is stopped, the code somehow inputted nothing --which I assume is a null-- into the second readLine(). So I just put a throwaway readLine() between those two. I still don't know why this is the case though
By using readLine() twice, you are effectively asking for 2 pieces of input. This is what your code is currently doing:
You are reading the input (using a while loop? Do you mean to use an if statement instead?)
You are reading a second piece of input, and appending " 123" to the second piece of input.
Try this instead:
fun main() {
//Some kind of for or while loop if you want to constantly take input
val input = readLine()
if (input == "A") {
println("A has been input")
println("$input 123")
}
}
The way it's written, you have to type your "other" input twice - once so it's seen as not "A", and again when you try to print it - you hit two readLine() calls when you type something that isn't "A"
At a guess, you're getting " 123" because you type "asdfasdfaf", which exits the while loop, but then you hit the second readLine() and you're probably just hitting Return again, wondering why it hasn't printed. So the print statement reads in the empty line you just typed, and you get " 123"
If you want to have access to the non-"A" input, you need to store it - that way you can check it during your if condition, and use it in your print statement later. Here's a way you can do it
fun main() {
// do-while runs the loop -at least once- and checks the repeat condition at the end
do {
val input = readLine()
if (input == "A") print("A is inputted")
// this prints inside the loop, now we just need to exit it
else print("$input 123")
} while (input == "A") // stops looping the first time you get non-"A" input
}
which is what Cloudate9 was getting at
I am not exactly sure what you are looking to do, but the way I read and understand your post, this is what I came up with:
fun main() {
val input = readLine()
if (input == "A") {
println("A has been inputted")
} else {
println("$input 123")
}
}

How to know which line of code was being executed when a signal is received

I'm trying to do something like this
$SIG{ALRM} = sub {
print $line_number_when_alarm_went_off;
};
alarm 10;
# rest of the script
I'm using ALRM as an example, I will end up using a different signal to kill from the outside to trigger it. Is there a neat way of doing this sort of operation?
I have some slow scripts and sometimes I would like to send them a signal to know where the code is at that moment.
I want to make this as unobtrusive as possible so I could package it and add it to legacy code.
You can use caller in list context to get the package, file and line number of the place that the current sub got called from.
$SIG{ALRM} = sub {
my ($pkg, $file, $line) = caller;
CORE::say $line;
die;
};
alarm 2;
while (1) {
1;
}
This will output 11 (if I counted correctly, in my file it's 1740, and the $SIG line is 1730.
It also works with other signal handlers, like warn.
$SIG{__WARN__} = sub {
my ($pkg, $file, $line) = caller;
CORE::say $line;
};
warn 'foo';
This will output 7
Note that your code has a syntax error. You are assigning a hash reference as a signal handler, not a sub reference!

JOptionPane.showInputDialog Changing the ´cancel´ Button

So I'm trying to get a number input from a player in an RPG/survival type game, using showInputDialog to present the options, prompting the user to input a number. My problem is, I get a fatal error if they press cancel.
This is my current code:
String typeReader;
do{
typeReader = JOptionPane.showInputDialog(options);
}while(typeReader.isEmpty());
if (typeReader.isEmpty())
typeReader = "0";
charType = Integer.parseInt(typeReader);
and this is the error I get:
Exception in thread "main" java.lang.NullPointerException
at Game.main(Game.java:66)
Java Result: 1
BUILD SUCCESSFUL (total time: 14 seconds)
Ideally, if a user presses cancel the program would just read it as an empty String:
typeReader = "";
Can anyone help?
OK, you seem to be pretty new to this ;-)
First, you won't need the loop. Just write
String typeReader = JOptionPane.showInputDialog(options);
If the user clicks "Cancel", typeReader will be null afterwards. null is not an object, so you cannot call isEmpty() on it and you get the NullPointerException. Instead, you should check for null:
if (typeReader != null) {
...
}
You should read the Oracle tutorial on dialogs and maybe also the Javadoc.

GetMessage() function is calling itself infinitely (not coming out of loop)

I am implementing similar type of thing- I have some message box in the else part of the code below..what I get on debugging is that - I have same message box again and again and it doesn't end (which makes my program crash and I need to restart my laptop)..Is there any solution for it? I am using MFC application and creating a button on window explorer's preview pane. Every thing is fine but this is the problem that once if I enter in the loop below I am not able to come out (I mean there is some thing in DispatchMessage or TranslateMessage which calls this function again and again)..I couldn't find whats that ??
the code is as follow-
while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0)
{
if (bRet == -1)
{
// handle the error and possibly exit
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
//Onee message box here
}
}
finally i found that when i return true; in this loop the control will come out of the loop(but its not in good approach) but this getmessage was not useful for me infact when i reomved it my program was working fine. In its presence it was having infinite loop.
Because i created the dialog using CreateDialogParam() and then DialogProc is called through this CreateDialogParam() and then i used WM_Commnands to handle the message received according to the application and i feel no use of this getmessage (please point anyone if i am wrong)

sprintf() and WriteFile() affecting string Buffer

I have a very weird problem which I cannot seem to figure out. Unfortunately, I'm not even sure how to describe it without describing my entire application. What I am trying to do is:
1) read a byte from the serial port
2) store each char into tagBuffer as they are read
3) run a query using tagBuffer to see what type of tag it is (book or shelf tag)
4) depending on the type of tag, output a series of bytes corresponding to the type of tag
Most of my code is implemented and I can get the right tag code sent back out the serial port. But there are two lines that I've added as debug statements which when I tried to remove them, they cause my program to stop working.
The lines are the two lines at the very bottom:
sprintf(buf,"%s!\n", tagBuffer);
WriteFile(hSerial,buf,strlen(buf), &dwBytesWritten,&ovWrite);
If I try to remove them, "tagBuffer" will only store the last character as oppose being a buffer. Same thing with the next line, WriteFile().
I thought sprintf and WriteFile are I/O functions and would have no effect on variables.
I'm stuck and I need help to fix this.
//keep polling as long as stop character '-' is not read
while(szRxChar != '-')
{
// Check if a read is outstanding
if (HasOverlappedIoCompleted(&ovRead))
{
// Issue a serial port read
if (!ReadFile(hSerial,&szRxChar,1,
&dwBytesRead,&ovRead))
{
DWORD dwErr = GetLastError();
if (dwErr!=ERROR_IO_PENDING)
return dwErr;
}
}
// resets tagBuffer in case tagBuffer is out of sync
time_t t_time = time(0);
char buf[50];
if (HasOverlappedIoCompleted(&ovWrite))
{
i=0;
}
// Wait 5 seconds for serial input
if (!(HasOverlappedIoCompleted(&ovRead)))
{
WaitForSingleObject(hReadEvent,RESET_TIME);
}
// Check if serial input has arrived
if (GetOverlappedResult(hSerial,&ovRead,
&dwBytesRead,FALSE))
{
// Wait for the write
GetOverlappedResult(hSerial,&ovWrite,
&dwBytesWritten,TRUE);
if( strlen(tagBuffer) >= PACKET_LENGTH )
{
i = 0;
}
//load tagBuffer with byte stream
tagBuffer[i] = szRxChar;
i++;
tagBuffer[i] = 0; //char arrays are \0 terminated
//run query with tagBuffer
sprintf(query,"select type from rfid where rfidnum=\"");
strcat(query, tagBuffer);
strcat(query, "\"");
mysql_real_query(&mysql,query,(unsigned int)strlen(query));
//process result and send back to handheld
res = mysql_use_result(&mysql);
while(row = mysql_fetch_row(res))
{
printf("result of query is %s\n",row[0]);
string str = "";
str = string(row[0]);
if( str == "book" )
{
WriteFile(hSerial,BOOK_INDICATOR,strlen(BOOK_INDICATOR),
&dwBytesWritten,&ovWrite);
}
else if ( str == "shelf" )
{
WriteFile(hSerial,SHELF_INDICATOR,strlen(SHELF_INDICATOR),
&dwBytesWritten,&ovWrite);
}
else //this else doesn't work
{
WriteFile(hSerial,NOK,strlen(NOK),
&dwBytesWritten,&ovWrite);
}
}
mysql_free_result(res);
// Display a response to input
//printf("query is %s!\n", query);
//printf("strlen(tagBuffer) is %d!\n", strlen(tagBuffer));
//without these, tagBuffer only holds the last character
sprintf(buf,"%s!\n", tagBuffer);
WriteFile(hSerial,buf,strlen(buf), &dwBytesWritten,&ovWrite);
}
}
With those two lines, my output looks like this:
s sh she shel shelf shelf0 shelf00 BOOKCODE shelf0001
Without them, I figured out that tagBuffer and buf only stores the most recent character at any one time.
Any help at all will be greatly appreciated. Thanks.
Where are you allocating tagbuffer, how large is it?
It's possible that you are overwriting 'buf' because you are writing past the end of tagbuffer.
It seems unlikely that those two lines would have that effect on a correct program - maybe you haven't allocated sufficient space in buf for the whole length of the string in tagBuffer? This might cause a buffer overrun that is disguising the real problem?
The first thing I'd say is a piece of general advice: bugs aren't always where you think they are. If you've got something going on that doesn't seem to make sense, it often means that your assumptions somewhere else are wrong.
Here, it does seem very unlikely that an sprintf() and a WriteFile() will change the state of the "buf" array variable. However, those two lines of test code do write to "hSerial", while your main loop also reads from "hSerial". That sounds like a recipie for changing the behaviour of your program.
Suggestion: Change your lines of debugging output to store the output somewhere else: to a dialog box, or to a log file, or similar. Debugging output should generally not go to files used in the core logic, as that's too likely to change how the core logic behaves.
In my opinion, the real problem here is that you're trying to read and write the serial port from a single thread, and this is making the code more complex than it needs to be. I suggest that you read the following articles and reconsider your design:
Serial Port I/O from Joseph Newcomer's website.
Serial Communications in Win32 from MSDN.
In a multithreaded implementation, whenever the reader thread reads a message from the serial port you would then post it to your application's main thread. The main thread would then parse the message and query the database, and then queue an appropriate response to the writer thread.
This may sound more complex than your current design, but really it isn't, as Newcomer explains.
I hope this helps!