Today's Page Hits: 1246
I have more hair and it isn't so grey. :->
This page validates as XHTML 1.0, and will look much better in a browser that supports web standards, but it is accessible to any browser or Internet device. It was created using techniques detailed at glish.com/css/.
Given a directory path entry to a file, I want to find:
I can probably find a standard function to do this, but where is the fun in that?
You might notice I am being vague with the extension and basename, I'm giving the definition we know from common usage, not a precise one. We'll see why in a bit. And I am assuming we are passing in a file and not a directroy.
I've got the code sitting in the policy prototype, but I pulled it out to focus on and to do some fun unit testing. So, here is the code:
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
typedef struct {
char *ext;
char *path;
char *base;
char *file;
} policyAttributes_t;
int
main (int argc, char *argv[])
{
policyAttributes_t pat;
int rc = 0;
char *junk;
char *s;
/*
* Do some initialization.
*/
memset(&pat, '\0', sizeof(pat));
pat.path = strdup(argv[1]);
if (pat.path == NULL) {
...
}
/*
* Now we need the file.
*/
s = strrchr(argv[1], '/');
if (s) {
junk = strdup(s+1);
if (junk == NULL) {
...
}
pat.file = strdup(junk);
if (pat.file == NULL) {
...
}
s = strrchr(junk, '.');
if (s) {
pat.ext = strdup(s+1);
if (junk == NULL) {
...
}
*s = '\0';
}
pat.base = junk;
}
cleanup:
if (pat.path) {
printf("path = <%s>\n", pat.path);
free(pat.path);
}
if (pat.ext) {
printf("ext = <%s>\n", pat.ext);
free(pat.ext);
}
if (pat.base) {
printf("base = <%s>\n", pat.base);
free(pat.base);
}
if (pat.file) {
printf("file = <%s>\n", pat.file);
free(pat.file);
}
return (rc);
}
You can see I pulled it out of the other code - I preserved the pat variable. Anyway, I was mostly worried about the pointer manipulation, but I shouldn't have:
% ./a.out /foo/bar.c path = </foo/bar.c> ext = <c> base = <bar> file = <bar.c> % ./a.out /foo/grabba/yabba/bar.c path = </foo/grabba/yabba/bar.c> ext = <c> base = <bar> file = <bar.c> % ./a.out /foo/grabba/yabba/bar path = </foo/grabba/yabba/bar> base = <bar> file = <bar>
Now, in a traditional CIFS only world, everything would be hunky-dory. I could probably even do the 8+3 filename stuff. But we are wearing big boy pants now, so another test yields a result I do not agree with:
% ./a.out /foo/grabba/yabba/.cshrc path = </foo/grabba/yabba/.cshrc> ext = <cshrc> base = <> file = <.cshrc>
I would argue that the base name is '.cshrc' and there is no extension.
Anyone have any different views?
shouldn't you canonicalize? consider
/foo//bar
/foo/
/foo/.
etc.
Posted by peter honeyman on January 23, 2008 at 12:33 AM CST #