0

I am trying to learn how to use curses to handle input for my upcoming assignment. i was given a c program called test-curses.c which contained the following code...

#include <curses.h>
#include <stdio.h>
#include <stdlib.h>

// brief example of using curses.
// man 3 ncurses for introductory man page, and man 3 function name
// for more information on that function.

void setup_curses();
void unset_curses();

int main()
{

 setup_curses();

 move(5, 10);
 printw("Press any key to start.");
 refresh();
 int c = getch();

 nodelay(stdscr, true);
 erase();

 move(5, 10);
 printw("Press arrow keys, 'q' to quit.");
 refresh();

 c = getch();

 while(1)
 {
   if (c != ERR)
    {
  // in asn3, won't need to do any printing to screen.
  // instead, will rotate figure on left or right arrow keys, and
  // initiate thrust when space bar is pressed.
  erase();
  move(5,10);
  printw("Press arrow keys, 'q' to quit.");
  move(6, 10);
  if (c == KEY_DOWN)
    printw("down key pressed");
  else if (c == KEY_LEFT)
    printw("left key pressed");
  else if (c == KEY_RIGHT) 
    printw("right key pressed");
  else if (c == KEY_UP)
    printw("up key pressed");
  else if (c == 'q')
    break;
  refresh();

   }

   c = getch();

}

// must do this or else Terminal will be unusable
// (if there are problems, it's not that big a deal though ... just
// close the Terminal, and open a new one.)
unset_curses();

exit(EXIT_SUCCESS);
}

void setup_curses()
{
  // use return values.  see man pages.  likely just useful for error
  // checking (NULL or non-NULL, at least for init_scr)
  initscr();
  cbreak();
  noecho();
  // needed for cursor keys (even though says keypad)
  keypad(stdscr, true);
}

void unset_curses()
{
  keypad(stdscr, false);
  nodelay(stdscr, false);
  nocbreak();
  echo();
  endwin();
}

i run this program by typing the following into the terminal gcc -std=c99 -Wall -o tester test-curses.c -lcurses ./tester

and everything is fine and dandy. However when I modified the code to move a simple line drawing in sketchpad in response to the arrow keys I get major bugs. here is my modified program.

#include <curses.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

// brief example of using curses.
// man 3 ncurses for introductory man page, and man 3 function name
// for more information on that function.
typedef struct {
  long x, y, x1, y1;
  long deltax, deltay, deltax1, deltay1;
 } line_item;

line_item *line;
FILE * popen(const char*, const char*);
int pclose(FILE*);
void setup_curses();
void unset_curses();
void draw(line_item * line, FILE * executable);
void translate(line_item * line, double trans_x, double trans_y);

int main()
{
  FILE * executable;
  executable = popen("java -jar Sketchpad.jar", "w");
  assert( executable != NULL);

  setup_curses();

  move(5, 10);
  printw("Press any key to start.");
  refresh();
  int c = getch();

  nodelay(stdscr, true);
  erase();

  move(5, 10);
  printw("Press arrow keys, 'q' to quit.");
  refresh();

  c = getch();

  while(1)
  {
    if (c != ERR)
    {
      // in asn3, won't need to do any printing to screen.
      // instead, will rotate figure on left or right arrow keys, and
      // initiate thrust when space bar is pressed.
      erase();
      move(5,10);
      printw("Press arrow keys, 'q' to quit.");
      move(6, 10);
      if (c == KEY_DOWN){
        printw("down key pressed");
        translate(line, 0, -10);
        draw(line, executable);
      }
      else if (c == KEY_LEFT){
        printw("left key pressed");
        translate(line, -10, 0);
        draw(line, executable);
      }
      else if (c == KEY_RIGHT){ 
        printw("right key pressed");
        translate(line, 10, 0); 
        draw(line, executable); 
      }
      else if (c == KEY_UP){
        printw("up key pressed");
        translate(line, 10, 0); 
        draw(line, executable); 
      }
      else if (c == 'q')
        break;
      refresh();

    } 

    c = getch();
    pclose(executable);
  }

  // must do this or else Terminal will be unusable
  // (if there are problems, it's not that big a deal though ... just
  // close the Terminal, and open a new one.)
  unset_curses();

  exit(EXIT_SUCCESS);
}

