mirror of git://git.sv.gnu.org/nano.git
More DLR updates
git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@1236 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
This commit is contained in:
parent
6df90f5787
commit
cf287c87cd
16
ChangeLog
16
ChangeLog
|
@ -78,6 +78,12 @@ CVS Code -
|
|||
including all the header files, as rcfile.c does; this fixes
|
||||
a warning about ANSI C'S inability to handle blank files.
|
||||
(DLR)
|
||||
- Add new function is_cntrl_char() as a wrapper for iscntrl();
|
||||
this is needed to treat ASCII 0x80-0x9f as control characters
|
||||
consistently. (Without this, they will only be treated as
|
||||
such when gettext is used; when it isn't used, they will be
|
||||
printed as-is and be interpreted as commands by xterm, which
|
||||
will corrupt the display.) (DLR)
|
||||
- Add command line option -I/--ignorercfiles to ignore
|
||||
/etc/nanorc and ~/.nanorc. (Carl Drinkwater)
|
||||
- files.c:
|
||||
|
@ -161,6 +167,9 @@ CVS Code -
|
|||
do_backspace():
|
||||
- Make sure placewewant is set properly, and that the mark is
|
||||
moved backwards. (David Benbennick)
|
||||
do_delete():
|
||||
- Make sure placewewant is set properly, to match Pico's
|
||||
behavior. (DLR)
|
||||
clear_filename():
|
||||
- Remove this function, as it has unneeded functionality, is
|
||||
short enough to be inlined, and is only called in two spots
|
||||
|
@ -197,6 +206,8 @@ CVS Code -
|
|||
numbers properly in parse_rcfile() (see below) to the
|
||||
handlers for the -r and -T options as well, so that -r/-T 0
|
||||
can be treated separately from -r/-T string. (DLR)
|
||||
- Fix so that Esc-Esc-Space is properly treated as Ctrl-Space.
|
||||
(DLR)
|
||||
- proto.h:
|
||||
- Remove external declaration of the global int fill, since
|
||||
it's now static. (DLR)
|
||||
|
@ -263,9 +274,8 @@ CVS Code -
|
|||
(which should never occur under normal circumstances; they will
|
||||
only be there if the line had nulls in it and was unsunder()ed
|
||||
beforehand) as ^@'s. (DLR)
|
||||
- Display ASCII 0x80-0x9f as backslashes followed by 3-digit
|
||||
octal values to keep xterm from screwing up the display when
|
||||
some of them are printed as-is. (David Benbennick)
|
||||
- Fix to properly treat ASCII 128-159 as control characters.
|
||||
(DLR)
|
||||
statusbar():
|
||||
- Limit statusbar display to the number of columns less four, and
|
||||
don't allow it to go over its original row. (David Benbennick)
|
||||
|
|
4
cut.c
4
cut.c
|
@ -126,7 +126,7 @@ void cut_marked_segment(filestruct *top, size_t top_x, filestruct *bot,
|
|||
top->data = (char *)nrealloc(top->data,
|
||||
sizeof(char) * newsize);
|
||||
} else {
|
||||
totsize -= bot_x;
|
||||
totsize -= bot_x + 1;
|
||||
|
||||
/* Here, the remainder line might get longer, so we realloc
|
||||
it first. */
|
||||
|
@ -150,7 +150,7 @@ void cut_marked_segment(filestruct *top, size_t top_x, filestruct *bot,
|
|||
if (!destructive)
|
||||
tmp = copy_node(tmp);
|
||||
else
|
||||
totsize -= strlen(tmp->data);
|
||||
totsize -= strlen(tmp->data) + 1;
|
||||
add_to_cutbuffer(tmp);
|
||||
tmp = next;
|
||||
}
|
||||
|
|
53
files.c
53
files.c
|
@ -184,10 +184,10 @@ int read_file(FILE *f, const char *filename, int quiet)
|
|||
}
|
||||
/* Read the entire file into file struct */
|
||||
while ((input_int = getc(f)) != EOF) {
|
||||
input = (char) input_int;
|
||||
input = (char)input_int;
|
||||
#ifndef NANO_SMALL
|
||||
if (!ISSET(NO_CONVERT) && iscntrl((int) input) && input != '\t'
|
||||
&& input != '\r' && input != '\n') {
|
||||
if (!ISSET(NO_CONVERT) && is_cntrl_char((int)input)
|
||||
&& input != '\t' && input != '\r' && input != '\n') {
|
||||
/* If the file has binary chars in it, don't stupidly
|
||||
assume it's a DOS or Mac formatted file! */
|
||||
SET(NO_CONVERT);
|
||||
|
@ -1788,6 +1788,7 @@ int do_writeout(char *path, int exiting, int append)
|
|||
return do_writeout(answer, exiting, append);
|
||||
} else
|
||||
#endif
|
||||
#ifndef NANO_SMALL
|
||||
if (i == TOGGLE_DOS_KEY) {
|
||||
UNSET(MAC_FILE);
|
||||
TOGGLE(DOS_FILE);
|
||||
|
@ -1796,10 +1797,11 @@ int do_writeout(char *path, int exiting, int append)
|
|||
UNSET(DOS_FILE);
|
||||
TOGGLE(MAC_FILE);
|
||||
return(do_writeout(answer, exiting, append));
|
||||
#ifndef NANO_SMALL
|
||||
} else if (i == TOGGLE_BACKUP_KEY) {
|
||||
TOGGLE(BACKUP_FILE);
|
||||
return(do_writeout(answer, exiting, append));
|
||||
#else
|
||||
if (0) {
|
||||
#endif
|
||||
} else if (i == NANO_PREPEND_KEY)
|
||||
return(do_writeout(answer, exiting, append == 2 ? 0 : 2));
|
||||
|
@ -2040,7 +2042,7 @@ char **username_tab_completion(char *buf, int *num_matches)
|
|||
|
||||
char **cwd_tab_completion(char *buf, int *num_matches)
|
||||
{
|
||||
char *dirName, *dirtmp = NULL, *tmp = NULL, *tmp2 = NULL;
|
||||
char *dirname, *dirtmp = NULL, *tmp = NULL, *tmp2 = NULL;
|
||||
char **matches = (char **) NULL;
|
||||
DIR *dir;
|
||||
struct dirent *next;
|
||||
|
@ -2052,23 +2054,23 @@ char **cwd_tab_completion(char *buf, int *num_matches)
|
|||
|
||||
/* Okie, if there's a / in the buffer, strip out the directory part */
|
||||
if (buf[0] != '\0' && strstr(buf, "/")) {
|
||||
dirName = charalloc(strlen(buf) + 1);
|
||||
dirname = charalloc(strlen(buf) + 1);
|
||||
tmp = buf + strlen(buf);
|
||||
while (*tmp != '/' && tmp != buf)
|
||||
tmp--;
|
||||
|
||||
tmp++;
|
||||
|
||||
strncpy(dirName, buf, tmp - buf + 1);
|
||||
dirName[tmp - buf] = '\0';
|
||||
strncpy(dirname, buf, tmp - buf + 1);
|
||||
dirname[tmp - buf] = '\0';
|
||||
|
||||
} else {
|
||||
|
||||
#ifdef PATH_MAX
|
||||
if ((dirName = getcwd(NULL, PATH_MAX+1)) == NULL)
|
||||
if ((dirname = getcwd(NULL, PATH_MAX + 1)) == NULL)
|
||||
#else
|
||||
/* The better, but apparently segfault-causing way */
|
||||
if ((dirName = getcwd(NULL, 0)) == NULL)
|
||||
if ((dirname = getcwd(NULL, 0)) == NULL)
|
||||
#endif /* PATH_MAX */
|
||||
return matches;
|
||||
else
|
||||
|
@ -2076,23 +2078,23 @@ char **cwd_tab_completion(char *buf, int *num_matches)
|
|||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "\nDir = %s\n", dirName);
|
||||
fprintf(stderr, "\nDir = %s\n", dirname);
|
||||
fprintf(stderr, "\nbuf = %s\n", buf);
|
||||
fprintf(stderr, "\ntmp = %s\n", tmp);
|
||||
#endif
|
||||
|
||||
dirtmp = real_dir_from_tilde(dirName);
|
||||
free(dirName);
|
||||
dirName = dirtmp;
|
||||
dirtmp = real_dir_from_tilde(dirname);
|
||||
free(dirname);
|
||||
dirname = dirtmp;
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "\nDir = %s\n", dirName);
|
||||
fprintf(stderr, "\nDir = %s\n", dirname);
|
||||
fprintf(stderr, "\nbuf = %s\n", buf);
|
||||
fprintf(stderr, "\ntmp = %s\n", tmp);
|
||||
#endif
|
||||
|
||||
|
||||
dir = opendir(dirName);
|
||||
dir = opendir(dirname);
|
||||
if (!dir) {
|
||||
/* Don't print an error, just shut up and return */
|
||||
*num_matches = 0;
|
||||
|
@ -2119,8 +2121,8 @@ char **cwd_tab_completion(char *buf, int *num_matches)
|
|||
before we check it */
|
||||
|
||||
if (operating_dir) {
|
||||
tmp2 = charalloc(strlen(dirName) + strlen(next->d_name) + 2);
|
||||
strcpy(tmp2, dirName);
|
||||
tmp2 = charalloc(strlen(dirname) + strlen(next->d_name) + 2);
|
||||
strcpy(tmp2, dirname);
|
||||
strcat(tmp2, "/");
|
||||
strcat(tmp2, next->d_name);
|
||||
if (check_operating_dir(tmp2, 1)) {
|
||||
|
@ -2342,7 +2344,6 @@ char *input_tab(char *buf, int place, int *lastwastab, int *newplace, int *list)
|
|||
*list = 1;
|
||||
} else
|
||||
beep();
|
||||
|
||||
}
|
||||
|
||||
/* Only refresh the edit window if we don't have a list of filename
|
||||
|
@ -2357,7 +2358,8 @@ char *input_tab(char *buf, int place, int *lastwastab, int *newplace, int *list)
|
|||
#ifndef DISABLE_BROWSER
|
||||
|
||||
/* Return the stat of the file pointed to by path */
|
||||
struct stat filestat(const char *path) {
|
||||
struct stat filestat(const char *path)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
stat(path, &st);
|
||||
|
@ -2367,7 +2369,8 @@ struct stat filestat(const char *path) {
|
|||
/* Our sort routine for file listings - sort directories before
|
||||
* files, and then alphabetically
|
||||
*/
|
||||
int diralphasort(const void *va, const void *vb) {
|
||||
int diralphasort(const void *va, const void *vb)
|
||||
{
|
||||
struct stat file1info, file2info;
|
||||
char *a = *(char **)va, *b = *(char **)vb;
|
||||
int aisdir, bisdir;
|
||||
|
@ -2675,7 +2678,11 @@ char *do_browser(char *inpath)
|
|||
/* SPK for '.' path, get the current path via getcwd */
|
||||
if (!strcmp(path, "./..")) {
|
||||
free(path);
|
||||
#ifdef PATH_MAX
|
||||
path = getcwd(NULL, PATH_MAX + 1);
|
||||
#else
|
||||
path = getcwd(NULL, 0);
|
||||
#endif
|
||||
striponedir(path);
|
||||
align(&path);
|
||||
free_charptrarray(filelist, numents);
|
||||
|
@ -2864,7 +2871,7 @@ char *do_browse_from(char *inpath)
|
|||
/* If there's no / in the string, we may as well start from . */
|
||||
if (tmp == NULL || *tmp == '\0' || !strstr(tmp, "/")) {
|
||||
#ifdef PATH_MAX
|
||||
char *from = getcwd(NULL, PATH_MAX+1);
|
||||
char *from = getcwd(NULL, PATH_MAX + 1);
|
||||
#else
|
||||
char *from = getcwd(NULL, 0);
|
||||
#endif /* PATH_MAX */
|
||||
|
@ -2883,4 +2890,4 @@ char *do_browse_from(char *inpath)
|
|||
return do_browser(tmp);
|
||||
|
||||
}
|
||||
#endif
|
||||
#endif /* !DISABLE_BROWSER */
|
||||
|
|
5
nano.1
5
nano.1
|
@ -6,7 +6,7 @@
|
|||
.\" Public License for copying conditions. There is NO warranty.
|
||||
.\"
|
||||
.\" $Id$
|
||||
.TH NANO 1 "July 6, 2002"
|
||||
.TH NANO 1 "July 14, 2002"
|
||||
.\" Please adjust this date whenever revising the manpage.
|
||||
.\"
|
||||
.SH NAME
|
||||
|
@ -41,6 +41,9 @@ Write file in DOS format.
|
|||
.B \-F (\-\-multibuffer)
|
||||
Enable multiple file buffers, if available.
|
||||
.TP
|
||||
.B \-I (\-\-ignorercfiles)
|
||||
Don't look at /etc/nanorc or ~/.nanorc, if nanorc support is available.
|
||||
.TP
|
||||
.B \-K (\-\-keypad)
|
||||
Do not use the ncurses keypad() call unless necessary. Try this flag if
|
||||
you find that the arrow keys on the numeric keypad do not work for you
|
||||
|
|
|
@ -3,7 +3,7 @@ Content-type: text/html
|
|||
<HTML><HEAD><TITLE>Manpage of NANO</TITLE>
|
||||
</HEAD><BODY>
|
||||
<H1>NANO</H1>
|
||||
Section: User Commands (1)<BR>Updated: July 5, 2002<BR><A HREF="#index">Index</A>
|
||||
Section: User Commands (1)<BR>Updated: July 14, 2002<BR><A HREF="#index">Index</A>
|
||||
<A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR>
|
||||
|
||||
|
||||
|
@ -56,6 +56,10 @@ Write file in DOS format.
|
|||
|
||||
<DD>
|
||||
Enable multiple file buffers, if available.
|
||||
<DT><B>-I (--ignorercfiles)</B>
|
||||
|
||||
<DD>
|
||||
Don't look at /etc/nanorc or ~/.nanorc, if nanorc support is available.
|
||||
<DT><B>-K (--keypad)</B>
|
||||
|
||||
<DD>
|
||||
|
@ -229,6 +233,6 @@ used by others).
|
|||
This document was created by
|
||||
<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>,
|
||||
using the manual pages.<BR>
|
||||
Time: 03:38:25 GMT, July 06, 2002
|
||||
Time: 00:51:19 GMT, July 14, 2002
|
||||
</BODY>
|
||||
</HTML>
|
||||
|
|
16
nano.c
16
nano.c
|
@ -1066,6 +1066,8 @@ int do_delete(void)
|
|||
if (current->next == filebot && current->data[0] == '\0')
|
||||
blbf = 1;
|
||||
|
||||
placewewant = xplustabs();
|
||||
|
||||
if (current_x != strlen(current->data)) {
|
||||
/* Let's get dangerous */
|
||||
memmove(¤t->data[current_x], ¤t->data[current_x + 1],
|
||||
|
@ -2129,10 +2131,8 @@ static int break_line(const char *line, int goal, int force) {
|
|||
space_loc = cur_loc;
|
||||
assert(*line != '\t');
|
||||
|
||||
if (iscntrl(*line))
|
||||
if (is_cntrl_char(*line))
|
||||
goal -= 2;
|
||||
else if ((unsigned char) *line >= 0x80 && (unsigned char) *line <= 0x9f)
|
||||
goal -= 4;
|
||||
else
|
||||
goal--;
|
||||
}
|
||||
|
@ -3421,11 +3421,13 @@ int main(int argc, char *argv[])
|
|||
break;
|
||||
}
|
||||
}
|
||||
/* If the modify_control_seq is set, we received an Alt-Alt
|
||||
sequence before this, so we make this key a control sequence
|
||||
by subtracting 64 or 96, depending on its value. */
|
||||
/* If modify_control_seq is set, we received an Alt-Alt
|
||||
sequence before this, so we make this key a control sequence
|
||||
by subtracting 32, 64, or 96, depending on its value. */
|
||||
if (!keyhandled && modify_control_seq) {
|
||||
if (kbinput >= 'A' && kbinput < 'a')
|
||||
if (kbinput == ' ')
|
||||
kbinput -= 32;
|
||||
else if (kbinput >= 'A' && kbinput < 'a')
|
||||
kbinput -= 64;
|
||||
else if (kbinput >= 'a' && kbinput <= 'z')
|
||||
kbinput -= 96;
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
@smallbook
|
||||
@set EDITION 0.1
|
||||
@set VERSION 1.1.9
|
||||
@set UPDATED 27 Jun 2002
|
||||
@set UPDATED 14 Jul 2002
|
||||
|
||||
@dircategory Editors
|
||||
@direntry
|
||||
|
@ -119,6 +119,9 @@ Write file in DOS format.
|
|||
@item -F, --multibuffer
|
||||
Enable multiple file buffers, if available.
|
||||
|
||||
@item -I, --ignorercfiles
|
||||
Don't look at /etc/nanorc or ~/.nanorc, if nanorc support is available.
|
||||
|
||||
@item -K, --keypad
|
||||
Do not use the ncurses keypad() call unless necessary. Try this flag if
|
||||
you find that the arrow keys on the numeric keypad do not work for you
|
||||
|
|
1
proto.h
1
proto.h
|
@ -254,6 +254,7 @@ filestruct *findnextstr(int quiet, int bracket_mode, const filestruct *begin,
|
|||
const char *stristr(const char *haystack, const char *needle);
|
||||
const char *strstrwrapper(const char *haystack, const char *needle,
|
||||
const char *rev_start, int line_pos);
|
||||
int is_cntrl_char(int c);
|
||||
int num_of_digits(int n);
|
||||
int check_wildcard_match(const char *text, const char *pattern);
|
||||
void align(char **strp);
|
||||
|
|
11
search.c
11
search.c
|
@ -104,15 +104,10 @@ static int search_init(int replacing)
|
|||
|
||||
/* If using Pico messages, we do things the old fashioned way... */
|
||||
if (ISSET(PICO_MODE) && last_search[0]) {
|
||||
size_t last_search_len = strlen(last_search);
|
||||
|
||||
buf = charalloc(last_search_len > COLS / 3 ?
|
||||
COLS / 3 + 7 : last_search_len + 4);
|
||||
buf = charalloc(COLS / 3 + 7);
|
||||
/* We use COLS / 3 here because we need to see more on the line */
|
||||
if (last_search_len > COLS / 3)
|
||||
snprintf(buf, COLS / 3 + 7, " [%s...]", last_search);
|
||||
else
|
||||
sprintf(buf, " [%s]", last_search);
|
||||
sprintf(buf, " [%.*s%s]", COLS / 3, last_search,
|
||||
strlen(last_search) > COLS / 3 ? "..." : "");
|
||||
} else {
|
||||
buf = charalloc(1);
|
||||
buf[0] = '\0';
|
||||
|
|
8
utils.c
8
utils.c
|
@ -36,6 +36,14 @@
|
|||
#define _(string) (string)
|
||||
#endif
|
||||
|
||||
int is_cntrl_char(int c)
|
||||
{
|
||||
if (iscntrl(c) || ((c & 127) != 127 && iscntrl(c & 127)))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
int num_of_digits(int n)
|
||||
{
|
||||
int i = 1;
|
||||
|
|
42
winio.c
42
winio.c
|
@ -80,13 +80,13 @@ int xpt(const filestruct *fileptr, int index)
|
|||
if (tabs % tabsize == 0);
|
||||
else
|
||||
tabs += tabsize - (tabs % tabsize);
|
||||
} else if (fileptr->data[i] & 0x80)
|
||||
} else if (is_cntrl_char((int)fileptr->data[i]))
|
||||
tabs++;
|
||||
else if (fileptr->data[i] & 0x80)
|
||||
/* Make 8 bit chars only 1 column! */
|
||||
;
|
||||
else if (iscntrl((int) fileptr->data[i]))
|
||||
tabs++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return tabs;
|
||||
}
|
||||
|
||||
|
@ -113,10 +113,8 @@ size_t actual_x(const filestruct *fileptr, size_t xplus)
|
|||
for (c = fileptr->data; length < xplus && *c != '\0'; i++, c++) {
|
||||
if (*c == '\t')
|
||||
length += tabsize - length % tabsize;
|
||||
else if (iscntrl((int)*c))
|
||||
else if (is_cntrl_char((int)*c))
|
||||
length += 2;
|
||||
else if ((unsigned char) *c >= 0x80 && (unsigned char) *c <= 0x9f)
|
||||
length += 4;
|
||||
else
|
||||
length++;
|
||||
}
|
||||
|
@ -142,10 +140,8 @@ size_t strnlenpt(const char *buf, size_t size)
|
|||
for (; *buf != '\0' && size != 0; size--, buf++) {
|
||||
if (*buf == '\t')
|
||||
length += tabsize - (length % tabsize);
|
||||
else if (iscntrl((int)*buf))
|
||||
else if (is_cntrl_char((int)*buf))
|
||||
length += 2;
|
||||
else if ((unsigned char) *buf >= 0x80 && (unsigned char) *buf <= 0x9f)
|
||||
length += 4;
|
||||
else
|
||||
length++;
|
||||
}
|
||||
|
@ -610,7 +606,7 @@ void set_modified(void)
|
|||
/* Given a column, this returns the "page" it is on */
|
||||
/* "page" in the case of the display columns, means which set of 80 */
|
||||
/* characters is viewable (e.g.: page 1 shows from 1 to COLS) */
|
||||
inline int get_page_from_virtual(int virtual)
|
||||
int get_page_from_virtual(int virtual)
|
||||
{
|
||||
int page = 2;
|
||||
|
||||
|
@ -627,7 +623,7 @@ inline int get_page_from_virtual(int virtual)
|
|||
}
|
||||
|
||||
/* The inverse of the above function */
|
||||
inline int get_page_start_virtual(int page)
|
||||
int get_page_start_virtual(int page)
|
||||
{
|
||||
int virtual;
|
||||
virtual = --page * (COLS - 7);
|
||||
|
@ -636,7 +632,7 @@ inline int get_page_start_virtual(int page)
|
|||
return virtual;
|
||||
}
|
||||
|
||||
inline int get_page_end_virtual(int page)
|
||||
int get_page_end_virtual(int page)
|
||||
{
|
||||
return get_page_start_virtual(page) + COLS - 1;
|
||||
}
|
||||
|
@ -1065,21 +1061,13 @@ void update_line(filestruct * fileptr, int index)
|
|||
if (i < mark_beginx)
|
||||
virt_mark_beginx--;
|
||||
} else if (realdata[i] == 127) {
|
||||
/* Treat control characters as ^symbol (ASCII 1 - 31 omitting
|
||||
10, 127) */
|
||||
/* Treat delete characters (ASCII 127's) as ^?'s */
|
||||
fileptr->data[pos++] = '^';
|
||||
fileptr->data[pos++] = '?';
|
||||
if (i < current_x)
|
||||
virt_cur_x++;
|
||||
if (i < mark_beginx)
|
||||
virt_mark_beginx++;
|
||||
} else if (realdata[i] >= 1 && realdata[i] <= 31 && realdata[i] != 10) {
|
||||
fileptr->data[pos++] = '^';
|
||||
fileptr->data[pos++] = realdata[i] + 64;
|
||||
if (i < current_x)
|
||||
virt_cur_x++;
|
||||
if (i < mark_beginx)
|
||||
virt_mark_beginx++;
|
||||
} else if (realdata[i] == 10) {
|
||||
/* Treat newlines (ASCII 10's) embedded in a line as encoded
|
||||
nulls (ASCII 0's); the line in question should be run
|
||||
|
@ -1090,6 +1078,14 @@ void update_line(filestruct * fileptr, int index)
|
|||
virt_cur_x++;
|
||||
if (i < mark_beginx)
|
||||
virt_mark_beginx++;
|
||||
} else if (is_cntrl_char(realdata[i])) {
|
||||
/* Treat control characters as ^symbol's */
|
||||
fileptr->data[pos++] = '^';
|
||||
fileptr->data[pos++] = realdata[i] + 64;
|
||||
if (i < current_x)
|
||||
virt_cur_x++;
|
||||
if (i < mark_beginx)
|
||||
virt_mark_beginx++;
|
||||
} else {
|
||||
fileptr->data[pos++] = realdata[i];
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue