2000-04-06 Timur Bakeyev <mc@bat.ru>
* file.c, widget.[ch]: Fixed long existing problems with filenames and input widgets, then char is greater than 128. They were processed incorrectly. As usual, char != unsigned char problem. 2000-03-03 Bjrn Eriksson <mdeans@algonet.se> * Similar patches came from Andrew V. Samoilov <sav@bcs.zp.ua>. * mad.[ch]: Some functions wrongly by-passed mad_alloc*() (causing problems when later g_free()ed. * Added mad_strndup(). * Repeated code collected in mad_fatal_error(). * The gcc-extension/C99-standard variable argument macros (adding __FILE__, __LINE__ before ', ...') would be nice. * Alloc_idx_hint and code added, the mad code was way too slow for my poor computer. A hash-table would be nice. * (mad_strconcat, mad_strdup_vprintf): g_malloc and g_new are undefined at the top of mad.c, so mad_alloc must be used.
Этот коммит содержится в:
родитель
02f3212280
Коммит
b192f71a88
@ -1,3 +1,29 @@
|
||||
2000-04-06 Timur Bakeyev <mc@bat.ru>
|
||||
|
||||
* file.c, widget.[ch]: Fixed long existing problems with filenames
|
||||
and input widgets, then char is greater than 128. They were processed
|
||||
incorrectly. As usual, char != unsigned char problem.
|
||||
|
||||
2000-03-03 BjЎrn Eriksson <mdeans@algonet.se>
|
||||
|
||||
* Similar patches came from Andrew V. Samoilov <sav@bcs.zp.ua>.
|
||||
|
||||
* mad.[ch]: Some functions wrongly by-passed mad_alloc*() (causing
|
||||
problems when later g_free()ed.
|
||||
|
||||
* Added mad_strndup().
|
||||
|
||||
* Repeated code collected in mad_fatal_error().
|
||||
|
||||
* The gcc-extension/C99-standard variable argument macros (adding
|
||||
__FILE__, __LINE__ before ', ...') would be nice.
|
||||
|
||||
* Alloc_idx_hint and code added, the mad code was way too slow for my
|
||||
poor computer. A hash-table would be nice.
|
||||
|
||||
* (mad_strconcat, mad_strdup_vprintf): g_malloc and g_new are
|
||||
undefined at the top of mad.c, so mad_alloc must be used.
|
||||
|
||||
2000-02-23 Norbert Warmuth <nwarmuth@privat.circular.de>
|
||||
|
||||
* main.c (parse_control_file): add missing right parentheses
|
||||
|
@ -393,6 +393,7 @@ background_attention (int fd, void *closure)
|
||||
resstr = (*(char * (*)(char *, char *, char *, char *))routine)
|
||||
(data [0], data [1], data [2], data [3]);
|
||||
break;
|
||||
default: g_assert_not_reached();
|
||||
}
|
||||
if (resstr){
|
||||
len = strlen (resstr);
|
||||
|
16
src/file.c
16
src/file.c
@ -188,14 +188,14 @@ convert_case (int c, enum CaseConvs *conversion)
|
||||
|
||||
static int transform_error = 0;
|
||||
|
||||
static char *
|
||||
do_transform_source (FileOpContext *ctx, char *source)
|
||||
static unsigned char *
|
||||
do_transform_source (FileOpContext *ctx, unsigned char *source)
|
||||
{
|
||||
int j, k, l, len;
|
||||
char *fnsource = x_basename (source);
|
||||
unsigned char *fnsource = x_basename (source);
|
||||
int next_reg;
|
||||
enum CaseConvs case_conv = NO_CONV;
|
||||
static char fntarget [MC_MAXPATHLEN];
|
||||
static unsigned char fntarget [MC_MAXPATHLEN];
|
||||
|
||||
len = strlen (fnsource);
|
||||
j = re_match (&ctx->rx, fnsource, len, 0, &ctx->regs);
|
||||
@ -259,11 +259,11 @@ do_transform_source (FileOpContext *ctx, char *source)
|
||||
return fntarget;
|
||||
}
|
||||
|
||||
static char *
|
||||
transform_source (FileOpContext *ctx, char *source)
|
||||
static unsigned char *
|
||||
transform_source (FileOpContext *ctx, unsigned char *source)
|
||||
{
|
||||
char *s = g_strdup (source);
|
||||
char *q;
|
||||
unsigned char *s = g_strdup (source);
|
||||
unsigned char *q;
|
||||
|
||||
/* We remove \n from the filename since regex routines would use \n as an anchor */
|
||||
/* this is just to be allowed to maniupulate file names with \n on it */
|
||||
|
163
src/mad.c
163
src/mad.c
@ -27,6 +27,7 @@
|
||||
#undef realloc
|
||||
#undef xmalloc
|
||||
#undef strdup
|
||||
#undef strndup
|
||||
#undef free
|
||||
|
||||
#undef g_malloc
|
||||
@ -34,6 +35,7 @@
|
||||
#undef g_calloc
|
||||
#undef g_realloc
|
||||
#undef g_strdup
|
||||
#undef g_strndup
|
||||
#undef g_free
|
||||
|
||||
#include <stdlib.h>
|
||||
@ -50,7 +52,7 @@
|
||||
|
||||
/* Maximum number of memory area handles,
|
||||
increase this if you run out of handles */
|
||||
#define MAD_MAX_AREAS 10000
|
||||
#define MAD_MAX_AREAS 20000 /* vfs leaks Lots of memory*/
|
||||
/* Maximum file name length */
|
||||
#define MAD_MAX_FILE 50
|
||||
/* Signature for detecting overwrites */
|
||||
@ -68,9 +70,17 @@ typedef struct {
|
||||
static mad_mem_area mem_areas [MAD_MAX_AREAS];
|
||||
static FILE *memlog;
|
||||
|
||||
#define MAD_CHECK_CALL_FACTOR 30 /* Perform actual test every N call. */
|
||||
static int Mad_check_call_delay;
|
||||
static int Alloc_idx_hint = 0;
|
||||
static struct /*mad_stats_struct*/ {
|
||||
int last_max_i;
|
||||
long check_call_cnt;
|
||||
} Stats = { -1, 0 } ;
|
||||
|
||||
void *watch_free_pointer = 0;
|
||||
|
||||
void
|
||||
void
|
||||
mad_init (void)
|
||||
{
|
||||
memlog = stderr;
|
||||
@ -95,6 +105,20 @@ static void mad_abort (char *message, int area, char *file, int line)
|
||||
kill (getpid (), 3);
|
||||
}
|
||||
|
||||
/* Code repeated in lots of places. Could be merged with mad_abort() above. */
|
||||
static void mad_fatal_error(const char *problem, void *ptr, const char *file, int line)
|
||||
{
|
||||
if (NULL != ptr) {
|
||||
fprintf(memlog, "MAD: %s: %p.\r\n", problem, ptr);
|
||||
} else {
|
||||
fprintf(memlog, "MAD: %s.\r\n", problem);
|
||||
}
|
||||
fprintf(memlog, " Discovered in file \"%s\" at line %d.\r\n", file, line);
|
||||
fprintf(memlog, "MAD: Aborting...\r\n");
|
||||
fflush(memlog);
|
||||
abort();
|
||||
}
|
||||
|
||||
/* Checks all the allocated memory areas.
|
||||
This is called everytime memory is allocated or freed.
|
||||
You can also call it anytime you think memory might be corrupted. */
|
||||
@ -102,6 +126,10 @@ void mad_check (char *file, int line)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (--Mad_check_call_delay > 0)
|
||||
return;
|
||||
Mad_check_call_delay = MAD_CHECK_CALL_FACTOR;
|
||||
|
||||
for (i = 0; i < MAD_MAX_AREAS; i++){
|
||||
if (! mem_areas [i].in_use)
|
||||
continue;
|
||||
@ -110,6 +138,7 @@ void mad_check (char *file, int line)
|
||||
if (*(mem_areas [i].end_sig) != MAD_SIGNATURE)
|
||||
mad_abort ("Overwrite error: Bad end signature", i, file, line);
|
||||
}
|
||||
Stats.check_call_cnt++;
|
||||
fflush (memlog);
|
||||
}
|
||||
|
||||
@ -121,30 +150,22 @@ void *mad_alloc (int size, char *file, int line)
|
||||
|
||||
mad_check (file, line);
|
||||
|
||||
for (i = 0; i < MAD_MAX_AREAS; i++){
|
||||
if (! mem_areas [i].in_use)
|
||||
break;
|
||||
}
|
||||
if (i >= MAD_MAX_AREAS){
|
||||
fprintf (memlog, "MAD: Out of memory area handles. Increase the value of MAD_MAX_AREAS.\r\n");
|
||||
fprintf (memlog, " Discovered in file \"%s\" at line %d.\r\n",
|
||||
file, line);
|
||||
fprintf (memlog, "MAD: Aborting...\r\n");
|
||||
fflush (memlog);
|
||||
abort ();
|
||||
for (i = Alloc_idx_hint; i < MAD_MAX_AREAS; i++) {
|
||||
if (! mem_areas [i].in_use)
|
||||
break;
|
||||
}
|
||||
if (i >= MAD_MAX_AREAS)
|
||||
mad_fatal_error("Out of memory area handles. Increase the value of MAD_MAX_AREAS.", NULL, file, line);
|
||||
|
||||
Alloc_idx_hint = i+1;
|
||||
if (i > Stats.last_max_i)
|
||||
Stats.last_max_i = i;
|
||||
|
||||
mem_areas [i].in_use = 1;
|
||||
size = (size + 3) & (~3); /* Alignment */
|
||||
area = (char*) g_malloc (size + 2 * sizeof (long));
|
||||
if (!area){
|
||||
fprintf (memlog, "MAD: Out of memory.\r\n");
|
||||
fprintf (memlog, " Discovered in file \"%s\" at line %d.\r\n",
|
||||
file, line);
|
||||
fprintf (memlog, "MAD: Aborting...\r\n");
|
||||
fflush (memlog);
|
||||
abort ();
|
||||
}
|
||||
if (!area)
|
||||
mad_fatal_error("Out of memory.", NULL, file, line);
|
||||
|
||||
mem_areas [i].start_sig = (long*) area;
|
||||
mem_areas [i].data = (area + sizeof (long));
|
||||
@ -177,26 +198,15 @@ void *mad_realloc (void *ptr, int newsize, char *file, int line)
|
||||
if (mem_areas [i].data == ptr)
|
||||
break;
|
||||
}
|
||||
if (i >= MAD_MAX_AREAS){
|
||||
fprintf (memlog, "MAD: Attempted to realloc unallocated pointer: %p.\r\n", ptr);
|
||||
fprintf (memlog, " Discovered in file \"%s\" at line %d.\r\n",
|
||||
file, line);
|
||||
fprintf (memlog, "MAD: Aborting...\r\n");
|
||||
fflush (memlog);
|
||||
abort ();
|
||||
}
|
||||
if (i >= MAD_MAX_AREAS)
|
||||
mad_fatal_error("Attempted to realloc unallocated pointer", ptr, file, line);
|
||||
|
||||
newsize = (newsize + 3) & (~3); /* Alignment */
|
||||
area = (char*) g_realloc (mem_areas [i].start_sig, newsize + 2 * sizeof (long));
|
||||
if (!area){
|
||||
fprintf (memlog, "MAD: Out of memory.\r\n");
|
||||
fprintf (memlog, " Discovered in file \"%s\" at line %d.\r\n",
|
||||
file, line);
|
||||
fprintf (memlog, "MAD: Aborting...\r\n");
|
||||
fflush (memlog);
|
||||
abort ();
|
||||
}
|
||||
if (!area)
|
||||
mad_fatal_error("Out of memory", NULL, file, line);
|
||||
|
||||
/* Reuses a position in mem_areas[] and thus does not set .in_use */
|
||||
mem_areas [i].start_sig = (long*) area;
|
||||
mem_areas [i].data = (area + sizeof (long));
|
||||
mem_areas [i].end_sig = (long*) (area + newsize + sizeof (long));
|
||||
@ -215,7 +225,7 @@ void *mad_realloc (void *ptr, int newsize, char *file, int line)
|
||||
void *mad_alloc0 (int size, char *file, int line)
|
||||
{
|
||||
char *t;
|
||||
|
||||
|
||||
t = (char *) mad_alloc (size, file, line);
|
||||
memset (t, 0, size);
|
||||
return (void *) t;
|
||||
@ -231,11 +241,25 @@ char *mad_strdup (const char *s, char *file, int line)
|
||||
return t;
|
||||
}
|
||||
|
||||
/* Duplicates a character string. Used instead of strndup. */
|
||||
/* Dup of GLib's gstrfuncs.c:g_strndup() */
|
||||
char *mad_strndup (const char *s, int n, char *file, int line)
|
||||
{
|
||||
if(s) {
|
||||
char *new_str = mad_alloc(n + 1, file, line);
|
||||
strncpy(new_str, s, n);
|
||||
new_str[n] = '\0';
|
||||
return new_str;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Frees a memory area. Used instead of free. */
|
||||
void mad_free (void *ptr, char *file, int line)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
mad_check (file, line);
|
||||
|
||||
if (watch_free_pointer && ptr == watch_free_pointer){
|
||||
@ -243,7 +267,7 @@ void mad_free (void *ptr, char *file, int line)
|
||||
file, line);
|
||||
fflush (memlog);
|
||||
}
|
||||
|
||||
|
||||
if (ptr == NULL){
|
||||
fprintf (memlog, "MAD: Attempted to free a NULL pointer in file \"%s\" at line %d.\r\n",
|
||||
file, line);
|
||||
@ -251,23 +275,28 @@ void mad_free (void *ptr, char *file, int line)
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < MAD_MAX_AREAS; i++){
|
||||
if (! mem_areas [i].in_use)
|
||||
continue;
|
||||
if (mem_areas [i].data == ptr)
|
||||
break;
|
||||
}
|
||||
if (i >= MAD_MAX_AREAS){
|
||||
fprintf (memlog, "MAD: Attempted to free an unallocated pointer: %p.\r\n", ptr);
|
||||
fprintf (memlog, " Discovered in file \"%s\" at line %d.\r\n",
|
||||
file, line);
|
||||
fprintf (memlog, "MAD: Aborting...\r\n");
|
||||
fflush (memlog);
|
||||
abort ();
|
||||
}
|
||||
|
||||
/* Do a quick search in the neighborhood of Alloc_idx_hint. */
|
||||
for ( i = MAX(Alloc_idx_hint-100, 0); i <= Alloc_idx_hint; i++ )
|
||||
if ( mem_areas [i].data == ptr )
|
||||
goto found_it;
|
||||
|
||||
for ( i = MIN(Alloc_idx_hint+100, MAD_MAX_AREAS-1); i > Alloc_idx_hint; i-- )
|
||||
if ( mem_areas [i].data == ptr )
|
||||
goto found_it;
|
||||
|
||||
for (i = 0; i < MAD_MAX_AREAS; i++)
|
||||
if ( mem_areas [i].data == ptr )
|
||||
goto found_it;
|
||||
|
||||
mad_fatal_error("Attempted to free an unallocated pointer", ptr, file, line);
|
||||
|
||||
found_it:
|
||||
g_free (mem_areas [i].start_sig);
|
||||
mem_areas [i].in_use = 0;
|
||||
|
||||
mem_areas[i].data = NULL; /* Kill the pointer - no need to check .in_use above.*/
|
||||
if ( i < Alloc_idx_hint )
|
||||
Alloc_idx_hint = i;
|
||||
}
|
||||
|
||||
char *mad_tempnam (char *a, char *b)
|
||||
@ -275,8 +304,8 @@ char *mad_tempnam (char *a, char *b)
|
||||
char *t, *u;
|
||||
t = tempnam(a,b); /* This malloc's internal buffer.. */
|
||||
u = mad_strdup(t, "(mad_tempnam)", 0);
|
||||
free(t);
|
||||
return u;
|
||||
free(t);
|
||||
return u;
|
||||
}
|
||||
|
||||
/* Outputs a list of unfreed memory areas,
|
||||
@ -284,7 +313,8 @@ char *mad_tempnam (char *a, char *b)
|
||||
void mad_finalize (char *file, int line)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
Mad_check_call_delay = 0;
|
||||
mad_check (file, line);
|
||||
|
||||
/* Following can be commented out if you don't want to see the
|
||||
@ -300,6 +330,10 @@ void mad_finalize (char *file, int line)
|
||||
file, line);
|
||||
fflush (memlog);
|
||||
}
|
||||
fprintf(memlog,
|
||||
"MAD: Stats -\n last_max_i:%d\n check_call_cnt:%ld\n",
|
||||
Stats.last_max_i, Stats.check_call_cnt
|
||||
);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -312,15 +346,15 @@ mad_strconcat (const char *first, ...)
|
||||
|
||||
if (!first)
|
||||
return 0;
|
||||
|
||||
|
||||
len = strlen (first) + 1;
|
||||
va_start (ap, first);
|
||||
|
||||
while ((data = va_arg (ap, char *)) != 0)
|
||||
len += strlen (data);
|
||||
|
||||
result = g_malloc (len);
|
||||
|
||||
result = mad_alloc(len, "(mad_strconcat)", 0);
|
||||
|
||||
va_end (ap);
|
||||
|
||||
va_start (ap, first);
|
||||
@ -334,7 +368,8 @@ mad_strconcat (const char *first, ...)
|
||||
return result;
|
||||
}
|
||||
|
||||
/* This two functions grabbed from GLib's gstrfuncs.c */
|
||||
|
||||
/* These two functions grabbed from GLib's gstrfuncs.c */
|
||||
char*
|
||||
mad_strdup_vprintf (const char *format, va_list args1)
|
||||
{
|
||||
@ -343,7 +378,7 @@ mad_strdup_vprintf (const char *format, va_list args1)
|
||||
|
||||
G_VA_COPY (args2, args1);
|
||||
|
||||
buffer = g_new (char, g_printf_string_upper_bound (format, args1));
|
||||
buffer = mad_alloc(g_printf_string_upper_bound(format, args1), "(mad_strdup_vprintf)", 0);
|
||||
|
||||
vsprintf (buffer, format, args2);
|
||||
va_end (args2);
|
||||
@ -358,7 +393,7 @@ mad_strdup_printf (const char *format, ...)
|
||||
va_list args;
|
||||
|
||||
va_start (args, format);
|
||||
buffer = g_strdup_vprintf (format, args);
|
||||
buffer = mad_strdup_vprintf(format, args);
|
||||
va_end (args);
|
||||
|
||||
return buffer;
|
||||
|
16
src/mad.h
16
src/mad.h
@ -3,10 +3,10 @@
|
||||
|
||||
/* To prevent molesting these files with the malloc/calloc/free macros. */
|
||||
#include <stdlib.h>
|
||||
#include <malloc.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#ifdef HAVE_MAD
|
||||
# define INLINE
|
||||
# define INLINE
|
||||
#else
|
||||
# ifndef INLINE
|
||||
# define INLINE inline
|
||||
@ -33,11 +33,17 @@
|
||||
#define calloc(x, y) mad_alloc ((x) * (y), __FILE__, __LINE__)
|
||||
#define realloc(x, y) mad_realloc (x, y, __FILE__, __LINE__)
|
||||
#define xmalloc(x, y) mad_alloc (x, __FILE__, __LINE__)
|
||||
#undef strdup
|
||||
#ifdef strdup
|
||||
# undef strdup
|
||||
#endif
|
||||
#define strdup(x) mad_strdup (x, __FILE__, __LINE__)
|
||||
#ifdef strndup
|
||||
# undef strndup
|
||||
#endif
|
||||
#define strndup(x, n) mad_strndup (x, n, __FILE__, __LINE__)
|
||||
#define free(x) mad_free (x, __FILE__, __LINE__)
|
||||
|
||||
/* This defenitions are grabbed from GLib.h */
|
||||
/* These definitions are grabbed from GLib.h */
|
||||
#define g_new(type, count) \
|
||||
((type *) g_malloc ((unsigned) sizeof (type) * (count)))
|
||||
#define g_new0(type, count) \
|
||||
@ -50,6 +56,7 @@
|
||||
#define g_calloc(x, y) mad_alloc ((x) * (y), __FILE__, __LINE__)
|
||||
#define g_realloc(x, y) mad_realloc (x, y, __FILE__, __LINE__)
|
||||
#define g_strdup(x) mad_strdup (x, __FILE__, __LINE__)
|
||||
#define g_strndup(x, n) mad_strndup (x, n, __FILE__, __LINE__)
|
||||
#define g_free(x) mad_free (x, __FILE__, __LINE__)
|
||||
#define g_strconcat mad_strconcat
|
||||
#define g_strdup_printf mad_strdup_printf
|
||||
@ -62,6 +69,7 @@ void *mad_alloc (int size, char *file, int line);
|
||||
void *mad_alloc0 (int size, char *file, int line);
|
||||
void *mad_realloc (void *ptr, int newsize, char *file, int line);
|
||||
char *mad_strdup (const char *s, char *file, int line);
|
||||
char *mad_strndup (const char *s, int n, char *file, int line);
|
||||
void mad_free (void *ptr, char *file, int line);
|
||||
void mad_finalize (char *file, int line);
|
||||
char *mad_tempnam (char *s1, char *s2);
|
||||
|
@ -1285,9 +1285,9 @@ forward_char (WInput *in)
|
||||
static void
|
||||
forward_word (WInput *in)
|
||||
{
|
||||
char *p = in->buffer+in->point;
|
||||
unsigned char *p = in->buffer+in->point;
|
||||
|
||||
while ((*p && isspace (*p)) || ispunct (*p))
|
||||
while (*p && (isspace (*p) || ispunct (*p)))
|
||||
p++;
|
||||
while (*p && isalnum (*p))
|
||||
p++;
|
||||
@ -1297,7 +1297,7 @@ forward_word (WInput *in)
|
||||
static void
|
||||
backward_word (WInput *in)
|
||||
{
|
||||
char *p = in->buffer+in->point;
|
||||
unsigned char *p = in->buffer+in->point;
|
||||
|
||||
while (p-1 > in->buffer-1 && (isspace (*(p-1)) || ispunct (*(p-1))))
|
||||
p--;
|
||||
|
@ -79,7 +79,7 @@ typedef struct {
|
||||
int first; /* Is first keystroke? */
|
||||
int disable_update; /* Do we want to skip updates? */
|
||||
int is_password; /* Is this a password input line? */
|
||||
char *buffer; /* pointer to editing buffer */
|
||||
unsigned char *buffer; /* pointer to editing buffer */
|
||||
Hist *history; /* The history */
|
||||
int need_push; /* need to push the current Input on hist? */
|
||||
char **completions; /* Possible completions array */
|
||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user