freebsd_amp_hwpstate/contrib/ncurses/tack/edit.c

978 lines
21 KiB
C
Raw Normal View History

/*
** Copyright (C) 1997 Free Software Foundation, Inc.
**
** This file is part of TACK.
**
** TACK is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2, or (at your option)
** any later version.
**
** TACK is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with TACK; see the file COPYING. If not, write to
** the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
** Boston, MA 02111-1307, USA.
*/
#include <tack.h>
#include <time.h>
#include <tic.h>
MODULE_ID("$Id: edit.c,v 1.3 1999/06/16 00:43:43 tom Exp $")
/*
* Terminfo edit features
*/
static void show_info(struct test_list *, int *, int *);
static void show_value(struct test_list *, int *, int *);
static void show_untested(struct test_list *, int *, int *);
static void show_changed(struct test_list *, int *, int *);
#define SHOW_VALUE 1
#define SHOW_EDIT 2
#define SHOW_DELETE 3
struct test_list edit_test_list[] = {
{MENU_CLEAR, 0, 0, 0, "i) display current terminfo", show_info, 0},
{0, 0, 0, 0, "w) write the current terminfo to a file", save_info, 0},
{SHOW_VALUE, 3, 0, 0, "v) show value of a selected cap", show_value, 0},
{SHOW_EDIT, 4, 0, 0, "e) edit value of a selected cap", show_value, 0},
{SHOW_DELETE, 3, 0, 0, "d) delete string", show_value, 0},
{0, 3, 0, 0, "m) show caps that have been modified", show_changed, 0},
{MENU_CLEAR + FLAG_CAN_TEST, 0, 0, 0, "c) show caps that can be tested", show_report, 0},
{MENU_CLEAR + FLAG_TESTED, 0, 0, 0, "t) show caps that have been tested", show_report, 0},
{MENU_CLEAR + FLAG_FUNCTION_KEY, 0, 0, 0, "f) show a list of function keys", show_report, 0},
{MENU_CLEAR, 0, 0, 0, "u) show caps defined that can not be tested", show_untested, 0},
{MENU_LAST, 0, 0, 0, 0, 0, 0}
};
static char change_pad_text[MAX_CHANGES][80];
struct test_list change_pad_list[MAX_CHANGES] = {
{MENU_LAST, 0, 0, 0, 0, 0, 0}
};
static void build_change_menu(struct test_menu *);
static void change_one_entry(struct test_list *, int *, int *);
struct test_menu change_pad_menu = {
0, 'q', 0,
"Select cap name", "change", 0,
build_change_menu, change_pad_list, 0, 0, 0
};
extern struct test_results *pads[STRCOUNT]; /* save pad results here */
static TERMTYPE original_term; /* terminal type description */
static char flag_boolean[BOOLCOUNT]; /* flags for booleans */
static char flag_numerics[NUMCOUNT]; /* flags for numerics */
static char flag_strings[STRCOUNT]; /* flags for strings */
static int xon_index; /* Subscript for (xon) */
int xon_shadow;
static int start_display; /* the display has just started */
static int display_lines; /* number of lines displayed */
/*
** send_info_string(str)
**
** Return the terminfo string prefixed by the correct seperator
*/
static void
send_info_string(
const char *str,
int *ch)
{
int len;
if (display_lines == -1) {
return;
}
len = strlen(str);
if (len + char_count + 3 >= columns) {
if (start_display == 0) {
put_str(",");
}
put_crlf();
if (++display_lines > lines) {
ptext("-- more -- ");
*ch = wait_here();
if (*ch == 'q') {
display_lines = -1;
return;
}
display_lines = 0;
}
if (len >= columns) {
/* if the terminal does not (am) then this loses */
if (columns) {
display_lines += ((strlen(str) + 3) / columns) + 1;
}
put_str(" ");
put_str(str);
start_display = 0;
return;
}
ptext(" ");
} else
if (start_display == 0) {
ptext(", ");
} else {
ptext(" ");
}
ptext(str);
start_display = 0;
}
/*
** show_info(test_list, status, ch)
**
** Display the current terminfo
*/
static void
show_info(
struct test_list *t GCC_UNUSED,
int *state GCC_UNUSED,
int *ch)
{
int i;
char buf[1024];
display_lines = 1;
start_display = 1;
for (i = 0; i < BOOLCOUNT; i++) {
if ((i == xon_index) ? xon_shadow : CUR Booleans[i]) {
send_info_string(boolnames[i], ch);
}
}
for (i = 0; i < NUMCOUNT; i++) {
if (CUR Numbers[i] >= 0) {
sprintf(buf, "%s#%d", numnames[i], CUR Numbers[i]);
send_info_string(buf, ch);
}
}
for (i = 0; i < STRCOUNT; i++) {
if (CUR Strings[i]) {
sprintf(buf, "%s=%s", strnames[i],
print_expand(CUR Strings[i]));
send_info_string(buf, ch);
}
}
put_newlines(2);
*ch = REQUEST_PROMPT;
}
/*
** save_info_string(str, fp)
**
** Write the terminfo string prefixed by the correct seperator
*/
static void
save_info_string(
const char *str,
FILE *fp)
{
int len;
len = strlen(str);
if (len + display_lines >= 77) {
if (display_lines > 0) {
(void) fprintf(fp, "\n\t");
}
display_lines = 8;
} else
if (display_lines > 0) {
(void) fprintf(fp, " ");
display_lines++;
} else {
(void) fprintf(fp, "\t");
display_lines = 8;
}
(void) fprintf(fp, "%s,", str);
display_lines += len + 1;
}
/*
** save_info(test_list, status, ch)
**
** Write the current terminfo to a file
*/
void
save_info(
struct test_list *t,
int *state,
int *ch)
{
int i;
FILE *fp;
time_t now;
char buf[1024];
if ((fp = fopen(tty_basename, "w")) == (FILE *) NULL) {
(void) sprintf(temp, "can't open: %s", tty_basename);
ptextln(temp);
generic_done_message(t, state, ch);
return;
}
time(&now);
/* Note: ctime() returns a newline at the end of the string */
(void) fprintf(fp, "# Terminfo created by TACK for TERM=%s on %s",
tty_basename, ctime(&now));
(void) fprintf(fp, "%s|%s,\n", tty_basename, longname());
display_lines = 0;
for (i = 0; i < BOOLCOUNT; i++) {
if (i == xon_index ? xon_shadow : CUR Booleans[i]) {
save_info_string(boolnames[i], fp);
}
}
for (i = 0; i < NUMCOUNT; i++) {
if (CUR Numbers[i] >= 0) {
sprintf(buf, "%s#%d", numnames[i], CUR Numbers[i]);
save_info_string(buf, fp);
}
}
for (i = 0; i < STRCOUNT; i++) {
if (CUR Strings[i]) {
sprintf(buf, "%s=%s", strnames[i],
_nc_tic_expand(CUR Strings[i], TRUE, TRUE));
save_info_string(buf, fp);
}
}
(void) fprintf(fp, "\n");
(void) fclose(fp);
sprintf(temp, "Terminfo saved as file: %s", tty_basename);
ptextln(temp);
}
/*
** show_value(test_list, status, ch)
**
** Display the value of a selected cap
*/
static void
show_value(
struct test_list *t,
int *state GCC_UNUSED,
int *ch)
{
struct name_table_entry const *nt;
char *s;
int n, op, b;
char buf[1024];
char tmp[1024];
ptext("enter name: ");
read_string(buf, 80);
if (buf[0] == '\0' || buf[1] == '\0') {
*ch = buf[0];
return;
}
if (line_count + 2 >= lines) {
put_clear();
}
op = t->flags & 255;
if ((nt = _nc_find_entry(buf, _nc_info_hash_table))) {
switch (nt->nte_type) {
case BOOLEAN:
if (op == SHOW_DELETE) {
if (nt->nte_index == xon_index) {
xon_shadow = 0;
} else {
CUR Booleans[nt->nte_index] = 0;
}
return;
}
b = nt->nte_index == xon_index ? xon_shadow :
CUR Booleans[nt->nte_index];
sprintf(temp, "boolean %s %s", buf,
b ? "True" : "False");
break;
case STRING:
if (op == SHOW_DELETE) {
CUR Strings[nt->nte_index] = (char *) 0;
return;
}
if (CUR Strings[nt->nte_index]) {
sprintf(temp, "string %s %s", buf,
expand(CUR Strings[nt->nte_index]));
} else {
sprintf(temp, "undefined string %s", buf);
}
break;
case NUMBER:
if (op == SHOW_DELETE) {
CUR Numbers[nt->nte_index] = -1;
return;
}
sprintf(temp, "numeric %s %d", buf,
CUR Numbers[nt->nte_index]);
break;
default:
sprintf(temp, "unknown");
break;
}
ptextln(temp);
} else {
sprintf(temp, "Cap not found: %s", buf);
ptextln(temp);
return;
}
if (op != SHOW_EDIT) {
return;
}
if (nt->nte_type == BOOLEAN) {
ptextln("Value flipped");
if (nt->nte_index == xon_index) {
xon_shadow = !xon_shadow;
} else {
CUR Booleans[nt->nte_index] = !CUR Booleans[nt->nte_index];
}
return;
}
ptextln("Enter new value");
read_string(buf, sizeof(buf));
switch (nt->nte_type) {
case STRING:
_nc_reset_input((FILE *) 0, buf);
_nc_trans_string(tmp);
s = (char *)malloc(strlen(tmp) + 1);
strcpy(s, tmp);
CUR Strings[nt->nte_index] = s;
sprintf(temp, "new string value %s", nt->nte_name);
ptextln(temp);
ptextln(expand(CUR Strings[nt->nte_index]));
break;
case NUMBER:
if (sscanf(buf, "%d", &n) == 1) {
CUR Numbers[nt->nte_index] = n;
sprintf(temp, "new numeric value %s %d",
nt->nte_name, n);
ptextln(temp);
} else {
sprintf(temp, "Illegal number: %s", buf);
ptextln(temp);
}
break;
default:
break;
}
}
/*
** get_string_cap_byname(name, long_name)
**
** Given a cap name, find the value
** Errors are quietly ignored.
*/
char *
get_string_cap_byname(
const char *name,
const char **long_name)
{
struct name_table_entry const *nt;
if ((nt = _nc_find_entry(name, _nc_info_hash_table))) {
if (nt->nte_type == STRING) {
*long_name = strfnames[nt->nte_index];
return (CUR Strings[nt->nte_index]);
}
}
*long_name = "??";
return (char *) 0;
}
/*
** get_string_cap_byvalue(value)
**
** Given a capability string, find its position in the data base.
** Return the index or -1 if not found.
*/
int
get_string_cap_byvalue(
const char *value)
{
int i;
if (value) {
for (i = 0; i < STRCOUNT; i++) {
if (CUR Strings[i] == value) {
return i;
}
}
/* search for translated strings */
for (i = 0; i < TM_last; i++) {
if (TM_string[i].value == value) {
return TM_string[i].index;
}
}
}
return -1;
}
/*
** show_changed(test_list, status, ch)
**
** Display a list of caps that have been changed.
*/
static void
show_changed(
struct test_list *t GCC_UNUSED,
int *state GCC_UNUSED,
int *ch)
{
int i, header = 1, v;
const char *a;
const char *b;
static char title[] = " old value cap new value";
char abuf[1024];
for (i = 0; i < BOOLCOUNT; i++) {
v = (i == xon_index) ? xon_shadow : CUR Booleans[i];
if (original_term.Booleans[i] != v) {
if (header) {
ptextln(title);
header = 0;
}
sprintf(temp, "%30d %6s %d",
original_term.Booleans[i], boolnames[i], v);
ptextln(temp);
}
}
for (i = 0; i < NUMCOUNT; i++) {
if (original_term.Numbers[i] != CUR Numbers[i]) {
if (header) {
ptextln(title);
header = 0;
}
sprintf(temp, "%30d %6s %d",
original_term.Numbers[i], numnames[i],
CUR Numbers[i]);
ptextln(temp);
}
}
for (i = 0; i < STRCOUNT; i++) {
a = original_term.Strings[i] ? original_term.Strings[i] : "";
b = CUR Strings[i] ? CUR Strings[i] : "";
if (strcmp(a, b)) {
if (header) {
ptextln(title);
header = 0;
}
strcpy(abuf, _nc_tic_expand(a, TRUE, TRUE));
sprintf(temp, "%30s %6s %s", abuf, strnames[i],
_nc_tic_expand(b, TRUE, TRUE));
putln(temp);
}
}
if (header) {
ptextln("No changes");
}
put_crlf();
*ch = REQUEST_PROMPT;
}
/*
** user_modified()
**
** Return TRUE if the user has modified the terminfo
*/
int
user_modified(void)
{
const char *a, *b;
int i, v;
for (i = 0; i < BOOLCOUNT; i++) {
v = (i == xon_index) ? xon_shadow : CUR Booleans[i];
if (original_term.Booleans[i] != v) {
return TRUE;
}
}
for (i = 0; i < NUMCOUNT; i++) {
if (original_term.Numbers[i] != CUR Numbers[i]) {
return TRUE;
}
}
for (i = 0; i < STRCOUNT; i++) {
a = original_term.Strings[i] ? original_term.Strings[i] : "";
b = CUR Strings[i] ? CUR Strings[i] : "";
if (strcmp(a, b)) {
return TRUE;
}
}
return FALSE;
}
/*****************************************************************************
*
* Maintain the list of capabilities that can be tested
*
*****************************************************************************/
/*
** mark_cap(name, flag)
**
** Mark the cap data base with the flag provided.
*/
static void
mark_cap(
char *name,
int flag)
{
struct name_table_entry const *nt;
if ((nt = _nc_find_entry(name, _nc_info_hash_table))) {
switch (nt->nte_type) {
case BOOLEAN:
flag_boolean[nt->nte_index] |= flag;
break;
case STRING:
flag_strings[nt->nte_index] |= flag;
break;
case NUMBER:
flag_numerics[nt->nte_index] |= flag;
break;
default:
sprintf(temp, "unknown cap type (%s)", name);
ptextln(temp);
break;
}
} else {
sprintf(temp, "Cap not found: %s", name);
ptextln(temp);
(void) wait_here();
}
}
/*
** can_test(name-list, flags)
**
** Scan the name list and get the names.
** Enter each name into the can-test data base.
** <space> ( and ) may be used as seperators.
*/
void
can_test(
const char *s,
int flags)
{
int ch, i, j;
char name[32];
if (s) {
for (i = j = 0; (name[j] = ch = *s); s++) {
if (ch == ' ' || ch == ')' || ch == '(') {
if (j) {
name[j] = '\0';
mark_cap(name, flags);
}
j = 0;
} else {
j++;
}
}
if (j) {
mark_cap(name, flags);
}
}
}
/*
** cap_index(name-list, index-list)
**
** Scan the name list and return a list of indexes.
** <space> ( and ) may be used as seperators.
** This list is terminated with -1.
*/
void
cap_index(
const char *s,
int *inx)
{
struct name_table_entry const *nt;
int ch, i, j;
char name[32];
if (s) {
for (i = j = 0; ; s++) {
name[j] = ch = *s;
if (ch == ' ' || ch == ')' || ch == '(' || ch == 0) {
if (j) {
name[j] = '\0';
if ((nt = _nc_find_entry(name,
_nc_info_hash_table)) &&
(nt->nte_type == STRING)) {
*inx++ = nt->nte_index;
}
}
if (ch == 0) {
break;
}
j = 0;
} else {
j++;
}
}
}
*inx = -1;
}
/*
** cap_match(name-list, cap)
**
** Scan the name list and see if the cap is in the list.
** Return TRUE if we find an exact match.
** <space> ( and ) may be used as seperators.
*/
int
cap_match(
const char *names,
const char *cap)
{
char *s;
int c, l, t;
if (names) {
l = strlen(cap);
while ((s = strstr(names, cap))) {
c = (names == s) ? 0 : *(s - 1);
t = s[l];
if ((c == 0 || c == ' ' || c == '(') &&
(t == 0 || t == ' ' || t == ')')) {
return TRUE;
}
if (t == 0) {
break;
}
names = s + l;
}
}
return FALSE;
}
/*
** show_report(test_list, status, ch)
**
** Display a list of caps that can be tested
*/
void
show_report(
struct test_list *t,
int *state GCC_UNUSED,
int *ch)
{
int i, j, nc, flag;
const char *s;
const char *nx[BOOLCOUNT + NUMCOUNT + STRCOUNT];
flag = t->flags & 255;
nc = 0;
for (i = 0; i < BOOLCOUNT; i++) {
if (flag_boolean[i] & flag) {
nx[nc++] = boolnames[i];
}
}
for (i = 0; i < NUMCOUNT; i++) {
if (flag_numerics[i] & flag) {
nx[nc++] = numnames[i];
}
}
for (i = 0; i < STRCOUNT; i++) {
if (flag_strings[i] & flag) {
nx[nc++] = strnames[i];
}
}
/* sort */
for (i = 0; i < nc - 1; i++) {
for (j = i + 1; j < nc; j++) {
if (strcmp(nx[i], nx[j]) > 0) {
s = nx[i];
nx[i] = nx[j];
nx[j] = s;
}
}
}
if (flag & FLAG_FUNCTION_KEY) {
ptextln("The following function keys can be tested:");
} else
if (flag & FLAG_CAN_TEST) {
ptextln("The following capabilities can be tested:");
} else
if (flag & FLAG_TESTED) {
ptextln("The following capabilities have been tested:");
}
put_crlf();
for (i = 0; i < nc; i++) {
sprintf(temp, "%s ", nx[i]);
ptext(temp);
}
put_newlines(1);
*ch = REQUEST_PROMPT;
}
/*
** show_untested(test_list, status, ch)
**
** Display a list of caps that are defined but cannot be tested.
** Don't bother to sort this list.
*/
static void
show_untested(
struct test_list *t GCC_UNUSED,
int *state GCC_UNUSED,
int *ch)
{
int i;
ptextln("Caps that are defined but cannot be tested:");
for (i = 0; i < BOOLCOUNT; i++) {
if (flag_boolean[i] == 0 && CUR Booleans[i]) {
sprintf(temp, "%s ", boolnames[i]);
ptext(temp);
}
}
for (i = 0; i < NUMCOUNT; i++) {
if (flag_numerics[i] == 0 && CUR Numbers[i] >= 0) {
sprintf(temp, "%s ", numnames[i]);
ptext(temp);
}
}
for (i = 0; i < STRCOUNT; i++) {
if (flag_strings[i] == 0 && CUR Strings[i]) {
sprintf(temp, "%s ", strnames[i]);
ptext(temp);
}
}
put_newlines(1);
*ch = REQUEST_PROMPT;
}
/*
** edit_init()
**
** Initialize the function key data base
*/
void
edit_init(void)
{
int i, j, lc;
char *lab;
struct name_table_entry const *nt;
int label_strings[STRCOUNT];
_nc_copy_termtype(&original_term, &cur_term->type);
for (i = 0; i < BOOLCOUNT; i++) {
original_term.Booleans[i] = CUR Booleans[i];
}
for (i = 0; i < NUMCOUNT; i++) {
original_term.Numbers[i] = CUR Numbers[i];
}
/* scan for labels */
for (i = lc = 0; i < STRCOUNT; i++) {
original_term.Strings[i] = CUR Strings[i];
if (strncmp(strnames[i], "lf", 2) == 0) {
flag_strings[i] |= FLAG_LABEL;
if (CUR Strings[i]) {
label_strings[lc++] = i;
}
}
}
/* scan for function keys */
for (i = 0; i < STRCOUNT; i++) {
if ((strnames[i][0] == 'k') && strcmp(strnames[i], "kmous")) {
flag_strings[i] |= FLAG_FUNCTION_KEY;
lab = (char *) 0;
for (j = 0; j < lc; j++) {
if (!strcmp(&strnames[i][1],
&strnames[label_strings[j]][1])) {
lab = CUR Strings[label_strings[j]];
break;
}
}
enter_key(strnames[i], CUR Strings[i], lab);
}
}
/* Lookup the translated strings */
for (i = 0; i < TM_last; i++) {
if ((nt = _nc_find_entry(TM_string[i].name,
_nc_info_hash_table)) && (nt->nte_type == STRING)) {
TM_string[i].index = nt->nte_index;
} else {
sprintf(temp, "TM_string lookup failed for: %s",
TM_string[i].name);
ptextln(temp);
}
}
if ((nt = _nc_find_entry("xon", _nc_info_hash_table)) != 0) {
xon_index = nt->nte_index;
}
xon_shadow = xon_xoff;
}
/*
** change_one_entry(test_list, status, ch)
**
** Change the padding on the selected cap
*/
static void
change_one_entry(
struct test_list *test,
int *state,
int *chp)
{
struct name_table_entry const *nt;
int i, j, x, star, slash, v, dot, ch;
const char *s;
char *t, *p;
const char *current_string;
char buf[1024];
char pad[1024];
i = test->flags & 255;
if (i == 255) {
/* read the cap name from the user */
ptext("enter name: ");
read_string(pad, 32);
if (pad[0] == '\0' || pad[1] == '\0') {
*chp = pad[0];
return;
}
if ((nt = _nc_find_entry(pad, _nc_info_hash_table)) &&
(nt->nte_type == STRING)) {
x = nt->nte_index;
current_string = CUR Strings[x];
} else {
sprintf(temp, "%s is not a string capability", pad);
ptext(temp);
generic_done_message(test, state, chp);
return;
}
} else {
x = tx_index[i];
current_string = tx_cap[i];
strcpy(pad, strnames[x]);
}
if (!current_string) {
ptextln("That string is not currently defined. Please enter a new value, including the padding delay:");
read_string(buf, sizeof(buf));
_nc_reset_input((FILE *) 0, buf);
_nc_trans_string(pad);
t = (char *)malloc(strlen(pad) + 1);
strcpy(t, pad);
CUR Strings[x] = t;
sprintf(temp, "new string value %s", strnames[x]);
ptextln(temp);
ptextln(expand(t));
return;
}
sprintf(buf, "Current value: (%s) %s", pad, _nc_tic_expand(current_string, TRUE, TRUE));
putln(buf);
ptextln("Enter new pad. 0 for no pad. CR for no change.");
read_string(buf, 32);
if (buf[0] == '\0' || (buf[1] == '\0' && isalpha(buf[0]))) {
*chp = buf[0];
return;
}
star = slash = FALSE;
for (j = v = dot = 0; (ch = buf[j]); j++) {
if (ch >= '0' && ch <= '9') {
v = ch - '0' + v * 10;
if (dot) {
dot++;
}
} else if (ch == '*') {
star = TRUE;
} else if (ch == '/') {
slash = TRUE;
} else if (ch == '.') {
dot = 1;
} else {
sprintf(temp, "Illegal character: %c", ch);
ptextln(temp);
ptext("General format: 99.9*/ ");
generic_done_message(test, state, chp);
return;
}
}
while (dot > 2) {
v /= 10;
dot--;
}
if (dot == 2) {
sprintf(pad, "%d.%d%s%s", v / 10, v % 10,
star ? "*" : "", slash ? "/" : "");
} else {
sprintf(pad, "%d%s%s",
v, star ? "*" : "", slash ? "/" : "");
}
s = current_string;
t = buf;
for (v = 0; (ch = *t = *s++); t++) {
if (v == '$' && ch == '<') {
while ((ch = *s++) && (ch != '>'));
for (p = pad; (*++t = *p++); );
*t++ = '>';
while ((*t++ = *s++));
pad[0] = '\0';
break;
}
v = ch;
}
if (pad[0]) {
sprintf(t, "$<%s>", pad);
}
if ((t = (char *)malloc(strlen(buf) + 1))) {
strcpy(t, buf);
CUR Strings[x] = t;
if (i != 255) {
tx_cap[i] = t;
}
}
generic_done_message(test, state, chp);
}
/*
** build_change_menu(menu_list)
**
** Build the change pad menu list
*/
static void
build_change_menu(
struct test_menu *m)
{
int i, j, k;
char *s;
for (i = j = 0; i < txp; i++) {
if ((k = tx_index[i]) >= 0) {
s = _nc_tic_expand(tx_cap[i], TRUE, TRUE);
s[40] = '\0';
sprintf(change_pad_text[j], "%c) (%s) %s",
'a' + j, strnames[k], s);
change_pad_list[j].flags = i;
change_pad_list[j].lines_needed = 4;
change_pad_list[j].menu_entry = change_pad_text[j];
change_pad_list[j].test_procedure = change_one_entry;
j++;
}
}
strcpy(change_pad_text[j], "z) enter name");
change_pad_list[j].flags = 255;
change_pad_list[j].lines_needed = 4;
change_pad_list[j].menu_entry = change_pad_text[j];
change_pad_list[j].test_procedure = change_one_entry;
j++;
change_pad_list[j].flags = MENU_LAST;
if (m->menu_title) {
put_crlf();
ptextln(m->menu_title);
}
}