Automated test tools for Linux/ncurses
I have considered using Rational Function Tester and TestComplete.
RFT has explicit support for testing this type of application (text-mode linux) via built-in terminal emulation.
TestComplete does not support testing Linux apps directly, but can be made to work by "testing" a COM-enabled terminal emulation program (Attachmate Reflection at this stage), and using COM from the test scripts to do screen scraping.
Have also considered using Reflection as the terminal emulator and rolling my own test framework in C# and NUnit.
Edit: "Final" solution is using Terminator (a Java terminal emulator), extending it with an RMI interface and using TestNG...
How do I pass the output of a c program which use curses/ncurses to another program?
initscr
does the equivalent of newterm(NULL, stdout, stdin)
, which pretty well makes it impossible to also pipe output into some other utility. If you want to do both, you can force ncurses to use /dev/tty
for both input and output by replacing initscr()
with something like:
FILE* tty = fopen("/dev/tty", "r+");
SCREEN* screen = newterm(NULL, tty, tty);
set_term(screen);
If you do that, you'll want to avoid writing to stdout (if it hasn't been redirected) while ncurses is active, since ncurses assumes that no-one else is writing to the console.
It might be useful to change the behaviour of your application, depending on whether stdout
has been redirected. You could use isatty()
for a fairly conservative test.
I don't really understand why you think it is necessary to use atexit()
in your sample program. As soon as you call endwin()
, it's safe to write to stdout
. (But the printf
of Hi
in print_menu
is problematic.)
It's also possible to use stderr
as the ncurses output, on the assumption that it has not been redirected. I prefer the use of /dev/tty
because it doesn't interfere with the use of stderr
for error logging (invalidating the assumption that it has not been redirected). But if that's not important to you, newterm(NULL, stderr, stdin)
is possibly simpler.
In any case, make sure you always check return values for error indications (which I omitted in the above code snippet).
embedded software maintainability - configuration
I have one microcontroller but several projects which get compiled from the same source code. I think my scenario is similar to yours, at least to some extent. My solution was inspired by Linux kernel, as well.
config.h
All source code which needs to get access to some configuration parameter simply includes an header file called config.h
.
config.h
consists of just one line:
#include <config/project.h>
project.h
I have several configuration header files, one per project. A project.h
consists of macro definitions with values such as true
, false
, or constants:
#define CONFIG_FOO true
#define CONFIG_BAR false
#define CONFIG_TIME 100
check.c
This file checks configuration parameters for correctness:
- all parameters must be defined, even if not used or meaningful for that project
- unwanted parameter combinations are signalled
- parameter values are constrained.
#if !defined(CONFIG_FOO)
#error CONFIG_FOO not defined
#endif
#if !defined(CONFIG_BAR)
#error CONFIG_BAR not defined
#endif
#if !defined(CONFIG_TIME)
#error CONFIG_TIME not defined
#endif
#if !(CONFIG_FOO ^ CONFIG_BAR)
#error either CONFIG_FOO or CONFIG_BAR should be se
#endif
#if CONFIG_TIME > 250
#error CONFIG_TIME too big
#endif
Makefile
By instructing the compiler to output the preprocessor macros, it is possible (with a bit of sed
expression) to feed the Makefile
with the same parameter values gprovided for a given project.
Create a function to check for key press in Unix using ncurses
You can use the nodelay()
function to turn getch()
into a non-blocking call, which returns ERR
if no key-press is available. If a key-press is available, it is pulled from the input queue, but you can push it back onto the queue if you like with ungetch()
.
#include <ncurses.h>
#include <unistd.h> /* only for sleep() */
int kbhit(void)
{
int ch = getch();
if (ch != ERR) {
ungetch(ch);
return 1;
} else {
return 0;
}
}
int main(void)
{
initscr();
cbreak();
noecho();
nodelay(stdscr, TRUE);
scrollok(stdscr, TRUE);
while (1) {
if (kbhit()) {
printw("Key pressed! It was: %d\n", getch());
refresh();
} else {
printw("No key pressed yet...\n");
refresh();
sleep(1);
}
}
}
Related Topics
How to Return Spawned Process Exit Code in Expect Script
What Is the Use of File Descriptor 255 in Bash Process
How to View and Edit the Ephemeral Port Range on Linux
Xampp: Another Web Server Daemon Is Already Running
Split Files Based on File Content and Pattern Matching
"Make" Command for Windows - Possible Options
Accessing a Cygwin Symlink from Windows
How to Do Foreach *.Mp3 File Recursively in a Bash Script
Is There Any Shortcut to Reference the Path of the First Argument in a Mv Command
Any Porting Available of Backtrace for Uclibc
"Cannot Execute Binary File" When Trying to Run a Shell Script on Linux
.Bashrc Not Read When Shell Script Is Invoked from Desktop Shortcut
How to Store the Output of a Git Command in a Variable
Fallocate() Command Equivalent in Os X
Docker Alpine Executable Binary Not Found Even If in Path
Position of a String Within a String Using Linux Shell Script