Given the following program:
\#include <libgen.h>
\#include <stdio.h>
/* extracts basename from path, optionally stripping the extension "\.*"
* (same concept as /bin/sh `basename`, but different handling of extension). */
static char *basename2 (char *path)
{
char *b;
for (b = path; *path; path++)
if (*path == '/')
b = path + 1;
return b;
}
static void basename_compare(char *path)
{
printf("basename: %s\n", basename(path));
printf("basename2: %s\n\n", basename2(path));
}
int main (int argc, char *argv[])
{
// From http://pubs.opengroup.org/onlinepubs/
9699919799/
// ``Sample Input and Output Strings''
basename_compare("/usr/lib");
basename_compare("/usr/");
basename_compare("/");
basename_compare("///");
basename_compare("//usr//lib//");
return 0;
}
... and the program's output:
basename: lib
basename2: lib
basename: usr
basename2:
basename: /
basename2:
basename: /
basename2:
basename: lib
basename2:
... we can see that basename2() behaves the same as basename(3) in the
average use case, but messes up pretty severely in others. Besides
that, basename(3) is mandated by POSIX so should be present on modern
Unix-like systems, so we shouldn't define it ourselves.
Some notes:
- it doesn't appear to be mentioned in POSIX, but OpenBSD's basename(3)
returns NULL if the returned path componenet is > PATH_MAX, so add a
check for that
- basename(3) shouldn't return an empty string, so remove the
program_name[0] != '\0' check
/* PURPOSE. */
\f
+#include <libgen.h>
+
#include "flexdef.h"
#include "version.h"
#include "options.h"
void flexinit(int, char **);
void readin(void);
void set_up_initial_allocations(void);
-static char *basename2(char *path);
/* these globals are all defined and commented in flexdef.h */
flex_init_regex();
/* Enable C++ if program name ends with '+'. */
- program_name = basename2 (argv[0]);
+ program_name = basename (argv[0]);
- if (program_name[0] != '\0' &&
+ if (program_name != NULL &&
program_name[strlen (program_name) - 1] == '+')
C_plus_plus = true;
}
-/* extracts basename from path, optionally stripping the extension "\.*"
- * (same concept as /bin/sh `basename`, but different handling of extension). */
-static char *basename2 (char *path)
-{
- char *b;
-
- for (b = path; *path; path++)
- if (*path == '/')
- b = path + 1;
- return b;
-}
-
void usage (void)
{
FILE *f = stdout;