0
0
mirror of https://github.com/netwide-assembler/nasm.git synced 2025-09-22 10:43:39 -04:00

Eliminate filename length restrictions, remote ofmt->filename()

Get rid of remaining dependencies on FILENAME_MAX, which ought to have
been removed a long time ago.

Remove ofmt->filename(); all implementations pretty much do the same
thing and there is absolutely no reason to duplicate that
functionality all over the place.

Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
This commit is contained in:
H. Peter Anvin
2017-12-20 13:33:49 -08:00
parent dcbaf677d4
commit 81b62b9f54
23 changed files with 170 additions and 236 deletions

View File

@@ -93,7 +93,8 @@ NASM = asm/nasm.$(O)
NDISASM = disasm/ndisasm.$(O) NDISASM = disasm/ndisasm.$(O)
LIBOBJ = stdlib/snprintf.$(O) stdlib/vsnprintf.$(O) stdlib/strlcpy.$(O) \ LIBOBJ = stdlib/snprintf.$(O) stdlib/vsnprintf.$(O) stdlib/strlcpy.$(O) \
stdlib/strnlen.$(O) \ stdlib/strnlen.$(O) stdlib/strrchrnul.$(O) \
\
nasmlib/ver.$(O) \ nasmlib/ver.$(O) \
nasmlib/crc64.$(O) nasmlib/malloc.$(O) \ nasmlib/crc64.$(O) nasmlib/malloc.$(O) \
nasmlib/md5c.$(O) nasmlib/string.$(O) \ nasmlib/md5c.$(O) nasmlib/string.$(O) \
@@ -105,7 +106,9 @@ LIBOBJ = stdlib/snprintf.$(O) stdlib/vsnprintf.$(O) stdlib/strlcpy.$(O) \
nasmlib/raa.$(O) nasmlib/saa.$(O) \ nasmlib/raa.$(O) nasmlib/saa.$(O) \
nasmlib/strlist.$(O) \ nasmlib/strlist.$(O) \
nasmlib/perfhash.$(O) nasmlib/badenum.$(O) \ nasmlib/perfhash.$(O) nasmlib/badenum.$(O) \
\
common/common.$(O) \ common/common.$(O) \
\
x86/insnsa.$(O) x86/insnsb.$(O) x86/insnsd.$(O) x86/insnsn.$(O) \ x86/insnsa.$(O) x86/insnsb.$(O) x86/insnsd.$(O) x86/insnsn.$(O) \
x86/regs.$(O) x86/regvals.$(O) x86/regflags.$(O) x86/regdis.$(O) \ x86/regs.$(O) x86/regvals.$(O) x86/regflags.$(O) x86/regdis.$(O) \
x86/disp8.$(O) x86/iflag.$(O) \ x86/disp8.$(O) x86/iflag.$(O) \

View File

@@ -69,7 +69,8 @@ NASM = asm\nasm.$(O)
NDISASM = disasm\ndisasm.$(O) NDISASM = disasm\ndisasm.$(O)
LIBOBJ = stdlib\snprintf.$(O) stdlib\vsnprintf.$(O) stdlib\strlcpy.$(O) \ LIBOBJ = stdlib\snprintf.$(O) stdlib\vsnprintf.$(O) stdlib\strlcpy.$(O) \
stdlib\strnlen.$(O) \ stdlib\strnlen.$(O) stdlib\strrchrnul.$(O) \
\
nasmlib\ver.$(O) \ nasmlib\ver.$(O) \
nasmlib\crc64.$(O) nasmlib\malloc.$(O) \ nasmlib\crc64.$(O) nasmlib\malloc.$(O) \
nasmlib\md5c.$(O) nasmlib\string.$(O) \ nasmlib\md5c.$(O) nasmlib\string.$(O) \
@@ -81,7 +82,9 @@ LIBOBJ = stdlib\snprintf.$(O) stdlib\vsnprintf.$(O) stdlib\strlcpy.$(O) \
nasmlib\raa.$(O) nasmlib\saa.$(O) \ nasmlib\raa.$(O) nasmlib\saa.$(O) \
nasmlib\strlist.$(O) \ nasmlib\strlist.$(O) \
nasmlib\perfhash.$(O) nasmlib\badenum.$(O) \ nasmlib\perfhash.$(O) nasmlib\badenum.$(O) \
\
common\common.$(O) \ common\common.$(O) \
\
x86\insnsa.$(O) x86\insnsb.$(O) x86\insnsd.$(O) x86\insnsn.$(O) \ x86\insnsa.$(O) x86\insnsb.$(O) x86\insnsd.$(O) x86\insnsn.$(O) \
x86\regs.$(O) x86\regvals.$(O) x86\regflags.$(O) x86\regdis.$(O) \ x86\regs.$(O) x86\regvals.$(O) x86\regflags.$(O) x86\regdis.$(O) \
x86\disp8.$(O) x86\iflag.$(O) \ x86\disp8.$(O) x86\iflag.$(O) \

View File

@@ -54,7 +54,8 @@ NASM = asm/nasm.$(O)
NDISASM = disasm/ndisasm.$(O) NDISASM = disasm/ndisasm.$(O)
LIBOBJ = stdlib/snprintf.$(O) stdlib/vsnprintf.$(O) stdlib/strlcpy.$(O) & LIBOBJ = stdlib/snprintf.$(O) stdlib/vsnprintf.$(O) stdlib/strlcpy.$(O) &
stdlib/strnlen.$(O) & stdlib/strnlen.$(O) stdlib/strrchrnul.$(O) &
&
nasmlib/ver.$(O) & nasmlib/ver.$(O) &
nasmlib/crc64.$(O) nasmlib/malloc.$(O) & nasmlib/crc64.$(O) nasmlib/malloc.$(O) &
nasmlib/md5c.$(O) nasmlib/string.$(O) & nasmlib/md5c.$(O) nasmlib/string.$(O) &
@@ -66,7 +67,9 @@ LIBOBJ = stdlib/snprintf.$(O) stdlib/vsnprintf.$(O) stdlib/strlcpy.$(O) &
nasmlib/raa.$(O) nasmlib/saa.$(O) & nasmlib/raa.$(O) nasmlib/saa.$(O) &
nasmlib/strlist.$(O) & nasmlib/strlist.$(O) &
nasmlib/perfhash.$(O) nasmlib/badenum.$(O) & nasmlib/perfhash.$(O) nasmlib/badenum.$(O) &
&
common/common.$(O) & common/common.$(O) &
&
x86/insnsa.$(O) x86/insnsb.$(O) x86/insnsd.$(O) x86/insnsn.$(O) & x86/insnsa.$(O) x86/insnsb.$(O) x86/insnsd.$(O) x86/insnsn.$(O) &
x86/regs.$(O) x86/regvals.$(O) x86/regflags.$(O) x86/regdis.$(O) & x86/regs.$(O) x86/regvals.$(O) x86/regflags.$(O) x86/regdis.$(O) &
x86/disp8.$(O) x86/iflag.$(O) & x86/disp8.$(O) x86/iflag.$(O) &

