Blame client/display.c

Packit 34410b
/*
Packit 34410b
 *
Packit 34410b
 *  BlueZ - Bluetooth protocol stack for Linux
Packit 34410b
 *
Packit 34410b
 *  Copyright (C) 2012  Intel Corporation. All rights reserved.
Packit 34410b
 *
Packit 34410b
 *
Packit 34410b
 *  This program is free software; you can redistribute it and/or modify
Packit 34410b
 *  it under the terms of the GNU General Public License as published by
Packit 34410b
 *  the Free Software Foundation; either version 2 of the License, or
Packit 34410b
 *  (at your option) any later version.
Packit 34410b
 *
Packit 34410b
 *  This program is distributed in the hope that it will be useful,
Packit 34410b
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 34410b
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 34410b
 *  GNU General Public License for more details.
Packit 34410b
 *
Packit 34410b
 *  You should have received a copy of the GNU General Public License
Packit 34410b
 *  along with this program; if not, write to the Free Software
Packit 34410b
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
Packit 34410b
 *
Packit 34410b
 */
Packit 34410b
Packit 34410b
#ifdef HAVE_CONFIG_H
Packit 34410b
#include <config.h>
Packit 34410b
#endif
Packit 34410b
Packit 34410b
#define _GNU_SOURCE
Packit 34410b
#include <stdio.h>
Packit 34410b
#include <stdlib.h>
Packit 34410b
#include <stdarg.h>
Packit 34410b
#include <stdbool.h>
Packit 34410b
#include <ctype.h>
Packit 34410b
#include <readline/readline.h>
Packit 34410b
Packit 34410b
#include "display.h"
Packit 34410b
Packit 34410b
static char *saved_prompt = NULL;
Packit 34410b
static int saved_point = 0;
Packit 34410b
static rl_prompt_input_func saved_func = NULL;
Packit 34410b
static void *saved_user_data = NULL;
Packit 34410b
Packit 34410b
void rl_printf(const char *fmt, ...)
Packit 34410b
{
Packit 34410b
	va_list args;
Packit 34410b
	bool save_input;
Packit 34410b
	char *saved_line;
Packit 34410b
	int saved_point;
Packit 34410b
Packit 34410b
	save_input = !RL_ISSTATE(RL_STATE_DONE);
Packit 34410b
Packit 34410b
	if (save_input) {
Packit 34410b
		saved_point = rl_point;
Packit 34410b
		saved_line = rl_copy_text(0, rl_end);
Packit 34410b
		rl_save_prompt();
Packit 34410b
		rl_replace_line("", 0);
Packit 34410b
		rl_redisplay();
Packit 34410b
	}
Packit 34410b
Packit 34410b
	va_start(args, fmt);
Packit 34410b
	vprintf(fmt, args);
Packit 34410b
	va_end(args);
Packit 34410b
Packit 34410b
	if (save_input) {
Packit 34410b
		rl_restore_prompt();
Packit 34410b
		rl_replace_line(saved_line, 0);
Packit 34410b
		rl_point = saved_point;
Packit 34410b
		rl_forced_update_display();
Packit 34410b
		free(saved_line);
Packit 34410b
	}
Packit 34410b
}
Packit 34410b
Packit 34410b
void rl_hexdump(const unsigned char *buf, size_t len)
Packit 34410b
{
Packit 34410b
	static const char hexdigits[] = "0123456789abcdef";
Packit 34410b
	char str[68];
Packit 34410b
	size_t i;
Packit 34410b
Packit 34410b
	if (!len)
Packit 34410b
		return;
Packit 34410b
Packit 34410b
	str[0] = ' ';
Packit 34410b
Packit 34410b
	for (i = 0; i < len; i++) {
Packit 34410b
		str[((i % 16) * 3) + 1] = ' ';
Packit 34410b
		str[((i % 16) * 3) + 2] = hexdigits[buf[i] >> 4];
Packit 34410b
		str[((i % 16) * 3) + 3] = hexdigits[buf[i] & 0xf];
Packit 34410b
		str[(i % 16) + 51] = isprint(buf[i]) ? buf[i] : '.';
Packit 34410b
Packit 34410b
		if ((i + 1) % 16 == 0) {
Packit 34410b
			str[49] = ' ';
Packit 34410b
			str[50] = ' ';
Packit 34410b
			str[67] = '\0';
Packit 34410b
			rl_printf("%s\n", str);
Packit 34410b
			str[0] = ' ';
Packit 34410b
		}
Packit 34410b
	}
Packit 34410b
Packit 34410b
	if (i % 16 > 0) {
Packit 34410b
		size_t j;
Packit 34410b
		for (j = (i % 16); j < 16; j++) {
Packit 34410b
			str[(j * 3) + 1] = ' ';
Packit 34410b
			str[(j * 3) + 2] = ' ';
Packit 34410b
			str[(j * 3) + 3] = ' ';
Packit 34410b
			str[j + 51] = ' ';
Packit 34410b
		}
Packit 34410b
		str[49] = ' ';
Packit 34410b
		str[50] = ' ';
Packit 34410b
		str[67] = '\0';
Packit 34410b
		rl_printf("%s\n", str);
Packit 34410b
	}
Packit 34410b
}
Packit 34410b
Packit 34410b
void rl_prompt_input(const char *label, const char *msg,
Packit 34410b
				rl_prompt_input_func func, void *user_data)
