mirror of
https://github.com/jarun/nnn.git
synced 2024-11-28 05:41:31 +00:00
An optimized dirname()
This commit is contained in:
parent
7be7a6d215
commit
8f18c4049c
10
README.md
10
README.md
|
@ -72,9 +72,15 @@ I chose to fork because:
|
|||
- Associate PDF files with [zathura](https://pwmt.org/projects/zathura/)
|
||||
- Use environment variable `NNN_FALLBACK_OPENER` to open other non-associated files
|
||||
- Removed `less` as default file opener (there is no universal standalone opener utility)
|
||||
- Compilation
|
||||
- Use `-O3` for compilation, fixed warnings
|
||||
- Optimizations
|
||||
- Efficient memory usage, 0 malloc()
|
||||
- Complete redundant buffer removal
|
||||
- All frequently used local chunks now static
|
||||
- Removed some redundant string allocation and manipulation
|
||||
- Simplified some roundabout procedures
|
||||
- `-O3` level optimization, warning fixes
|
||||
- Added compilation flag `-march=native`
|
||||
- Massive binary size optimization
|
||||
- Remove generated config.h on `make clean`
|
||||
- strip the final binary
|
||||
|
||||
|
|
95
nnn.c
95
nnn.c
|
@ -7,7 +7,6 @@
|
|||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <libgen.h>
|
||||
#include <limits.h>
|
||||
#include <locale.h>
|
||||
#include <regex.h>
|
||||
|
@ -93,9 +92,9 @@ typedef struct entry {
|
|||
static struct entry *dents;
|
||||
static int ndents, cur;
|
||||
static int idle;
|
||||
static char *opener = NULL;
|
||||
static char *fallback_opener = NULL;
|
||||
static char *copier = NULL;
|
||||
static char *opener;
|
||||
static char *fallback_opener;
|
||||
static char *copier;
|
||||
static const char* size_units[] = {"B", "K", "M", "G", "T", "P", "E", "Z", "Y"};
|
||||
|
||||
/*
|
||||
|
@ -144,6 +143,29 @@ xrealloc(void *p, size_t size)
|
|||
return p;
|
||||
}
|
||||
|
||||
/*
|
||||
* The poor man's implementation of memrchr().
|
||||
* We are only looking for '/' in this program.
|
||||
*/
|
||||
static void *
|
||||
xmemrchr(const void *s, int c, size_t n)
|
||||
{
|
||||
unsigned char *p;
|
||||
unsigned char ch = (unsigned char)c;
|
||||
|
||||
if (!s || !n)
|
||||
return NULL;
|
||||
|
||||
p = (unsigned char *)s + n - 1;
|
||||
|
||||
while(n--)
|
||||
if ((*p--) == ch)
|
||||
return ++p;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Some implementations of dirname(3) may modify `path' and some
|
||||
* return a pointer inside `path'. */
|
||||
static char *
|
||||
|
@ -159,6 +181,71 @@ xdirname(const char *path)
|
|||
strlcpy(out, p, sizeof(out));
|
||||
return out;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The following dirname() implementation does not
|
||||
* change the input. We use a copy of the original.
|
||||
*
|
||||
* Modified from the glibc (GNU LGPL) version.
|
||||
*/
|
||||
static char *
|
||||
xdirname(const char *path)
|
||||
{
|
||||
static char name[PATH_MAX];
|
||||
char *last_slash;
|
||||
|
||||
strlcpy(name, path, PATH_MAX);
|
||||
|
||||
/* Find last '/'. */
|
||||
last_slash = name != NULL ? strrchr(name, '/') : NULL;
|
||||
|
||||
if (last_slash != NULL && last_slash != name && last_slash[1] == '\0') {
|
||||
/* Determine whether all remaining characters are slashes. */
|
||||
char *runp;
|
||||
|
||||
for (runp = last_slash; runp != name; --runp)
|
||||
if (runp[-1] != '/')
|
||||
break;
|
||||
|
||||
/* The '/' is the last character, we have to look further. */
|
||||
if (runp != name)
|
||||
last_slash = xmemrchr(name, '/', runp - name);
|
||||
}
|
||||
|
||||
if (last_slash != NULL) {
|
||||
/* Determine whether all remaining characters are slashes. */
|
||||
char *runp;
|
||||
|
||||
for (runp = last_slash; runp != name; --runp)
|
||||
if (runp[-1] != '/')
|
||||
break;
|
||||
|
||||
/* Terminate the name. */
|
||||
if (runp == name) {
|
||||
/* The last slash is the first character in the string.
|
||||
We have to return "/". As a special case we have to
|
||||
return "//" if there are exactly two slashes at the
|
||||
beginning of the string. See XBD 4.10 Path Name
|
||||
Resolution for more information. */
|
||||
if (last_slash == name + 1)
|
||||
++last_slash;
|
||||
else
|
||||
last_slash = name + 1;
|
||||
} else
|
||||
last_slash = runp;
|
||||
|
||||
last_slash[0] = '\0';
|
||||
} else {
|
||||
/* This assignment is ill-designed but the XPG specs require to
|
||||
return a string containing "." in any case no directory part
|
||||
is found and so a static and constant string is required. */
|
||||
name[0] = '.';
|
||||
name[1] = '\0';
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
static void
|
||||
spawn(char *file, char *arg, char *dir)
|
||||
|
|
Loading…
Reference in a new issue