void draw(line_item * line, FILE * executable)
{
  fprintf(executable, "eraseSegment %ld %ld %ld %ld", line->x, line->y, line->x1, line->y1);
  fprintf(executable, "drawSegment %ld %ld %ld %ld", line->deltax, line->deltay, line->deltax1, line->deltay1);
  fflush(executable);
}
void translate(line_item * line, double trans_x, double trans_y)
{
  line->x = line->deltax;
  line->y = line->deltay;
  line->x1 = line->deltax1;
  line->y1 = line->deltay1;

  line->deltax = line->x + trans_x;
  line->deltax1 = line->x1 + trans_x;
  line->deltay = line->y + trans_y;
  line->deltay1 = line->y1 + trans_y;
}

void setup_curses()
{
  // use return values.  see man pages.  likely just useful for error
  // checking (NULL or non-NULL, at least for init_scr)
  initscr();
  cbreak();
  noecho();
  // needed for cursor keys (even though says keypad)
  keypad(stdscr, true);
}

void unset_curses()
{
  keypad(stdscr, false);
  nodelay(stdscr, false);
  nocbreak();
  echo();
  endwin();
}

the current directory holds these two programs and Sketchpad.jar. the error I get when I run the second one looks like this....

ses.so.5.9
          7f100a23a000-7f100a23b000 r--p 0001f000 08:01 2882225                    /lib/x86_64-linux-gnu/libncurses.so.5.9
          7f100a23b000-7f100a23c000 rw-p 00020000 08:01 2882225                    /lib/x86_64-linux-gnu/libncurses.so.5.9
          7f100a23c000-7f100a25e000 r-xp 00000000 08:01 2877975                    /lib/x86_64-linux-gnu/ld-2.15.so
          7f100a428000-7f100a42c000 rw-p 00000000 00:00 0 
          7f100a45b000-7f100a45e000 rw-p 00000000 00:00 0 
          7f100a45e000-7f100a45f000 r--p 00022000 08:01 2877975                    /lib/x86_64-linux-gnu/ld-2.15.so
          7f100a45f000-7f100a461000 rw-p 00023000 08:01 2877975                    /lib/x86_64-linux-gnu/ld-2.15.so
          7ffffa0be000-7ffffa0df000 rw-p 00000000 00:00 0                          [stack]
         7ffffa19e000-7ffffa19f000 r-xp 00000000 00:00 0                          [vdso]
    ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
       Aborted (core dumped)

i do not understand what this is telling me, and what difference between the files has caused this mess. please help.

I should tell you something about the following commands sent to sketchpad drawSegment x y x1 y1 draws a line from (x,y) -> (x1, y1) in sketchpad window eraseSegment x y x1 y1 erases that line.

Keith Nicholas
  • 43,549
  • 15
  • 93
  • 156
wenincode
  • 376
  • 5
  • 10
  • 20
  • It sounds like you want to run your test program inside of gdb. That way, when you get a core dump, you can 1) get a traceback, and 2) possibly determine the values of relevant variables at the time of crash. – paulsm4 Nov 14 '12 at 01:50
  • i ran it with gdb and it gave me the following additional lines Program received signal SIGABRT, Aborted. 0x00007ffff7609425 in __GI_raise (sig=) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64 64 ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory. (gdb) – wenincode Nov 14 '12 at 01:52
  • When GDB catches a crash, you can use the `bt` (backtrace) command to see the call chain. The use the `up` command to go to your function. Then you can examine variables to see what might be wrong. Please read the [GDB documentation](http://www.gnu.org/software/gdb/documentation/). – Some programmer dude Nov 14 '12 at 07:19

1 Answers1

0

Well for starters your line pointer never points to anything real. That will likely cause a core dump.

a minimal edit fix you could do :-

line_item _line;
line_item *line;

then in main, before the loop do :-

line = &_line;
Keith Nicholas
  • 43,549
  • 15
  • 93
  • 156