Packit 34410b
{
Packit 34410b
	char prompt[256];
Packit 34410b
Packit 34410b
	/* Normal use should not prompt for user input to the value a second
Packit 34410b
	 * time before it releases the prompt, but we take a safe action. */
Packit 34410b
	if (saved_prompt)
Packit 34410b
		return;
Packit 34410b
Packit 34410b
	saved_point = rl_point;
Packit 34410b
	saved_prompt = strdup(rl_prompt);
Packit 34410b
	saved_func = func;
Packit 34410b
	saved_user_data = user_data;
Packit 34410b
Packit 34410b
	rl_set_prompt("");
Packit 34410b
	rl_redisplay();
Packit 34410b
Packit 34410b
	memset(prompt, 0, sizeof(prompt));
Packit 34410b
	snprintf(prompt, sizeof(prompt), COLOR_RED "[%s]" COLOR_OFF " %s ",
Packit 34410b
								label, msg);
Packit 34410b
	rl_set_prompt(prompt);
Packit 34410b
Packit 34410b
	rl_replace_line("", 0);
Packit 34410b
	rl_redisplay();
Packit 34410b
}
Packit 34410b
Packit 34410b
int rl_release_prompt(const char *input)
Packit 34410b
{
Packit 34410b
	rl_prompt_input_func func;
Packit 34410b
	void *user_data;
Packit 34410b
Packit 34410b
	if (!saved_prompt)
Packit 34410b
		return -1;
Packit 34410b
Packit 34410b
	/* This will cause rl_expand_prompt to re-run over the last prompt, but
Packit 34410b
	 * our prompt doesn't expand anyway. */
Packit 34410b
	rl_set_prompt(saved_prompt);
Packit 34410b
	rl_replace_line("", 0);
Packit 34410b
	rl_point = saved_point;
Packit 34410b
	rl_redisplay();
Packit 34410b
Packit 34410b
	free(saved_prompt);
Packit 34410b
	saved_prompt = NULL;
Packit 34410b
Packit 34410b
	func = saved_func;
Packit 34410b
	user_data = saved_user_data;
Packit 34410b
Packit 34410b
	saved_func = NULL;
Packit 34410b
	saved_user_data = NULL;
Packit 34410b
Packit 34410b
	func(input, user_data);
Packit 34410b
Packit 34410b
	return 0;
Packit 34410b
}