1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
|
/*
------------------------------------------------------------
filemap.h - Simple Portable File Path Mapper
------------------------------------------------------------
* David Olofson, 2001
* This code is released under the terms of the GNU LGPL.
*/
/*
* Path syntax:
* All filemapper_t functions but exepath(<exepath>)
* and sys2unix() (obviously!) expect paths in the
* native system format.
*
* ALL OTHER PATHS SHOULD BE IN UNIX FORMAT.
*
* All arguments that are expected to be in system
* format are named along the lines of "syspath".
*
* Classes:
* The 'class>>' construct expands to one of the
* paths registered for 'class', or makes the mapping
* fail (NULL is returned), if the object doesn't
* exist or cannot be created as applicable.
*
* Class references are recursive, and are resolved
* late, at mapping time. (That is, they are resolved
* when someone asks for it, not when registering
* paths.)
*
* Class "HOME>>" is built-in, and resolves to the
* root of the user home directory. (Currently
* looks only at the environment variable "HOME",
* which may not be defined on all platforms.)
*
* Class "EXE>>" is another built-in, and refers to
* the path extracted from exepath().
*/
#ifndef _FILEMAP_H_
#define _FILEMAP_H_
#include "aconfig.h"
#define FM_DEREF_TOKEN ">>"
#include <stdio.h>
#include <dirent.h>
#define FM_BUFFERS 16
#define FM_BUFFER_SIZE 512
struct fm_key_t
{
fm_key_t *next;
char key[10];
char *path;
};
enum
{
FM_ERROR = 0,
FM_FILE,
FM_DIR,
FM_ANY,
FM_FILE_CREATE,
FM_DIR_CREATE
};
// Not a great name - but fm_path_t would just be confusing,
// and an fm_object_t can actually be either a dir or a file.
struct fm_object_t
{
fm_object_t *next;
char *path;
int kind;
~fm_object_t();
};
class filemapper_t
{
// For get_(first|next)()
fm_object_t *objects;
fm_object_t *current_obj;
DIR *current_dir;
// File mapper keys
fm_key_t *keys;
// Application executable path
char *app_path;
// Silly/safe/string alloc :-)
char buffers[FM_BUFFERS][FM_BUFFER_SIZE];
int next_buffer;
char *salloc();
// Various private funcs
void no_double_slashes(char *buf);
void unix_slashes(char *buf);
void sys_slashes(char *buf);
int probe(const char *syspath);
int test_file_create(const char *syspath);
int test_file_dir_any(const char *syspath, int kind);
int try_get(const char *path, int kind);
void add_object(const char *path, int kind);
int recurse_get(char *result, const char *ref, int kind,
int level, int build);
public:
filemapper_t();
~filemapper_t();
// Set/get path to exe file.
// Note that exepath(<appname>) expects a
// path in the *native system* format,
// while exepath() returns a Unix path.
void exepath(const char *syspath);
const char *exepath() { return app_path; }
// Add 'path' to class 'key'.
// Key should be given *without* the '::'.
void addpath(const char *key, const char *path, int first = 0);
// key == NULL, ref == NULL or "*":
// Get first key.
// key == NULL, ref == <some class name>:
// Get first key of class 'ref'.
// key == <some key>, ref == NULL:
// Get next key of same class as 'key'.
// key == <some key>, ref == <some class name>:
// Get next key of class 'ref'.
// The "*" wildcard for 'ref' is allowed.
// Returns NULL if no key was found.
fm_key_t *getkey(fm_key_t *key = NULL, const char *ref = NULL);
// Get object path (returns path in system format!)
const char *get(const char *ref, int kind = FM_FILE);
/*
FIXME: Do these really handle the 'kind' argument properly...?
FIXME: When looking for files, they should return only files
FIXME: matching the 'ref' path, while when looking for dirs,
FIXME: every file inside each matching dir should be returned.
*/
// Initialize path scan. Use get_next() to get the
// paths to all matches.
void get_all(const char *ref, int kind = FM_FILE);
// Get next object (returns path in system format!)
const char *get_next();
// Open/create file/dir.
FILE *fopen(const char *ref, const char *mode);
DIR *opendir(const char *ref);
int mkdir(const char *ref, int perm);
// Print out all registered paths of class 'ref'
// to stream 'f'. (ref == '*') ==> All classes.
void print(FILE *f, const char *ref);
// Translate to and from the internal Unix-like path format
char *sys2unix(const char *syspath);
char *unix2sys(const char *path);
};
#endif
|