Import existing source tree; original VCS history is no longer available. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
171 lines
4.3 KiB
C++
171 lines
4.3 KiB
C++
/*
|
|
------------------------------------------------------------
|
|
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
|