Exemplo n.º 1
0
void wideTest(WINDOW *win)
{
    wchar_t tmp[513];
    size_t i;

    attrset(A_BOLD);
    mvaddstr(1, (COLS - 25) / 2, "Wide Character Input Test");
    attrset(A_NORMAL);

    mvaddstr(4, 1, "Enter a string: ");

    echo();

    get_wstr((wint_t *)tmp);
    addstr("\n\n String:\n\n ");
    addwstr(tmp);
    addstr("\n\n\n Hex:\n\n ");

    for (i = 0; i < wcslen(tmp); i++)
    {
        printw("%04x ", tmp[i]);
        addnwstr(tmp + i, 1);
        addstr("  ");
    }

    noecho();

    Continue2();
}
Exemplo n.º 2
0
int
main(int argc, char *argv[])
{
	int optc;
	int option_differences = 0,
	    option_differences_cumulative = 0,
			option_exec = 0,
			option_beep = 0,
      option_color = 0,
        option_errexit = 0,
	    option_help = 0, option_version = 0;
	double interval = 2;
	char *command;
	wchar_t *wcommand = NULL;
	char **command_argv;
	int command_length = 0;	/* not including final \0 */
	int wcommand_columns = 0;	/* not including final \0 */
	int wcommand_characters = 0; /* not including final \0 */
    watch_usec_t next_loop; /* next loop time in us, used for precise time
                               keeping only */
	int pipefd[2];
	int status;
	pid_t child;

	setlocale(LC_ALL, "");
	progname = argv[0];

	while ((optc = getopt_long(argc, argv, "+bced::hn:pvtx", longopts, (int *) 0))
	       != EOF) {
		switch (optc) {
		case 'b':
			option_beep = 1;
			break;
    case 'c':
      option_color = 1;
      break;
		case 'd':
			option_differences = 1;
			if (optarg)
				option_differences_cumulative = 1;
			break;
        case 'e':
            option_errexit = 1;
            break;
		case 'h':
			option_help = 1;
			break;
		case 't':
			show_title = 0;
			break;
		case 'x':
		  option_exec = 1;
			break;
		case 'n':
			{
				char *str;
				interval = strtod(optarg, &str);
				if (!*optarg || *str)
					do_usage();
				if(interval < 0.1)
					interval = 0.1;
				if(interval > ~0u/1000000)
					interval = ~0u/1000000;
			}
			break;
		case 'p':
			precise_timekeeping = 1;
			break;
		case 'v':
			option_version = 1;
			break;
		default:
			do_usage();
			break;
		}
	}

	if (option_version) {
		fprintf(stderr, "%s\n", VERSION);
		if (!option_help)
			exit(0);
	}

	if (option_help) {
		fprintf(stderr, usage, progname);
		fputs("  -b, --beep\t\t\t\tbeep if the command has a non-zero exit\n", stderr);
		fputs("  -d, --differences[=cumulative]\thighlight changes between updates\n", stderr);
		fputs("\t\t(cumulative means highlighting is cumulative)\n", stderr);
		fputs("  -e, --errexit\t\t\t\texit watch if the command has a non-zero exit\n", stderr);
		fputs("  -h, --help\t\t\t\tprint a summary of the options\n", stderr);
		fputs("  -n, --interval=<seconds>\t\tseconds to wait between updates\n", stderr);
        fputs("  -p, --precise\t\t\t\tprecise timing, ignore command run time\n", stderr);
		fputs("  -v, --version\t\t\t\tprint the version number\n", stderr);
		fputs("  -t, --no-title\t\t\tturns off showing the header\n", stderr);
		fputs("  -x, --exec\t\t\t\tpass command to exec instead of sh\n", stderr);
		exit(0);
	}

	if (optind >= argc)
		do_usage();

	command_argv=&(argv[optind]); /* save for later */

	command = strdup(argv[optind++]);
	command_length = strlen(command);
	for (; optind < argc; optind++) {
		char *endp;
		int s = strlen(argv[optind]);
		command = realloc(command, command_length + s + 2);	/* space and \0 */
		endp = command + command_length;
		*endp = ' ';
		memcpy(endp + 1, argv[optind], s);
		command_length += 1 + s;	/* space then string length */
		command[command_length] = '\0';
	}

	// convert to wide for printing purposes
	//mbstowcs(NULL, NULL, 0);
	wcommand_characters = mbstowcs(NULL, command, 0);
	if(wcommand_characters < 0) {
		fprintf(stderr, "Unicode Handling Error\n");
		exit(1);
	}
	wcommand = (wchar_t*)malloc((wcommand_characters+1) * sizeof(wcommand));
	if(wcommand == NULL) {
		fprintf(stderr, "Unicode Handling Error (malloc)\n");
		exit(1);
	}
	mbstowcs(wcommand, command, wcommand_characters+1);
	wcommand_columns = wcswidth(wcommand, -1);



	get_terminal_size();

	/* Catch keyboard interrupts so we can put tty back in a sane state.  */
	signal(SIGINT, die);
	signal(SIGTERM, die);
	signal(SIGHUP, die);
	signal(SIGWINCH, winch_handler);

	/* Set up tty for curses use.  */
	curses_started = 1;
	initscr();
  if (option_color) {
    if (has_colors()) {
      start_color();
      use_default_colors();
      init_ansi_colors();
    } else
      option_color = 0;
  }
	nonl();
	noecho();
	cbreak();

	if (precise_timekeeping)
		next_loop = get_time_usec();

	for (;;) {
		time_t t = time(NULL);
		char *ts = ctime(&t);
		int tsl = strlen(ts);
		char *header;
		FILE *p;
		int x, y;
		int oldeolseen = 1;

		if (screen_size_changed) {
			get_terminal_size();
			resizeterm(height, width);
			clear();
			/* redrawwin(stdscr); */
			screen_size_changed = 0;
			first_screen = 1;
		}

		if (show_title) {
			// left justify interval and command,
			// right justify time, clipping all to fit window width

			int hlen = asprintf(&header, "Every %.1fs: ", interval);

			// the rules:
			//   width < tsl : print nothing
			//   width < tsl + hlen + 1: print ts
			//   width = tsl + hlen + 1: print header, ts
			//   width < tsl + hlen + 4: print header, ..., ts
			//   width < tsl + hlen + wcommand_columns: print header, truncated wcommand, ..., ts
			//   width > "": print header, wcomand, ts
			// this is slightly different from how it used to be
			if(width >= tsl) {
				if(width >= tsl + hlen + 1) {
					mvaddstr(0, 0, header);
					if(width >= tsl + hlen + 2) {
						if(width < tsl + hlen + 4) {
							mvaddstr(0, width - tsl - 4, "...  ");
						}else{
							if(width < tsl + hlen + wcommand_columns) {
								// print truncated
								int avail_columns = width - tsl - hlen;
								int using_columns = wcommand_columns;
								int using_characters = wcommand_characters;
								while(using_columns > avail_columns - 4) {
									using_characters--;
								using_columns = wcswidth(wcommand, using_characters);
								}
								mvaddnwstr(0, hlen, wcommand, using_characters);
								mvaddstr(0, width - tsl - 4, "... ");
							}else{
								mvaddwstr(0, hlen, wcommand);
							}
						}
					}
				}
				mvaddstr(0, width - tsl + 1, ts);
			}

			free(header);
		}

		/* allocate pipes */
		if (pipe(pipefd)<0) {
		  perror("pipe");
			do_exit(7);
	  }

		/* flush stdout and stderr, since we're about to do fd stuff */
		fflush(stdout);
		fflush(stderr);

		/* fork to prepare to run command */
		child=fork();

		if (child<0) { /* fork error */
		  perror("fork");
			do_exit(2);
		} else if (child==0) { /* in child */
			close (pipefd[0]); /* child doesn't need read side of pipe */
			close (1); /* prepare to replace stdout with pipe */
			if (dup2 (pipefd[1], 1)<0) { /* replace stdout with write side of pipe */
			  perror("dup2");
				exit(3);
			}
			dup2(1, 2); /* stderr should default to stdout */

			if (option_exec) { /* pass command to exec instead of system */
			  if (execvp(command_argv[0], command_argv)==-1) {
				  perror("exec");
				  exit(4);
				}
			} else {
		    status=system(command); /* watch manpage promises sh quoting */

			  /* propagate command exit status as child exit status */
			  if (!WIFEXITED(status)) { /* child exits nonzero if command does */
			    exit(1);
			  } else {
			    exit(WEXITSTATUS(status));
		    }
			}

		}

		/* otherwise, we're in parent */
		close(pipefd[1]); /* close write side of pipe */
		if ((p=fdopen(pipefd[0], "r"))==NULL) {
		  perror("fdopen");
			do_exit(5);
		}


		for (y = show_title; y < height; y++) {
			int eolseen = 0, tabpending = 0;
			wint_t carry = WEOF;
			for (x = 0; x < width; x++) {
				wint_t c = L' ';
				int attr = 0;

				if (!eolseen) {
					/* if there is a tab pending, just spit spaces until the
					   next stop instead of reading characters */
					if (!tabpending)
						do {
							if(carry == WEOF) {
								c = my_getwc(p);
							}else{
								c = carry;
								carry = WEOF;
							}
						}while (c != WEOF && !isprint(c) && c<128
						       && wcwidth(c) == 0
						       && c != L'\n'
						       && c != L'\t'
                   && (c != L'\033' || option_color != 1));
          if (c == L'\033' && option_color == 1) {
            x--;
            process_ansi(p);
            continue;
          }
					if (c == L'\n')
						if (!oldeolseen && x == 0) {
							x = -1;
							continue;
						} else
							eolseen = 1;
					else if (c == L'\t')
						tabpending = 1;
					if (x==width-1 && wcwidth(c)==2) {
						y++;
						x = -1; //process this double-width
						carry = c; //character on the next line
						continue; //because it won't fit here
					}
					if (c == WEOF || c == L'\n' || c == L'\t')
						c = L' ';
					if (tabpending && (((x + 1) % 8) == 0))
						tabpending = 0;
				}
				move(y, x);
				if (option_differences) {
						cchar_t oldc;
					in_wch(&oldc);
					attr = !first_screen
					    && ((wchar_t)c != oldc.chars[0]
						||
						(option_differences_cumulative
						 && (oldc.attr & A_ATTRIBUTES)));
				}
				if (attr)
					standout();
				addnwstr((wchar_t*)&c,1);
				if (attr)
					standend();
				if(wcwidth(c) == 0) { x--; }
				if(wcwidth(c) == 2) { x++; }
			}
			oldeolseen = eolseen;
		}

		fclose(p);

		/* harvest child process and get status, propagated from command */
		if (waitpid(child, &status, 0)<0) {
		  perror("waitpid");
			do_exit(8);
		};

		/* if child process exited in error, beep if option_beep is set */
		if ((!WIFEXITED(status) || WEXITSTATUS(status))) {
          if (option_beep) beep();
          if (option_errexit) do_exit(8);
		}

		first_screen = 0;
		refresh();
		if (precise_timekeeping) {
			watch_usec_t cur_time = get_time_usec();
			next_loop += USECS_PER_SEC*interval;
			if (cur_time < next_loop)
				usleep(next_loop - cur_time);
		} else
		usleep(interval * 1000000);
	}

	endwin();

	return 0;
}