View File

@@ -75,7 +75,7 @@ struct forwrefinfo { /* info held on forward refs. */
}; };
static void parse_cmdline(int, char **, int); static void parse_cmdline(int, char **, int);
static void assemble_file(char *, StrList **); static void assemble_file(const char *, StrList **);
static bool is_suppressed_warning(int severity); static bool is_suppressed_warning(int severity);
static bool skip_this_pass(int severity); static bool skip_this_pass(int severity);
static void nasm_verror_gnu(int severity, const char *fmt, va_list args); static void nasm_verror_gnu(int severity, const char *fmt, va_list args);
@@ -94,10 +94,11 @@ int globalbnd = 0;
struct compile_time official_compile_time; struct compile_time official_compile_time;
static char inname[FILENAME_MAX]; const char *inname;
static char outname[FILENAME_MAX]; const char *outname;
static char listname[FILENAME_MAX]; static const char *listname;
static char errname[FILENAME_MAX]; static const char *errname;
static int globallineno; /* for forward-reference tracking */ static int globallineno; /* for forward-reference tracking */
/* static int pass = 0; */ /* static int pass = 0; */
const struct ofmt *ofmt = &OF_DEFAULT; const struct ofmt *ofmt = &OF_DEFAULT;
@@ -383,6 +384,10 @@ int main(int argc, char **argv)
if (ofmt->stdmac) if (ofmt->stdmac)
preproc->extra_stdmac(ofmt->stdmac); preproc->extra_stdmac(ofmt->stdmac);
/* no output file name? */
if (!outname)
outname = filename_set_extension(inname, ofmt->extension);
/* define some macros dependent of command-line */ /* define some macros dependent of command-line */
define_macros_late(); define_macros_late();
@@ -398,8 +403,6 @@ int main(int argc, char **argv)
preproc->include_path(NULL); /* "assume generated" */ preproc->include_path(NULL); /* "assume generated" */
preproc->reset(inname, 0, depend_ptr); preproc->reset(inname, 0, depend_ptr);
if (outname[0] == '\0')
ofmt->filename(inname, outname);
ofile = NULL; ofile = NULL;
while ((line = preproc->getline())) while ((line = preproc->getline()))
nasm_free(line); nasm_free(line);
@@ -410,7 +413,7 @@ int main(int argc, char **argv)
int32_t prior_linnum = 0; int32_t prior_linnum = 0;
int lineinc = 0; int lineinc = 0;
if (*outname) { if (outname) {
ofile = nasm_open_write(outname, NF_TEXT); ofile = nasm_open_write(outname, NF_TEXT);
if (!ofile) if (!ofile)
nasm_fatal(ERR_NOFILE, nasm_fatal(ERR_NOFILE,
@@ -456,15 +459,6 @@ int main(int argc, char **argv)
} }
if (operating_mode & OP_NORMAL) { if (operating_mode & OP_NORMAL) {
/*
* We must call ofmt->filename _anyway_, even if the user
* has specified their own output file, because some
* formats (eg OBJ and COFF) use ofmt->filename to find out
* the name of the input file and then put that inside the
* file.
*/
ofmt->filename(inname, outname);
ofile = nasm_open_write(outname, (ofmt->flags & OFMT_TEXT) ? NF_TEXT : NF_BINARY); ofile = nasm_open_write(outname, (ofmt->flags & OFMT_TEXT) ? NF_TEXT : NF_BINARY);
if (!ofile) if (!ofile)
nasm_fatal(ERR_NOFILE, nasm_fatal(ERR_NOFILE,
@@ -537,15 +531,12 @@ static char *get_param(char *p, char *q, bool *advance)
/* /*
* Copy a filename * Copy a filename
*/ */
static void copy_filename(char *dst, const char *src) static void copy_filename(const char **dst, const char *src, const char *what)
{ {
size_t len = strlen(src); if (*dst)
nasm_fatal(0, "more than one %s file specified: %s\n", what, src);
if (len >= (size_t)FILENAME_MAX) { *dst = nasm_strdup(src);
nasm_fatal(ERR_NOFILE, "file name too long");
return;
}
strncpy(dst, src, FILENAME_MAX);
} }
/* /*
@@ -746,7 +737,7 @@ static bool process_arg(char *p, char *q, int pass)
case 'o': /* output file */ case 'o': /* output file */
if (pass == 2) if (pass == 2)
copy_filename(outname, param); copy_filename(&outname, param, "output");
break; break;
case 'f': /* output format */ case 'f': /* output format */
@@ -832,12 +823,12 @@ static bool process_arg(char *p, char *q, int pass)
case 'l': /* listing file */ case 'l': /* listing file */
if (pass == 2) if (pass == 2)
copy_filename(listname, param); copy_filename(&listname, param, "listing");
break; break;
case 'Z': /* error messages file */ case 'Z': /* error messages file */
if (pass == 1) if (pass == 1)
copy_filename(errname, param); copy_filename(&errname, param, "error");
break; break;
case 'F': /* specify debug format */ case 'F': /* specify debug format */
@@ -1096,12 +1087,8 @@ static bool process_arg(char *p, char *q, int pass)
break; break;
} }
} else if (pass == 2) { } else if (pass == 2) {
if (*inname) { /* In theory we could allow multiple input files... */
nasm_error(ERR_NONFATAL | ERR_NOFILE | ERR_USAGE, copy_filename(&inname, p, "input");
"more than one input file specified");
} else {
copy_filename(inname, p);
}
} }
return advance; return advance;
@@ -1215,8 +1202,6 @@ static void parse_cmdline(int argc, char **argv, int pass)
char *envreal, *envcopy = NULL, *p; char *envreal, *envcopy = NULL, *p;
int i; int i;
*inname = *outname = *listname = *errname = '\0';
/* Initialize all the warnings to their default state */ /* Initialize all the warnings to their default state */
for (i = 0; i < ERR_WARN_ALL; i++) { for (i = 0; i < ERR_WARN_ALL; i++) {
warning_state_init[i] = warning_state[i] = warning_state_init[i] = warning_state[i] =
@@ -1274,18 +1259,16 @@ static void parse_cmdline(int argc, char **argv, int pass)
if (pass != 2) if (pass != 2)
return; return;
if (!*inname) if (!inname)
nasm_error(ERR_NONFATAL | ERR_NOFILE | ERR_USAGE, nasm_fatal(ERR_NOFILE | ERR_USAGE, "no input file specified");
"no input file specified");
else if (!strcmp(inname, errname) ||
!strcmp(inname, outname) ||
!strcmp(inname, listname) ||
(depend_file && !strcmp(inname, depend_file)))
nasm_fatal(ERR_NOFILE | ERR_USAGE,
"file `%s' is both input and output file",
inname);
if (*errname) { else if ((errname && !strcmp(inname, errname)) ||
(outname && !strcmp(inname, outname)) ||
(listname && !strcmp(inname, listname)) ||
(depend_file && !strcmp(inname, depend_file)))
nasm_fatal(ERR_USAGE, "will not overwrite input file");
if (errname) {
error_file = nasm_open_write(errname, NF_TEXT); error_file = nasm_open_write(errname, NF_TEXT);
if (!error_file) { if (!error_file) {
error_file = stderr; /* Revert to default! */ error_file = stderr; /* Revert to default! */
@@ -1296,7 +1279,7 @@ static void parse_cmdline(int argc, char **argv, int pass)
} }
} }
static void assemble_file(char *fname, StrList **depend_ptr) static void assemble_file(const char *fname, StrList **depend_ptr)
{ {
char *line; char *line;
insn output_ins; insn output_ins;
@@ -1323,7 +1306,7 @@ static void assemble_file(char *fname, StrList **depend_ptr)
cpu = cmd_cpu; cpu = cmd_cpu;
if (pass0 == 2) { if (pass0 == 2) {
lfmt->init(listname); lfmt->init(listname);
} else if (passn == 1 && *listname) { } else if (passn == 1 && listname) {
/* Remove the list file in case we die before the output pass */ /* Remove the list file in case we die before the output pass */
remove(listname); remove(listname);
} }

View File

@@ -63,7 +63,7 @@ static void nop_init(void)
/* Nothing to do */ /* Nothing to do */
} }
static void nop_reset(char *file, int pass, StrList **deplist) static void nop_reset(const char *file, int pass, StrList **deplist)
{ {
src_set(0, file); src_set(0, file);
nop_lineinc = 1; nop_lineinc = 1;

View File

@@ -4970,7 +4970,7 @@ static void pp_verror(int severity, const char *fmt, va_list arg)
} }
static void static void
pp_reset(char *file, int apass, StrList **deplist) pp_reset(const char *file, int apass, StrList **deplist)
{ {
Token *t; Token *t;

View File

@@ -115,6 +115,7 @@ AC_CHECK_FUNCS(strcasecmp stricmp)
AC_CHECK_FUNCS(strncasecmp strnicmp) AC_CHECK_FUNCS(strncasecmp strnicmp)
AC_CHECK_FUNCS(strsep) AC_CHECK_FUNCS(strsep)
AC_CHECK_FUNCS(strnlen) AC_CHECK_FUNCS(strnlen)
AC_CHECK_FUNCS(strrchrnul)
AC_CHECK_FUNCS(getuid) AC_CHECK_FUNCS(getuid)
AC_CHECK_FUNCS(getgid) AC_CHECK_FUNCS(getgid)
@@ -146,10 +147,11 @@ PA_HAVE_FUNC(__builtin_clzll, (0ULL))
PA_HAVE_FUNC(_BitScanReverse, (0)) PA_HAVE_FUNC(_BitScanReverse, (0))
PA_HAVE_FUNC(_BitScanReverse64, (0)) PA_HAVE_FUNC(_BitScanReverse64, (0))
dnl Functions for which we have replacements available in lib/ dnl Functions for which we have replacements available in stdlib/
AC_CHECK_FUNCS([vsnprintf _vsnprintf]) AC_CHECK_FUNCS([vsnprintf _vsnprintf])
AC_CHECK_FUNCS([snprintf _snprintf]) AC_CHECK_FUNCS([snprintf _snprintf])
AC_CHECK_FUNCS([strlcpy]) AC_CHECK_FUNCS([strlcpy])
AC_CHECK_FUNCS([strrchrnul])
dnl These types are POSIX-specific, and Windows does it differently... dnl These types are POSIX-specific, and Windows does it differently...
AC_CHECK_TYPES([struct _stati64]) AC_CHECK_TYPES([struct _stati64])
@@ -167,6 +169,7 @@ AC_CHECK_DECLS(strnicmp)
AC_CHECK_DECLS(strsep) AC_CHECK_DECLS(strsep)
AC_CHECK_DECLS(strlcpy) AC_CHECK_DECLS(strlcpy)
AC_CHECK_DECLS(strnlen) AC_CHECK_DECLS(strnlen)
AC_CHECK_DECLS(strrchrnul)
dnl Check for missing types dnl Check for missing types
AC_TYPE_UINTPTR_T AC_TYPE_UINTPTR_T

View File

@@ -155,6 +155,10 @@ int vsnprintf(char *, size_t, const char *, va_list);
size_t strlcpy(char *, const char *, size_t); size_t strlcpy(char *, const char *, size_t);
#endif #endif
#if !defined(HAVE_STRCHRNUL) || !HAVE_DECL_STRCHRNUL
char *strrchrnul(const char *, int);
#endif
#ifndef __cplusplus /* C++ has false, true, bool as keywords */ #ifndef __cplusplus /* C++ has false, true, bool as keywords */
# ifdef HAVE_STDBOOL_H # ifdef HAVE_STDBOOL_H
# include <stdbool.h> # include <stdbool.h>

View File

@@ -64,10 +64,6 @@ extern struct compile_time official_compile_time;
#define NO_SEG -1L /* null segment value */ #define NO_SEG -1L /* null segment value */
#define SEG_ABS 0x40000000L /* mask for far-absolute segments */ #define SEG_ABS 0x40000000L /* mask for far-absolute segments */
#ifndef FILENAME_MAX
#define FILENAME_MAX 256
#endif
#ifndef PREFIX_MAX #ifndef PREFIX_MAX
#define PREFIX_MAX 10 #define PREFIX_MAX 10
#endif #endif
@@ -354,7 +350,7 @@ struct preproc_ops {
* of the pass, an error reporting function, an evaluator * of the pass, an error reporting function, an evaluator
* function, and a listing generator to talk to. * function, and a listing generator to talk to.
*/ */
void (*reset)(char *file, int pass, StrList **deplist); void (*reset)(const char *file, int pass, StrList **deplist);
/* /*
* Called to fetch a line of preprocessed source. The line * Called to fetch a line of preprocessed source. The line
@@ -782,6 +778,11 @@ struct ofmt {
*/ */
const char *shortname; const char *shortname;
/*
* Default output filename extension, or a null string
*/
const char *extension;
/* /*
* Output format flags. * Output format flags.
*/ */
@@ -928,25 +929,6 @@ struct ofmt {
enum directive_result enum directive_result
(*directive)(enum directive directive, char *value, int pass); (*directive)(enum directive directive, char *value, int pass);
/*
* This procedure is called before anything else - even before
* the "init" routine - and is passed the name of the input
* file from which this output file is being generated. It
* should return its preferred name for the output file in
* `outname', if outname[0] is not '\0', and do nothing to
* `outname' otherwise. Since it is called before the driver is
* properly initialized, it has to be passed its error handler
* separately.
*
* This procedure may also take its own copy of the input file
* name for use in writing the output file: it is _guaranteed_
* that it will be called before the "init" routine.
*
* The parameter `outname' points to an area of storage
* guaranteed to be at least FILENAME_MAX in size.
*/
void (*filename)(char *inname, char *outname);
/* /*
* This procedure is called after assembly finishes, to allow * This procedure is called after assembly finishes, to allow
* the output driver to clean itself up and free its memory. * the output driver to clean itself up and free its memory.
@@ -1244,4 +1226,7 @@ extern int globalbits; /* 16, 32 or 64-bit mode */
extern int globalrel; /* default to relative addressing? */ extern int globalrel; /* default to relative addressing? */
extern int globalbnd; /* default to using bnd prefix? */ extern int globalbnd; /* default to using bnd prefix? */
extern const char *inname; /* primary input filename */
extern const char *outname; /* output filename */
#endif #endif

View File

@@ -196,10 +196,9 @@ void pure_func seg_init(void);
int32_t pure_func seg_alloc(void); int32_t pure_func seg_alloc(void);
/* /*
* many output formats will be able to make use of this: a standard * Add/replace or remove an extension to the end of a filename
* function to add an extension to the name of the input file
*/ */
void standard_extension(char *inname, char *outname, char *extension); const char *filename_set_extension(const char *inname, const char *extension);
/* /*
* Utility macros... * Utility macros...

View File

@@ -1,6 +1,6 @@
/* ----------------------------------------------------------------------- * /* ----------------------------------------------------------------------- *
* *
* Copyright 1996-2016 The NASM Authors - All Rights Reserved * Copyright 1996-2017 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for * See the file AUTHORS included with the NASM distribution for
* the specific copyright holders. * the specific copyright holders.
* *
@@ -14,7 +14,7 @@
* copyright notice, this list of conditions and the following * copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided * disclaimer in the documentation and/or other materials provided
* with the distribution. * with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
@@ -39,31 +39,25 @@
#include "nasmlib.h" #include "nasmlib.h"
#include "error.h" #include "error.h"
void standard_extension(char *inname, char *outname, char *extension) /*
* Add/modify a filename extension, assumed to be a period-delimited
* field at the very end of the filename. Returns a newly allocated
* string buffer.
*/
const char *filename_set_extension(const char *inname, const char *extension)
{ {
char *p, *q; const char *q = inname;
char *p;
size_t elen = strlen(extension);
size_t baselen;
if (*outname) /* file name already exists, */ q = strrchrnul(inname, '.'); /* find extension or end of string */
return; /* so do nothing */ baselen = q - inname;
q = inname;
p = outname; p = nasm_malloc(baselen + elen + 1);
while (*q)
*p++ = *q++; /* copy, and find end of string */ memcpy(p, inname, baselen);
*p = '\0'; /* terminate it */ memcpy(p+baselen, extension, elen+1);
while (p > outname && *--p != '.') ; /* find final period (or whatever) */
if (*p != '.') return p;
while (*p)
p++; /* go back to end if none found */
if (!strcmp(p, extension)) { /* is the extension already there? */
if (*extension)
nasm_error(ERR_WARNING | ERR_NOFILE,
"file name already ends in `%s': "
"output will be in `nasm.out'", extension);
else
nasm_error(ERR_WARNING | ERR_NOFILE,
"file name already has no extension: "
"output will be in `nasm.out'");
strcpy(outname, "nasm.out");
} else
strcpy(p, extension);
} }

View File

@@ -314,7 +314,7 @@ static void cv8_cleanup(void)
struct coff_Section *symbol_sect = coff_sects[cv8_state.symbol_sect]; struct coff_Section *symbol_sect = coff_sects[cv8_state.symbol_sect];
struct coff_Section *type_sect = coff_sects[cv8_state.type_sect]; struct coff_Section *type_sect = coff_sects[cv8_state.type_sect];
cv8_state.outfile.name = nasm_realpath(coff_outfile); cv8_state.outfile.name = nasm_realpath(outname);
cv8_state.outfile.namebytes = strlen(cv8_state.outfile.name) + 1; cv8_state.outfile.namebytes = strlen(cv8_state.outfile.name) + 1;
build_symbol_table(symbol_sect); build_symbol_table(symbol_sect);

View File

@@ -894,11 +894,6 @@ static int32_t aout_segbase(int32_t segment)
return segment; return segment;
} }
static void aout_filename(char *inname, char *outname)
{
standard_extension(inname, outname, ".o");
}
extern macros_t aout_stdmac[]; extern macros_t aout_stdmac[];
#endif /* OF_AOUT || OF_AOUTB */ #endif /* OF_AOUT || OF_AOUTB */
@@ -908,6 +903,7 @@ extern macros_t aout_stdmac[];
const struct ofmt of_aout = { const struct ofmt of_aout = {
"Linux a.out object files", "Linux a.out object files",
"aout", "aout",
".o",
0, 0,
32, 32,
null_debug_arr, null_debug_arr,
@@ -921,7 +917,6 @@ const struct ofmt of_aout = {
null_sectalign, null_sectalign,
aout_segbase, aout_segbase,
null_directive, null_directive,
aout_filename,
aout_cleanup, aout_cleanup,
NULL /* pragma list */ NULL /* pragma list */
}; };
@@ -933,6 +928,7 @@ const struct ofmt of_aout = {
const struct ofmt of_aoutb = { const struct ofmt of_aoutb = {
"NetBSD/FreeBSD a.out object files", "NetBSD/FreeBSD a.out object files",
"aoutb", "aoutb",
".o",
0, 0,
32, 32,
null_debug_arr, null_debug_arr,
@@ -946,7 +942,6 @@ const struct ofmt of_aoutb = {
null_sectalign, null_sectalign,
aout_segbase, aout_segbase,
null_directive, null_directive,
aout_filename,
aout_cleanup, aout_cleanup,
NULL /* pragma list */ NULL /* pragma list */
}; };

View File

@@ -1,6 +1,6 @@
/* ----------------------------------------------------------------------- * /* ----------------------------------------------------------------------- *
* *
* Copyright 1996-2013 The NASM Authors - All Rights Reserved * Copyright 1996-2017 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for * See the file AUTHORS included with the NASM distribution for
* the specific copyright holders. * the specific copyright holders.
* *
@@ -91,8 +91,6 @@ struct Section {
struct Piece *head, *last, **tail; struct Piece *head, *last, **tail;
}; };
static char as86_module[FILENAME_MAX];
static struct Section stext, sdata; static struct Section stext, sdata;
static uint32_t bsslen; static uint32_t bsslen;
static int32_t bssindex; static int32_t bssindex;
@@ -103,13 +101,13 @@ static uint32_t nsyms;
static struct RAA *bsym; static struct RAA *bsym;
static struct SAA *strs; static struct SAA *strs;
static uint32_t strslen; static size_t strslen;
static int as86_reloc_size; static int as86_reloc_size;
static void as86_write(void); static void as86_write(void);
static void as86_write_section(struct Section *, int); static void as86_write_section(struct Section *, int);
static int as86_add_string(char *name); static size_t as86_add_string(const char *name);
static void as86_sect_write(struct Section *, const uint8_t *, static void as86_sect_write(struct Section *, const uint8_t *,
uint32_t); uint32_t);
@@ -135,7 +133,8 @@ static void as86_init(void)
strs = saa_init(1L); strs = saa_init(1L);
strslen = 0; strslen = 0;
as86_add_string(as86_module); /* as86 module name = input file minus extension */
as86_add_string(filename_set_extension(inname, ""));
} }
static void as86_cleanup(void) static void as86_cleanup(void)
@@ -183,12 +182,12 @@ static int32_t as86_section_names(char *name, int pass, int *bits)
return NO_SEG; return NO_SEG;
} }
static int as86_add_string(char *name) static size_t as86_add_string(const char *name)
{ {
int pos = strslen; size_t pos = strslen;
int length = strlen(name); size_t length = strlen(name);
saa_wbytes(strs, name, (int32_t)(length + 1)); saa_wbytes(strs, name, length + 1);
strslen += 1 + length; strslen += 1 + length;
return pos; return pos;
@@ -611,24 +610,12 @@ static int32_t as86_segbase(int32_t segment)
return segment; return segment;
} }
static void as86_filename(char *inname, char *outname)
{
char *p;
if ((p = strrchr(inname, '.')) != NULL) {
strncpy(as86_module, inname, p - inname);
as86_module[p - inname] = '\0';
} else
strcpy(as86_module, inname);
standard_extension(inname, outname, ".o");
}
extern macros_t as86_stdmac[]; extern macros_t as86_stdmac[];
const struct ofmt of_as86 = { const struct ofmt of_as86 = {
"Linux as86 (bin86 version 0.3) object files", "Linux as86 (bin86 version 0.3) object files",
"as86", "as86",
".o",
0, 0,
32, 32,
null_debug_arr, null_debug_arr,
@@ -642,7 +629,6 @@ const struct ofmt of_as86 = {
null_sectalign, null_sectalign,
as86_segbase, as86_segbase,
null_directive, null_directive,
as86_filename,
as86_cleanup, as86_cleanup,
NULL /* pragma list */ NULL /* pragma list */
}; };

View File

@@ -1,6 +1,6 @@
/* ----------------------------------------------------------------------- * /* ----------------------------------------------------------------------- *
* *
* Copyright 1996-2013 The NASM Authors - All Rights Reserved * Copyright 1996-2017 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for * See the file AUTHORS included with the NASM distribution for
* the specific copyright holders. * the specific copyright holders.
* *
@@ -161,7 +161,6 @@ static int origin_defined;
#define MAP_SECTIONS 4 #define MAP_SECTIONS 4
#define MAP_SYMBOLS 8 #define MAP_SYMBOLS 8
static int map_control = 0; static int map_control = 0;
static char *infile, *outfile;
extern macros_t bin_stdmac[]; extern macros_t bin_stdmac[];
@@ -580,7 +579,7 @@ static void bin_cleanup(void)
for (h = 63; h; h--) for (h = 63; h; h--)
fputc('-', rf); fputc('-', rf);
fprintf(rf, "\n\nSource file: %s\nOutput file: %s\n\n", fprintf(rf, "\n\nSource file: %s\nOutput file: %s\n\n",
infile, outfile); inname, outname);
if (map_control & MAP_ORIGIN) { /* Display program origin. */ if (map_control & MAP_ORIGIN) { /* Display program origin. */
fprintf(rf, "-- Program origin "); fprintf(rf, "-- Program origin ");
@@ -1371,27 +1370,6 @@ bin_directive(enum directive directive, char *args, int pass)
} }
} }
static void bin_filename(char *inname, char *outname)
{
standard_extension(inname, outname, "");
infile = inname;
outfile = outname;
}
static void ith_filename(char *inname, char *outname)
{
standard_extension(inname, outname, ".ith");
infile = inname;
outfile = outname;
}
static void srec_filename(char *inname, char *outname)
{
standard_extension(inname, outname, ".srec");
infile = inname;
outfile = outname;
}
static int32_t bin_segbase(int32_t segment) static int32_t bin_segbase(int32_t segment)
{ {
return segment; return segment;
@@ -1650,6 +1628,7 @@ static void do_output_srec(void)
const struct ofmt of_bin = { const struct ofmt of_bin = {
"flat-form binary files (e.g. DOS .COM, .SYS)", "flat-form binary files (e.g. DOS .COM, .SYS)",
"bin", "bin",
"",
0, 0,
64, 64,
null_debug_arr, null_debug_arr,
@@ -1663,7 +1642,6 @@ const struct ofmt of_bin = {
bin_sectalign, bin_sectalign,
bin_segbase, bin_segbase,
bin_directive, bin_directive,
bin_filename,
bin_cleanup, bin_cleanup,
NULL /* pragma list */ NULL /* pragma list */
}; };
@@ -1671,6 +1649,7 @@ const struct ofmt of_bin = {
const struct ofmt of_ith = { const struct ofmt of_ith = {
"Intel hex", "Intel hex",
"ith", "ith",
".ith", /* really should have been ".hex"... */
OFMT_TEXT, OFMT_TEXT,
64, 64,
null_debug_arr, null_debug_arr,
@@ -1684,7 +1663,6 @@ const struct ofmt of_ith = {
bin_sectalign, bin_sectalign,
bin_segbase, bin_segbase,
bin_directive, bin_directive,
ith_filename,
bin_cleanup, bin_cleanup,
NULL /* pragma list */ NULL /* pragma list */
}; };
@@ -1692,6 +1670,7 @@ const struct ofmt of_ith = {
const struct ofmt of_srec = { const struct ofmt of_srec = {
"Motorola S-records", "Motorola S-records",
"srec", "srec",
".srec",
OFMT_TEXT, OFMT_TEXT,
64, 64,
null_debug_arr, null_debug_arr,
@@ -1705,7 +1684,6 @@ const struct ofmt of_srec = {
bin_sectalign, bin_sectalign,
bin_segbase, bin_segbase,
bin_directive, bin_directive,
srec_filename,
bin_cleanup, bin_cleanup,
NULL /* pragma list */ NULL /* pragma list */
}; };

View File

@@ -1,6 +1,6 @@
/* ----------------------------------------------------------------------- * /* ----------------------------------------------------------------------- *
* *
* Copyright 1996-2014 The NASM Authors - All Rights Reserved * Copyright 1996-2017 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for * See the file AUTHORS included with the NASM distribution for
* the specific copyright holders. * the specific copyright holders.
* *
@@ -106,9 +106,6 @@ bool win32, win64;
static int32_t imagebase_sect; static int32_t imagebase_sect;
#define WRT_IMAGEBASE "..imagebase" #define WRT_IMAGEBASE "..imagebase"
char coff_infile[FILENAME_MAX];
char coff_outfile[FILENAME_MAX];
/* /*
* Some common section flags by default * Some common section flags by default
*/ */
@@ -1080,7 +1077,7 @@ static void coff_write_symbols(void)
* The `.file' record, and the file name auxiliary record. * The `.file' record, and the file name auxiliary record.
*/ */
coff_symbol(".file", 0L, 0L, -2, 0, 0x67, 1); coff_symbol(".file", 0L, 0L, -2, 0, 0x67, 1);
strncpy(filename, coff_infile, 18); strncpy(filename, inname, 18);
nasm_write(filename, 18, ofile); nasm_write(filename, 18, ofile);
/* /*
@@ -1143,20 +1140,6 @@ static int32_t coff_segbase(int32_t segment)
return segment; return segment;
} }
static void coff_std_filename(char *inname, char *outname)
{
strcpy(coff_infile, inname);
standard_extension(inname, outname, ".o");
strcpy(coff_outfile, outname);
}
static void coff_win32_filename(char *inname, char *outname)
{
strcpy(coff_infile, inname);
standard_extension(inname, outname, ".obj");
strcpy(coff_outfile, outname);
}
extern macros_t coff_stdmac[]; extern macros_t coff_stdmac[];
#endif /* defined(OF_COFF) || defined(OF_WIN32) */ #endif /* defined(OF_COFF) || defined(OF_WIN32) */
@@ -1166,6 +1149,7 @@ extern macros_t coff_stdmac[];
const struct ofmt of_coff = { const struct ofmt of_coff = {
"COFF (i386) object files (e.g. DJGPP for DOS)", "COFF (i386) object files (e.g. DJGPP for DOS)",
"coff", "coff",
".o",
0, 0,
32, 32,
null_debug_arr, null_debug_arr,
@@ -1179,7 +1163,6 @@ const struct ofmt of_coff = {
coff_sectalign, coff_sectalign,
coff_segbase, coff_segbase,
coff_directives, coff_directives,
coff_std_filename,
coff_cleanup, coff_cleanup,
NULL /* pragma list */ NULL /* pragma list */
}; };
@@ -1195,6 +1178,7 @@ static const struct dfmt * const win32_debug_arr[2] = { &df_cv8, NULL };
const struct ofmt of_win32 = { const struct ofmt of_win32 = {
"Microsoft Win32 (i386) object files", "Microsoft Win32 (i386) object files",
"win32", "win32",
".obj",
0, 0,
32, 32,
win32_debug_arr, win32_debug_arr,
@@ -1208,7 +1192,6 @@ const struct ofmt of_win32 = {
coff_sectalign, coff_sectalign,
coff_segbase, coff_segbase,
coff_directives, coff_directives,
coff_win32_filename,
coff_cleanup, coff_cleanup,
NULL /* pragma list */ NULL /* pragma list */
}; };
@@ -1222,6 +1205,7 @@ static const struct dfmt * const win64_debug_arr[2] = { &df_cv8, NULL };
const struct ofmt of_win64 = { const struct ofmt of_win64 = {
"Microsoft Win64 (x86-64) object files", "Microsoft Win64 (x86-64) object files",
"win64", "win64",
".obj",
0, 0,
64, 64,
win64_debug_arr, win64_debug_arr,
@@ -1235,7 +1219,6 @@ const struct ofmt of_win64 = {
coff_sectalign, coff_sectalign,
coff_segbase, coff_segbase,
coff_directives, coff_directives,
coff_win32_filename,
coff_cleanup, coff_cleanup,
NULL /* pragma list */ NULL /* pragma list */
}; };

View File

@@ -66,6 +66,8 @@ static void dbg_init(void)
{ {
dbgsect = NULL; dbgsect = NULL;
fprintf(ofile, "NASM Output format debug dump\n"); fprintf(ofile, "NASM Output format debug dump\n");
fprintf(ofile, "input file = %s\n", inname);
fprintf(ofile, "output file = %s\n", outname);
} }
static void dbg_cleanup(void) static void dbg_cleanup(void)
@@ -369,11 +371,6 @@ dbg_pragma(const struct pragma *pragma)
return DIRR_OK; return DIRR_OK;
} }
static void dbg_filename(char *inname, char *outname)
{
standard_extension(inname, outname, ".dbg");
}
static const char * const types[] = { static const char * const types[] = {
"unknown", "label", "byte", "word", "dword", "float", "qword", "tbyte" "unknown", "label", "byte", "word", "dword", "float", "qword", "tbyte"
}; };
@@ -443,6 +440,7 @@ extern macros_t dbg_stdmac[];
const struct ofmt of_dbg = { const struct ofmt of_dbg = {
"Trace of all info passed to output stage", "Trace of all info passed to output stage",
"dbg", "dbg",
".dbg",
OFMT_TEXT, OFMT_TEXT,
64, 64,
debug_debug_arr, debug_debug_arr,
@@ -456,7 +454,6 @@ const struct ofmt of_dbg = {
dbg_sectalign, dbg_sectalign,
dbg_segbase, dbg_segbase,
dbg_directive, dbg_directive,
dbg_filename,
dbg_cleanup, dbg_cleanup,
dbg_pragma_list dbg_pragma_list
}; };

View File

@@ -2224,12 +2224,6 @@ static int32_t elf_segbase(int32_t segment)
return segment; return segment;
} }
static void elf_filename(char *inname, char *outname)
{
strcpy(elf_module, inname);
standard_extension(inname, outname, ".o");
}
extern macros_t elf_stdmac[]; extern macros_t elf_stdmac[];
/* Claim "elf" as a pragma namespace, for the future */ /* Claim "elf" as a pragma namespace, for the future */
@@ -2272,6 +2266,7 @@ static const struct dfmt * const elf32_debugs_arr[3] =
const struct ofmt of_elf32 = { const struct ofmt of_elf32 = {
"ELF32 (i386) object files (e.g. Linux)", "ELF32 (i386) object files (e.g. Linux)",
"elf32", "elf32",
".o",
0, 0,
32, 32,
elf32_debugs_arr, elf32_debugs_arr,
@@ -2285,7 +2280,6 @@ const struct ofmt of_elf32 = {
elf_sectalign, elf_sectalign,
elf_segbase, elf_segbase,
elf_directive, elf_directive,
elf_filename,
elf_cleanup, elf_cleanup,
elf_pragma_list, elf_pragma_list,
}; };
@@ -2322,6 +2316,7 @@ static const struct dfmt * const elf64_debugs_arr[3] =
const struct ofmt of_elf64 = { const struct ofmt of_elf64 = {
"ELF64 (x86_64) object files (e.g. Linux)", "ELF64 (x86_64) object files (e.g. Linux)",
"elf64", "elf64",
".o",
0, 0,
64, 64,
elf64_debugs_arr, elf64_debugs_arr,
@@ -2335,7 +2330,6 @@ const struct ofmt of_elf64 = {
elf_sectalign, elf_sectalign,
elf_segbase, elf_segbase,
elf_directive, elf_directive,
elf_filename,
elf_cleanup, elf_cleanup,
elf_pragma_list, elf_pragma_list,
}; };
@@ -2372,6 +2366,7 @@ static const struct dfmt * const elfx32_debugs_arr[3] =
const struct ofmt of_elfx32 = { const struct ofmt of_elfx32 = {
"ELFX32 (x86_64) object files (e.g. Linux)", "ELFX32 (x86_64) object files (e.g. Linux)",
"elfx32", "elfx32",
".o",
0, 0,
64, 64,
elfx32_debugs_arr, elfx32_debugs_arr,
@@ -2385,7 +2380,6 @@ const struct ofmt of_elfx32 = {
elf_sectalign, elf_sectalign,
elf_segbase, elf_segbase,
elf_directive, elf_directive,
elf_filename,
elf_cleanup, elf_cleanup,
NULL /* pragma list */ NULL /* pragma list */
}; };

View File

@@ -886,15 +886,6 @@ static int32_t ieee_segbase(int32_t segment)
return segment; /* no special treatment */ return segment; /* no special treatment */
} }
/*
* filename
*/
static void ieee_filename(char *inname, char *outname)
{
strcpy(ieee_infile, inname);
standard_extension(inname, outname, ".o");
}
static void ieee_write_file(void) static void ieee_write_file(void)
{ {
const struct tm * const thetime = &official_compile_time.local; const struct tm * const thetime = &official_compile_time.local;
@@ -1507,6 +1498,7 @@ static const struct dfmt * const ladsoft_debug_arr[3] = {
const struct ofmt of_ieee = { const struct ofmt of_ieee = {
"IEEE-695 (LADsoft variant) object file format", "IEEE-695 (LADsoft variant) object file format",
"ieee", "ieee",
".o",
OFMT_TEXT, OFMT_TEXT,
32, 32,
ladsoft_debug_arr, ladsoft_debug_arr,
@@ -1520,7 +1512,6 @@ const struct ofmt of_ieee = {
ieee_sectalign, ieee_sectalign,
ieee_segbase, ieee_segbase,
ieee_directive, ieee_directive,
ieee_filename,
ieee_cleanup, ieee_cleanup,
NULL /* pragma list */ NULL /* pragma list */
}; };

View File

@@ -1106,12 +1106,6 @@ static int32_t macho_segbase(int32_t section)
return section; return section;
} }
static void macho_filename(char *inname, char *outname)
{
standard_extension(inname, outname, ".o");
module_name = inname;
}
extern macros_t macho_stdmac[]; extern macros_t macho_stdmac[];
/* Comparison function for qsort symbol layout. */ /* Comparison function for qsort symbol layout. */
@@ -2293,6 +2287,7 @@ static const struct dfmt * const macho32_df_arr[2] =
const struct ofmt of_macho32 = { const struct ofmt of_macho32 = {
"NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (i386) object files", "NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (i386) object files",
"macho32", "macho32",
".o",
0, 0,
32, 32,
macho32_df_arr, macho32_df_arr,
@@ -2306,7 +2301,6 @@ const struct ofmt of_macho32 = {
macho_sectalign, macho_sectalign,
macho_segbase, macho_segbase,
null_directive, null_directive,
macho_filename,
macho_cleanup, macho_cleanup,
macho_pragma_list macho_pragma_list
}; };
@@ -2358,6 +2352,7 @@ static const struct dfmt * const macho64_df_arr[2] =
const struct ofmt of_macho64 = { const struct ofmt of_macho64 = {
"NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (x86_64) object files", "NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (x86_64) object files",
"macho64", "macho64",
".o",
0, 0,
64, 64,
macho64_df_arr, macho64_df_arr,
@@ -2371,7 +2366,6 @@ const struct ofmt of_macho64 = {
macho_sectalign, macho_sectalign,
macho_segbase, macho_segbase,
null_directive, null_directive,
macho_filename,
macho_cleanup, macho_cleanup,
macho_pragma_list, macho_pragma_list,
}; };

View File

@@ -1940,12 +1940,6 @@ static int32_t obj_segbase(int32_t segment)
return segment; /* no special treatment */ return segment; /* no special treatment */
} }
static void obj_filename(char *inname, char *outname)
{
strcpy(obj_infile, inname);
standard_extension(inname, outname, ".obj");
}
/* Get a file timestamp in MS-DOS format */ /* Get a file timestamp in MS-DOS format */
static uint32_t obj_file_timestamp(const char *pathname) static uint32_t obj_file_timestamp(const char *pathname)
{ {
@@ -2705,6 +2699,7 @@ static const struct pragma_facility obj_pragma_list[] = {
const struct ofmt of_obj = { const struct ofmt of_obj = {
"MS-DOS 16-bit/32-bit OMF object files", "MS-DOS 16-bit/32-bit OMF object files",
"obj", "obj",
".obj",
0, 0,
32, 32,
borland_debug_arr, borland_debug_arr,
@@ -2718,7 +2713,6 @@ const struct ofmt of_obj = {
obj_sectalign, obj_sectalign,
obj_segbase, obj_segbase,
obj_directive, obj_directive,
obj_filename,
obj_cleanup, obj_cleanup,
obj_pragma_list obj_pragma_list
}; };

View File

@@ -760,16 +760,12 @@ rdf2_directive(enum directive directive, char *value, int pass)
} }
} }
static void rdf2_filename(char *inname, char *outname)
{
standard_extension(inname, outname, ".rdf");
}
extern macros_t rdf2_stdmac[]; extern macros_t rdf2_stdmac[];
const struct ofmt of_rdf2 = { const struct ofmt of_rdf2 = {
"Relocatable Dynamic Object File Format v2.0", "Relocatable Dynamic Object File Format v2.0",
"rdf", "rdf",
".rdf",
0, 0,
64, 64,
null_debug_arr, null_debug_arr,
@@ -783,7 +779,6 @@ const struct ofmt of_rdf2 = {
null_sectalign, null_sectalign,
rdf2_segbase, rdf2_segbase,
rdf2_directive, rdf2_directive,
rdf2_filename,
rdf2_cleanup, rdf2_cleanup,
NULL /* pragma list */ NULL /* pragma list */
}; };

50
stdlib/strrchrnul.c Normal file
View File

@@ -0,0 +1,50 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 2017 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ----------------------------------------------------------------------- */
#include "compiler.h"
#include <string.h>
#ifndef HAVE_STRRCHRNUL
char *strrchrnul(const char *s, int c)
{
char *p;
p = strrchr(s, c);
if (!p)
p = strchr(s, '\0');
return p;
}
#endif