blob: 7d1b67e5136bcd34ab6b624275f2196e7ae1f10a [file] [log] [blame]
/*
* Utility routines
*
* Copyright 1998 Bertho A. Stultiens
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <assert.h>
#include <ctype.h>
#include <config.h>
#include "wrc.h"
#include "utils.h"
#include "parser.h"
#define WANT_NEAR_INDICATION
#ifdef WANT_NEAR_INDICATION
void make_print(char *str)
{
while(*str)
{
if(!isprint(*str))
*str = ' ';
str++;
}
}
#endif
int yyerror(const char *s, ...)
{
va_list ap;
va_start(ap, s);
fprintf(stderr, "Error %s: %d, %d: ", input_name ? input_name : "stdin", line_number, char_number);
vfprintf(stderr, s, ap);
#ifdef WANT_NEAR_INDICATION
{
char *cpy = xstrdup(yytext);
make_print(cpy);
fprintf(stderr, " near '%s'\n", cpy);
free(cpy);
}
#else
fprintf(stderr, "\n");
#endif
va_end(ap);
exit(1);
return 1;
}
int yywarning(const char *s, ...)
{
va_list ap;
va_start(ap, s);
fprintf(stderr, "Warning %s: %d, %d: ", input_name ? input_name : "stdin", line_number, char_number);
vfprintf(stderr, s, ap);
#ifdef WANT_NEAR_INDICATION
{
char *cpy = xstrdup(yytext);
make_print(cpy);
fprintf(stderr, " near '%s'\n", cpy);
free(cpy);
}
#else
fprintf(stderr, "\n");
#endif
va_end(ap);
return 0;
}
void internal_error(const char *file, int line, const char *s, ...)
{
va_list ap;
va_start(ap, s);
fprintf(stderr, "Internal error (please report) %s %d: ", file, line);
vfprintf(stderr, s, ap);
fprintf(stderr, "\n");
va_end(ap);
exit(3);
}
void error(const char *s, ...)
{
va_list ap;
va_start(ap, s);
fprintf(stderr, "Error: ");
vfprintf(stderr, s, ap);
fprintf(stderr, "\n");
va_end(ap);
exit(2);
}
void warning(const char *s, ...)
{
va_list ap;
va_start(ap, s);
fprintf(stderr, "Warning: ");
vfprintf(stderr, s, ap);
fprintf(stderr, "\n");
va_end(ap);
}
void chat(const char *s, ...)
{
if(debuglevel & DEBUGLEVEL_CHAT)
{
va_list ap;
va_start(ap, s);
fprintf(stderr, "FYI: ");
vfprintf(stderr, s, ap);
fprintf(stderr, "\n");
va_end(ap);
}
}
char *dup_basename(const char *name, const char *ext)
{
int namelen;
int extlen = strlen(ext);
char *base;
char *slash;
if(!name)
name = "wrc.tab";
slash = strrchr(name, '/');
if (slash)
name = slash + 1;
namelen = strlen(name);
/* +4 for later extension and +1 for '\0' */
base = (char *)xmalloc(namelen +4 +1);
strcpy(base, name);
if(!stricmp(name + namelen-extlen, ext))
{
base[namelen - extlen] = '\0';
}
return base;
}
void *xmalloc(size_t size)
{
void *res;
assert(size > 0);
assert(size < 102400);
res = malloc(size);
if(res == NULL)
{
error("Virtual memory exhausted.\n");
}
memset(res, 0, size);
return res;
}
void *xrealloc(void *p, size_t size)
{
void *res;
assert(size > 0);
assert(size < 102400);
res = realloc(p, size);
if(res == NULL)
{
error("Virtual memory exhausted.\n");
}
return res;
}
char *xstrdup(const char *str)
{
char *s = (char *)xmalloc(strlen(str)+1);
return strcpy(s, str);
}
int string_compare(const string_t *s1, const string_t *s2)
{
if(s1->type == str_char && s2->type == str_char)
{
return stricmp(s1->str.cstr, s2->str.cstr);
}
else
{
internal_error(__FILE__, __LINE__, "Cannot yet compare unicode strings");
}
return 0;
}
int wstrlen(const short *s)
{
int cnt = 0;
while(*s++)
cnt++;
return cnt;
}
short *wstrcpy(short *dst, const short *src)
{
short *d = dst;
while(*src)
*d++ = *src++;
return dst;
}
int wstricmp(const short *s1, const short *s2)
{
char *cs1 = dupwstr2cstr(s1);
char *cs2 = dupwstr2cstr(s2);
int retval = stricmp(cs1, cs2);
free(cs1);
free(cs2);
warning("Comparing unicode strings without case -> converting to ascii");
return retval;;
}
short *dupcstr2wstr(const char *str)
{
int len = strlen(str) + 1;
short *ws = (short *)xmalloc(len*2);
short *wptr;
wptr = ws;
/* FIXME: codepage translation */
while(*str)
*wptr++ = (short)(*str++ & 0xff);
*wptr = 0;
return ws;
}
char *dupwstr2cstr(const short *str)
{
int len = wstrlen(str) + 1;
char *cs = (char *)xmalloc(len);
char *cptr;
cptr = cs;
/* FIXME: codepage translation */
while(*str)
*cptr++ = (char)*str++;
*cptr = 0;
return cs;
}
#ifndef HAVE_STRICMP
int stricmp(const char *s1, const char *s2)
{
while(*s1 && *s2 && !(toupper(*s1) - toupper(*s2)))
{
s1++;
s2++;
}
return *s2 - *s1;
}
#endif