with all the other lists, have the replace list accept all the
same function keys as the search list, and clarify a few
shortcut descriptions.
+ - Convert nano to use the new parse_num() function to read in
+ numeric values at the command line and in the rcfile, and
+ duplicate the messages used in the rcfile in the command line
+ for consistency. (David Benbennick) DLR: Convert tabsize,
+ wrap_at, and fill to ssize_t in order to work with
+ parse_num() properly and also to increase their capacity
+ while keeping the ability to hold negative numbers in case of
+ errors. Also exit instead of calling usage() in the event of
+ an invalid fill value, for consistency with how an invalid
+ tabsize value is handled.
- files.c:
close_open_file()
- Tweak to no longer rely on the return values of
nregcomp()
- Rename the variable flags to eflags so as not to conflict with
the global flags. (DLR)
+- utils.c:
+ parse_num()
+ - New function to parse numeric values, so that we don't have to
+ duplicate code that calls strtol() all over the place. (David
+ Benbennick) DLR: Renamed from parse_int() to parse_num() and
+ converted to use ssize_t instead of int.
- winio.c:
get_control_kbinput()
- Fix erroneous debugging statement so that nano compiles with
/* Global variables */
#ifndef DISABLE_WRAPJUSTIFY
-/* wrap_at might be set in rcfile.c or nano.c */
-int wrap_at = -CHARS_FROM_EOL;/* Right justified fill value, allows resize */
+/* wrap_at might be set in rcfile.c or nano.c. */
+ssize_t wrap_at = -CHARS_FROM_EOL; /* Right justified fill value,
+ allows resize */
#endif
char *last_search = NULL; /* Last string we searched for */
to jump to when we go to the
next or previous line */
-int tabsize = -1; /* Our internal tabsize variable. The
- default value 8 is set in main(). */
+ssize_t tabsize = -1; /* Our internal tabsize variable. The
+ default value is set in main(). */
char *hblank = NULL; /* A horizontal blank line */
#ifndef DISABLE_HELP
#endif
#ifndef DISABLE_WRAPJUSTIFY
-static int fill = 0; /* Fill - where to wrap lines, basically */
+static ssize_t fill = 0; /* Fill - where to wrap lines,
+ basically */
#endif
#ifndef DISABLE_WRAPPING
static int same_line_wrap = FALSE; /* Whether wrapped text should
break;
#endif
case 'T':
- {
- int i;
- char *first_error;
-
- /* Using strtol() instead of atoi() lets us accept 0
- * while checking other errors. */
- i = (int)strtol(optarg, &first_error, 10);
- if (errno == ERANGE || *optarg == '\0' || *first_error != '\0')
- usage();
- else
- tabsize = i;
- if (tabsize <= 0) {
- fprintf(stderr, _("Tab size is too small for nano...\n"));
- exit(1);
- }
+ if (parse_num(optarg, &tabsize) == -1 || tabsize <= 0) {
+ fprintf(stderr, _("Requested tab size %s invalid"), optarg);
+ fprintf(stderr, "\n");
+ exit(1);
}
break;
case 'V':
break;
#ifndef DISABLE_WRAPJUSTIFY
case 'r':
- {
- int i;
- char *first_error;
-
- /* Using strtol() instead of atoi() lets us accept 0
- * while checking other errors. */
- i = (int)strtol(optarg, &first_error, 10);
- if (errno == ERANGE || *optarg == '\0' || *first_error != '\0')
- usage();
- else
- wrap_at = i;
+ if (parse_num(optarg, &wrap_at) == -1) {
+ fprintf(stderr, _("Requested fill size %s invalid"), optarg);
+ fprintf(stderr, "\n");
+ exit(1);
}
fill_flag_used = TRUE;
break;
char *operating_dir_cpy = operating_dir;
#endif
#ifndef DISABLE_WRAPPING
- int wrap_at_cpy = wrap_at;
+ ssize_t wrap_at_cpy = wrap_at;
#endif
#ifndef NANO_SMALL
char *backup_dir_cpy = backup_dir;
#ifndef DISABLE_SPELLER
char *alt_speller_cpy = alt_speller;
#endif
- int tabsize_cpy = tabsize;
+ ssize_t tabsize_cpy = tabsize;
long flags_cpy = flags;
#ifndef DISABLE_OPERATINGDIR
titlebar(NULL);
if (startline > 0)
- do_gotoline(startline, 0);
+ do_gotoline(startline, FALSE);
#ifndef NANO_SMALL
/* Return here after a SIGWINCH. */
/* Externs. */
#include <sys/stat.h>
-
#ifdef HAVE_REGEX_H
#include <regex.h>
#endif
-
#include "nano.h"
#ifndef DISABLE_WRAPJUSTIFY
-extern int wrap_at;
+extern ssize_t wrap_at;
#endif
extern int editwinrows;
extern int current_x, current_y, totlines;
#endif
extern long totsize;
extern long flags;
-extern int tabsize;
+extern ssize_t tabsize;
extern int search_last_line;
extern int currslen;
int do_replace_loop(const char *needle, const filestruct *real_current,
size_t *real_current_x, int wholewords);
void do_replace(void);
-void do_gotoline(int line, int save_pos);
+void do_gotoline(ssize_t line, int save_pos);
void do_gotoline_void(void);
#if defined (ENABLE_MULTIBUFFER) || !defined (DISABLE_SPELLER)
void do_gotopos(int line, int pos_x, int pos_y, int pos_placewewant);
#endif
int is_cntrl_char(int c);
int num_of_digits(int n);
+int parse_num(const char *str, ssize_t *val);
void align(char **strp);
void null_at(char **data, size_t index);
void unsunder(char *str, size_t true_len);
void parse_rcfile(FILE *rcstream)
{
char *buf, *ptr, *keyword, *option;
- int set = 0, i, j;
+ int set = 0, i;
buf = charalloc(1024);
while (fgets(buf, 1023, rcstream) != 0) {
#endif
#ifndef DISABLE_WRAPJUSTIFY
if (!strcasecmp(rcopts[i].name, "fill")) {
- char *first_error;
-
- /* Using strtol() instead of atoi() lets
- * us accept 0 while checking other
- * errors. */
- j = (int)strtol(option, &first_error, 10);
- if (errno == ERANGE || *option == '\0' || *first_error != '\0')
+ if (parse_num(option, &wrap_at) == -1)
rcfile_error(
- N_("Requested fill size %d invalid"),
- j);
- else
- wrap_at = j;
+ N_("Requested fill size %s invalid"),
+ option);
} else
#endif
#ifndef NANO_SMALL
else
#endif
if (!strcasecmp(rcopts[i].name, "tabsize")) {
- char *first_error;
-
- /* Using strtol instead of atoi lets us
- * accept 0 while checking other
- * errors. */
- j = (int)strtol(option, &first_error, 10);
- if (errno == ERANGE || *option == '\0' || *first_error != '\0')
- rcfile_error(N_("Requested tab size %d invalid"),
- j);
- else
- tabsize = j;
+ if (parse_num(option, &tabsize) == -1)
+ rcfile_error(
+ N_("Requested tab size %s invalid"),
+ option);
}
} else
SET(rcopts[i].flag);
#ifndef NANO_SMALL
search_history.current = search_history.next;
#endif
- i = (int)strtol(answer, &buf, 10); /* Just testing answer here. */
- if (!(errno == ERANGE || *answer == '\0' || *buf != '\0'))
- do_gotoline(-1, FALSE);
- else
- do_gotoline_void();
+ /* If answer parses as an integer, put it up on the
+ * statusbar. */
+ do_gotoline(parse_num(answer, NULL), FALSE);
/* Fall through. */
default:
return -1;
replace_abort();
}
-void do_gotoline(int line, int save_pos)
+void do_gotoline(ssize_t line, int save_pos)
{
if (line <= 0) { /* Ask for it */
char *ans = mallocstrcpy(NULL, answer);
#include "config.h"
-#include <stdio.h>
-#include <unistd.h>
#include <stdlib.h>
#include <string.h>
+#include <stdio.h>
+#include <unistd.h>
#include <ctype.h>
+#include <errno.h>
#include <assert.h>
#include "proto.h"
#include "nano.h"
return i;
}
+/* Read an int from str, and store it in *val (if val is not NULL). On
+ * error, we return -1 and don't change *val. */
+int parse_num(const char *str, ssize_t *val)
+{
+ char *first_error;
+ ssize_t j;
+
+ assert(str != NULL);
+ j = (ssize_t)strtol(str, &first_error, 10);
+ if (errno == ERANGE || *str == '\0' || *first_error != '\0')
+ return -1;
+ if (val != NULL)
+ *val = j;
+ return 0;
+}
+
/* Fix the memory allocation for a string. */
void align(char **strp)
{