mirror of
https://github.com/fallout2-ce/fallout2-ce.git
synced 2026-07-27 16:47:11 -07:00
Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3a9433c0f1 | ||
|
|
b97c9864aa | ||
|
|
8d0009aa45 |
+3
-2
@@ -373,8 +373,8 @@ if(APPLE)
|
||||
endif()
|
||||
|
||||
set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.alexbatalov.fallout2-ce")
|
||||
set(MACOSX_BUNDLE_SHORT_VERSION_STRING "1.3.0")
|
||||
set(MACOSX_BUNDLE_BUNDLE_VERSION "1.3.0")
|
||||
set(MACOSX_BUNDLE_SHORT_VERSION_STRING "1.4.0")
|
||||
set(MACOSX_BUNDLE_BUNDLE_VERSION "1.4.0")
|
||||
endif()
|
||||
|
||||
if((NOT ${CMAKE_SYSTEM_NAME} MATCHES "Emscripten"))
|
||||
@@ -434,6 +434,7 @@ endif()
|
||||
|
||||
add_subdirectory("third_party/fpattern")
|
||||
target_link_libraries(${EXECUTABLE_NAME} fpattern::fpattern)
|
||||
target_link_libraries(${EXECUTABLE_NAME} fpattern_windows::fpattern_windows)
|
||||
|
||||
target_link_libraries(${EXECUTABLE_NAME} ${ZLIB_LIBRARIES})
|
||||
target_include_directories(${EXECUTABLE_NAME} PRIVATE ${ZLIB_INCLUDE_DIRS})
|
||||
|
||||
@@ -197,11 +197,6 @@ NumbersInDialogue=0
|
||||
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
[Scripts]
|
||||
|
||||
;Comma-separated list of masked paths to load global scripts from
|
||||
;Only use single backslash \ as the directory separator
|
||||
;Paths outside of scripts folder are supported
|
||||
;GlobalScriptPaths=scripts\gl_*.int,scripts\sfall\gl*.int
|
||||
|
||||
;Uncomment the option to specify an additional directory for ini files used by scripts
|
||||
;The game will search for ini files first relative to this directory and then relative to the root directory if not found
|
||||
;The path length is limited to 61 characters
|
||||
|
||||
@@ -9,8 +9,8 @@ android {
|
||||
applicationId 'com.alexbatalov.fallout2ce'
|
||||
minSdk 21
|
||||
targetSdk 32
|
||||
versionCode 4
|
||||
versionName '1.3.0'
|
||||
versionCode 5
|
||||
versionName '1.4.0'
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
arguments '-DANDROID_STL=c++_static'
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.alexbatalov.fallout2ce"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0.0"
|
||||
android:versionCode="5"
|
||||
android:versionName="1.4.0"
|
||||
android:installLocation="auto">
|
||||
|
||||
<!-- OpenGL ES 2.0 -->
|
||||
|
||||
+2
-14
@@ -30,22 +30,10 @@ compile.exe -q -p -l -O2 -d -s -n -I<sfall_headers_id> <script_name.ssl>
|
||||
|
||||
- Install [VSCode Extension](https://marketplace.visualstudio.com/items?itemName=BGforge.bgforge-mls)
|
||||
|
||||
|
||||
|
||||
## Run test script
|
||||
|
||||
1. Move compiled `.int` file into game folder as `data/scripts/gl_<script_name>.int`
|
||||
1. Move compiled `.int` file into game folder as `scripts/gl_<script_name>.int`
|
||||
|
||||
2. Change `ddraw.ini` and add this section:
|
||||
```ini
|
||||
[Scripts]
|
||||
GlobalScriptPaths=data/scripts/gl*.int
|
||||
```
|
||||
|
||||
(or add new path using comma as separator)
|
||||
|
||||
Note that on non-Windows it have to be `/` as folder separator
|
||||
|
||||
3. Run game, check that game displays message about tests
|
||||
2. Run game, check that game displays message about tests
|
||||
|
||||
|
||||
|
||||
@@ -164,6 +164,12 @@ procedure array_test_suite begin
|
||||
call assertEquals("saved arrays 3", len_array(list_saved_arrays), len_array(arr2) - 1);
|
||||
*/
|
||||
|
||||
display_msg("Testing nested expressions...");
|
||||
arr := [["one", "two"]];
|
||||
call assertEquals("nested 1", arr[0][1], "two");
|
||||
arr := [["one", "two"], {"three": ["four", -1]}];
|
||||
call assertEquals("nested 2", arr[1].three[0], "four");
|
||||
|
||||
display_msg("All tests finished with "+test_suite_errors+" errors.");
|
||||
|
||||
call report_test_results("arrays");
|
||||
|
||||
+4
-3
@@ -7,7 +7,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <fpattern/fpattern.h>
|
||||
#include "fpattern_windows.h"
|
||||
|
||||
#include "platform_compat.h"
|
||||
|
||||
@@ -201,9 +201,10 @@ bool dbaseClose(DBase* dbase)
|
||||
// 0x4E5308
|
||||
bool dbaseFindFirstEntry(DBase* dbase, DFileFindData* findFileData, const char* pattern)
|
||||
{
|
||||
// .dat files always have windows style paths
|
||||
for (int index = 0; index < dbase->entriesLength; index++) {
|
||||
DBaseEntry* entry = &(dbase->entries[index]);
|
||||
if (fpattern_match(pattern, entry->path)) {
|
||||
if (fpattern_windows_match(pattern, entry->path)) {
|
||||
strcpy(findFileData->fileName, entry->path);
|
||||
strcpy(findFileData->pattern, pattern);
|
||||
findFileData->index = index;
|
||||
@@ -219,7 +220,7 @@ bool dbaseFindNextEntry(DBase* dbase, DFileFindData* findFileData)
|
||||
{
|
||||
for (int index = findFileData->index + 1; index < dbase->entriesLength; index++) {
|
||||
DBaseEntry* entry = &(dbase->entries[index]);
|
||||
if (fpattern_match(findFileData->pattern, entry->path)) {
|
||||
if (fpattern_windows_match(findFileData->pattern, entry->path)) {
|
||||
strcpy(findFileData->fileName, entry->path);
|
||||
findFileData->index = index;
|
||||
return true;
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
#ifndef FALLOUT_FPATTERN_WINDOWS_H_
|
||||
#define FALLOUT_FPATTERN_WINDOWS_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int fpattern_windows_isvalid(const char* pat);
|
||||
int fpattern_windows_match(const char* pat, const char* fname);
|
||||
int fpattern_windows_matchn(const char* pat, const char* fname);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+44
-9
@@ -476,7 +476,14 @@ private:
|
||||
struct SfallArraysState {
|
||||
std::unordered_map<ArrayId, std::unique_ptr<SFallArray>> arrays;
|
||||
std::unordered_set<ArrayId> temporaryArrayIds;
|
||||
|
||||
// auto-incremented ID
|
||||
int nextArrayId = kInitialArrayId;
|
||||
|
||||
// special array ID for array expressions, contains the ID number of the currently created array
|
||||
ArrayId expressionArrayId = 0;
|
||||
// special stack for array expressions, contains ID numbers of the currently created arrays
|
||||
std::vector<ArrayId> arrayExpressionStack;
|
||||
};
|
||||
|
||||
static SfallArraysState* _state = nullptr;
|
||||
@@ -525,6 +532,21 @@ ArrayId CreateArray(int len, unsigned int flags)
|
||||
_state->arrays.emplace(std::make_pair(arrayId, std::make_unique<SFallArrayList>(len, flags)));
|
||||
}
|
||||
|
||||
if ((flags & SFALL_ARRAYFLAG_EXPR_PUSH) != 0) {
|
||||
// When creating array for sub-expression, make sure to add array for base expression to stack
|
||||
// This is messy, but required to support older scripts:
|
||||
// - We must always assign expressionArrayId for one-layer expressions from older scripts to work like they did before
|
||||
// - We can't directly push first arrayID into stack b/c no way to distinguish between start of an expression and normal temp_array call
|
||||
// - Compiler will only add this flag for temp_array call generated from a sub-expression
|
||||
// - So only on this second call we know we are in expression and expressionArrayId definitely contains arrayId of the first layer
|
||||
auto& expressionStack = _state->arrayExpressionStack;
|
||||
if (expressionStack.empty() && _state->expressionArrayId != 0) {
|
||||
expressionStack.push_back(_state->expressionArrayId);
|
||||
}
|
||||
expressionStack.push_back(arrayId);
|
||||
}
|
||||
_state->expressionArrayId = arrayId;
|
||||
|
||||
return arrayId;
|
||||
}
|
||||
|
||||
@@ -614,28 +636,41 @@ void ResizeArray(ArrayId arrayId, int newLen)
|
||||
arr->ResizeArray(newLen);
|
||||
}
|
||||
|
||||
int StackArray(const ProgramValue& key, const ProgramValue& val, Program* program)
|
||||
void SetArrayFromExpression(const ProgramValue& key, const ProgramValue& val, Program* program)
|
||||
{
|
||||
// CE: Sfall uses eponymous global variable which is always the id of the
|
||||
// last created array.
|
||||
ArrayId stackArrayId = _state->nextArrayId - 1;
|
||||
ArrayId arrayId = !_state->arrayExpressionStack.empty()
|
||||
? _state->arrayExpressionStack.back()
|
||||
: _state->expressionArrayId;
|
||||
|
||||
auto arr = get_array_by_id(stackArrayId);
|
||||
auto arr = get_array_by_id(arrayId);
|
||||
if (arr == nullptr) {
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
|
||||
auto size = arr->size();
|
||||
if (size >= ARRAY_MAX_SIZE) {
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (key.asInt() >= size) {
|
||||
arr->ResizeArray(size + 1);
|
||||
}
|
||||
|
||||
SetArray(stackArrayId, key, val, false, program);
|
||||
return 0;
|
||||
SetArray(arrayId, key, val, false, program);
|
||||
}
|
||||
|
||||
void PopExpressionArray()
|
||||
{
|
||||
auto& expressionStack = _state->arrayExpressionStack;
|
||||
if (expressionStack.empty()) return;
|
||||
|
||||
expressionStack.pop_back();
|
||||
|
||||
// Reversing the hack from CreateArray
|
||||
if (expressionStack.size() == 1) {
|
||||
_state->expressionArrayId = expressionStack.back();
|
||||
expressionStack.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
ProgramValue ScanArray(ArrayId arrayId, const ProgramValue& val, Program* program)
|
||||
|
||||
+4
-1
@@ -8,6 +8,8 @@ namespace fallout {
|
||||
#define SFALL_ARRAYFLAG_ASSOC (1) // is map
|
||||
#define SFALL_ARRAYFLAG_CONSTVAL (2) // don't update value of key if the key exists in map
|
||||
#define SFALL_ARRAYFLAG_RESERVED (4) // has no significance in sfall or CE
|
||||
#define SFALL_ARRAYFLAG_EXPR_PUSH (32) // is created as part of array sub-expression
|
||||
#define SFALL_ARRAYFLAG_EXPR_POP (64) // is used to indicate end of array sub-expression, not used in actual array
|
||||
|
||||
using ArrayId = unsigned int;
|
||||
|
||||
@@ -24,7 +26,8 @@ void FreeArray(ArrayId arrayId);
|
||||
void FixArray(ArrayId id);
|
||||
void ResizeArray(ArrayId arrayId, int newLen);
|
||||
void DeleteAllTempArrays();
|
||||
int StackArray(const ProgramValue& key, const ProgramValue& val, Program* program);
|
||||
void SetArrayFromExpression(const ProgramValue& key, const ProgramValue& val, Program* program);
|
||||
void PopExpressionArray();
|
||||
ProgramValue ScanArray(ArrayId arrayId, const ProgramValue& val, Program* program);
|
||||
ArrayId ListAsArray(int type);
|
||||
|
||||
|
||||
@@ -62,8 +62,6 @@ bool sfallConfigInit(int argc, char** argv)
|
||||
configSetBool(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_CITIES_LIMIT_FIX, true);
|
||||
|
||||
configSetString(&gSfallConfig, SFALL_CONFIG_SCRIPTS_KEY, SFALL_CONFIG_INI_CONFIG_FOLDER, "");
|
||||
configSetString(&gSfallConfig, SFALL_CONFIG_SCRIPTS_KEY, SFALL_CONFIG_GLOBAL_SCRIPT_PATHS, "");
|
||||
|
||||
configSetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_PIPBOY_AVAILABLE_AT_GAMESTART, 0);
|
||||
configSetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_USE_WALK_DISTANCE, 5);
|
||||
configSetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_AUTO_OPEN_DOORS, 0);
|
||||
|
||||
@@ -71,7 +71,6 @@ namespace fallout {
|
||||
#define SFALL_CONFIG_EXTRA_MESSAGE_LISTS_KEY "ExtraGameMsgFileList"
|
||||
#define SFALL_CONFIG_NUMBERS_IS_DIALOG_KEY "NumbersInDialogue"
|
||||
#define SFALL_CONFIG_INI_CONFIG_FOLDER "IniConfigFolder"
|
||||
#define SFALL_CONFIG_GLOBAL_SCRIPT_PATHS "GlobalScriptPaths"
|
||||
#define SFALL_CONFIG_AUTO_QUICK_SAVE "AutoQuickSave"
|
||||
#define SFALL_CONFIG_VERSION_STRING "VersionString"
|
||||
#define SFALL_CONFIG_CONFIG_FILE "ConfigFile"
|
||||
|
||||
+11
-31
@@ -37,39 +37,19 @@ bool sfall_gl_scr_init()
|
||||
return false;
|
||||
}
|
||||
|
||||
char* paths;
|
||||
configGetString(&gSfallConfig, SFALL_CONFIG_SCRIPTS_KEY, SFALL_CONFIG_GLOBAL_SCRIPT_PATHS, &paths);
|
||||
|
||||
char* curr = paths;
|
||||
while (curr != nullptr && *curr != '\0') {
|
||||
char* end = strchr(curr, ',');
|
||||
if (end != nullptr) {
|
||||
*end = '\0';
|
||||
// CE: always use "scripts\gl*.int" as global script path
|
||||
const char* scriptPath = "scripts\\gl*.int";
|
||||
const char* dir = "scripts";
|
||||
char** files;
|
||||
int filesLength = fileNameListInit(scriptPath, &files);
|
||||
if (filesLength != 0) {
|
||||
for (int index = 0; index < filesLength; index++) {
|
||||
char path[COMPAT_MAX_PATH];
|
||||
snprintf(path, sizeof(path), "%s\\%s", dir, files[index]);
|
||||
state->paths.push_back(std::string { path });
|
||||
}
|
||||
|
||||
char drive[COMPAT_MAX_DRIVE];
|
||||
char dir[COMPAT_MAX_DIR];
|
||||
compat_splitpath(curr, drive, dir, nullptr, nullptr);
|
||||
|
||||
char** files;
|
||||
int filesLength = fileNameListInit(curr, &files);
|
||||
if (filesLength != 0) {
|
||||
for (int index = 0; index < filesLength; index++) {
|
||||
char path[COMPAT_MAX_PATH];
|
||||
compat_makepath(path, drive, dir, files[index], nullptr);
|
||||
|
||||
state->paths.push_back(std::string { path });
|
||||
}
|
||||
|
||||
fileNameListFree(&files, 0);
|
||||
}
|
||||
|
||||
if (end != nullptr) {
|
||||
*end = ',';
|
||||
curr = end + 1;
|
||||
} else {
|
||||
curr = nullptr;
|
||||
}
|
||||
fileNameListFree(&files, 0);
|
||||
}
|
||||
|
||||
std::sort(state->paths.begin(), state->paths.end());
|
||||
|
||||
+14
-4
@@ -957,6 +957,14 @@ static void op_temp_array(Program* program)
|
||||
{
|
||||
auto flags = programStackPopInteger(program);
|
||||
auto len = programStackPopInteger(program);
|
||||
|
||||
// Special case for array sub-expressions.
|
||||
if ((flags & SFALL_ARRAYFLAG_EXPR_POP) != 0) {
|
||||
PopExpressionArray();
|
||||
programStackPushInteger(program, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
auto arrayId = CreateTempArray(len, flags);
|
||||
programStackPushInteger(program, arrayId);
|
||||
}
|
||||
@@ -986,13 +994,15 @@ static void op_set_array(Program* program)
|
||||
SetArray(arrayId, key, value, true, program);
|
||||
}
|
||||
|
||||
// This special opcode is used to implement array expressions.
|
||||
// It should always push 0 on the stack.
|
||||
// arrayexpr
|
||||
static void op_stack_array(Program* program)
|
||||
static void op_arrayexpr(Program* program)
|
||||
{
|
||||
auto value = programStackPopValue(program);
|
||||
auto key = programStackPopValue(program);
|
||||
auto returnValue = StackArray(key, value, program);
|
||||
programStackPushInteger(program, returnValue);
|
||||
SetArrayFromExpression(key, value, program);
|
||||
programStackPushInteger(program, 0);
|
||||
}
|
||||
|
||||
// scan_array
|
||||
@@ -1654,7 +1664,7 @@ void sfallOpcodesInit()
|
||||
// 0x8256 - int array_key(int array, int index)
|
||||
interpreterRegisterOpcode(0x8256, op_get_array_key);
|
||||
// 0x8257 - int arrayexpr(any key, any value)
|
||||
interpreterRegisterOpcode(0x8257, op_stack_array);
|
||||
interpreterRegisterOpcode(0x8257, op_arrayexpr);
|
||||
|
||||
// 0x81a0 - void set_pickpocket_max(int percentage)
|
||||
// 0x81a1 - void set_hit_chance_max(int percentage)
|
||||
|
||||
Vendored
+30
-8
@@ -1,11 +1,33 @@
|
||||
include(FetchContent)
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
FetchContent_Declare(fpattern
|
||||
GIT_REPOSITORY "https://github.com/alexbatalov/fpattern"
|
||||
GIT_TAG 8523173ec252c3b796fcdfca0fcc6329642fbbe3 # v1.9
|
||||
GIT_SHALLOW TRUE
|
||||
GIT_PROGRESS TRUE
|
||||
EXCLUDE_FROM_ALL
|
||||
project(fpattern
|
||||
LANGUAGES C
|
||||
VERSION "1.0.0"
|
||||
)
|
||||
|
||||
FetchContent_MakeAvailable(fpattern)
|
||||
add_library(fpattern-static src/fpattern.c)
|
||||
add_library(fpattern::fpattern ALIAS fpattern-static)
|
||||
|
||||
if(NOT WIN32)
|
||||
target_compile_definitions(fpattern-static PRIVATE
|
||||
unix=1
|
||||
)
|
||||
endif()
|
||||
|
||||
target_include_directories(fpattern-static PUBLIC
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include"
|
||||
)
|
||||
|
||||
add_library(fpattern-windows-static src/fpattern.c)
|
||||
add_library(fpattern_windows::fpattern_windows ALIAS fpattern-windows-static)
|
||||
|
||||
target_compile_definitions(fpattern-windows-static PRIVATE
|
||||
FPAT_WINDOWS_PATHS
|
||||
fpattern_isvalid=fpattern_windows_isvalid
|
||||
fpattern_match=fpattern_windows_match
|
||||
fpattern_matchn=fpattern_windows_matchn
|
||||
)
|
||||
|
||||
target_include_directories(fpattern-windows-static PUBLIC
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include"
|
||||
)
|
||||
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
/******************************************************************************
|
||||
* debug.h
|
||||
*
|
||||
* Copyright ©1997-2015 by David R. Tribble, all rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef drt_debug_h
|
||||
#define drt_debug_h 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
/* Identification */
|
||||
|
||||
#ifndef NO_H_IDENT
|
||||
static const char drt_debug_h_id[] =
|
||||
"@(#)drt/src/lib/debug.h $Revision: 1.4 $ $Date: 2001/11/12 06:00:00 $";
|
||||
#endif
|
||||
|
||||
|
||||
/*==============================================================================
|
||||
* Debug macros
|
||||
*/
|
||||
|
||||
#ifndef DEBUG
|
||||
#define DEBUG 0
|
||||
#endif
|
||||
|
||||
#if DEBUG-0 <= 0
|
||||
#undef DEBUG
|
||||
#define DEBUG 0
|
||||
#endif
|
||||
|
||||
#if DEBUG
|
||||
#define DL(e) (opt_debug ? (void)(e) : (void)0)
|
||||
#else
|
||||
#define DL(e) ((void)0)
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* drt_debug_h */
|
||||
|
||||
/* End debug.h */
|
||||
+217
@@ -0,0 +1,217 @@
|
||||
/******************************************************************************
|
||||
* fpattern.h
|
||||
* Functions for matching filename patterns to filenames.
|
||||
*
|
||||
* Usage
|
||||
* Filename patterns are composed of regular (printable) characters which
|
||||
* may comprise a filename, as well as special pattern matching characters:
|
||||
*
|
||||
* . Matches a period (.).
|
||||
* Note that a period in a filename is not treated any
|
||||
* differently than any other character.
|
||||
*
|
||||
* ? Any.
|
||||
* Matches any single character except '/' or '\'.
|
||||
*
|
||||
* * Closure.
|
||||
* Matches zero or more occurences of any characters other
|
||||
* than '/' or '\'. Leading '*' characters are allowed.
|
||||
*
|
||||
* SUB Substitute (control-Z).
|
||||
* Similar to '*', this matches zero or more occurences of
|
||||
* any characters other than '/', '\', or '.'. Leading
|
||||
* '^Z' characters are allowed.
|
||||
*
|
||||
* [ab] Set.
|
||||
* Matches the single character 'a' or 'b'.
|
||||
* If the dash '-' character is to be included, it must
|
||||
* immediately follow the opening bracket '['. If the
|
||||
* closing bracket ']' character is to be included, it must
|
||||
* be preceded by a quote '`'.
|
||||
*
|
||||
* [a-z] Range.
|
||||
* Matches a single character in the range 'a' to 'z'.
|
||||
* Ranges and sets may be combined within the same set of
|
||||
* brackets.
|
||||
*
|
||||
* [!R] Exclusive range.
|
||||
* Matches a single character not in the range 'R'.
|
||||
* If range 'R' includes the dash '-' character, the dash
|
||||
* must immediately follow the caret '!'.
|
||||
*
|
||||
* ! Not.
|
||||
* Makes the following pattern (up to the next '/') match
|
||||
* any filename except those what it would normally match.
|
||||
*
|
||||
* / Path separator (UNIX and DOS).
|
||||
* Matches a '/' or '\' pathname (directory) separator.
|
||||
* Multiple separators are treated like a single separator.
|
||||
* A leading separator indicates an absolute pathname.
|
||||
*
|
||||
* \ Path separator (DOS).
|
||||
* Same as the '/' character. Note that this character
|
||||
* must be escaped if used within string constants ("\\").
|
||||
*
|
||||
* \ Quote (UNIX).
|
||||
* Makes the next character a regular (nonspecial)
|
||||
* character. Note that to match the quote character
|
||||
* itself, it must be quoted. Note that this character
|
||||
* must be escaped if used within string constants ("\\").
|
||||
*
|
||||
* ` Quote (DOS).
|
||||
* Makes the next character a regular (nonspecial)
|
||||
* character. Note that to match the quote character
|
||||
* itself, it must be quoted.
|
||||
*
|
||||
* Upper and lower case alphabetic characters are considered identical,
|
||||
* i.e., 'a' and 'A' match each other. (What constitutes a lowercase
|
||||
* letter depends on the current locale settings.)
|
||||
*
|
||||
* Spaces and control characters are treated as normal characters.
|
||||
*
|
||||
* Examples
|
||||
* The following patterns in the left column will match the filenames in
|
||||
* the middle column and will not match filenames in the right column:
|
||||
*
|
||||
* Pattern Will Match Will Not Match
|
||||
* ------- ---------- --------------
|
||||
* a a (only) (anything else)
|
||||
* a. a. (only) (anything else)
|
||||
* a?c abc, acc, arc, a.c a, ac, abbc
|
||||
* a*c ac, abc, abbc, acc, a.c a, ab, acb, bac
|
||||
* a* a, ab, abb, a., a.b b, ba
|
||||
* * a, ab, abb, a., .foo, a.foo (nothing)
|
||||
* *. a., ab., abb., a.foo. a, ab, a.foo, .foo
|
||||
* *.* a., a.b, ah.bc.foo a
|
||||
* ^Z a, ab, abb a., .foo, a.foo
|
||||
* ^Z. a., ab., abb. a, .foo, a.foo
|
||||
* ^Z.* a, a., .foo, a.foo ab, abb
|
||||
* *2.c 2.c, 12.c, foo2.c, foo.12.c 2x.c
|
||||
* a[b-z]c abc, acc, azc (only) (anything else)
|
||||
* [ab0-9]x ax, bx, 0x, 9x zx
|
||||
* a[-.]b a-b, a.b (only) (anything else)
|
||||
* a[!a-z]b a0b, a.b, a@b aab, azb, aa0b
|
||||
* a[!-b]x a0x, a+x, acx a-x, abx, axxx
|
||||
* a[-!b]x a-x, a!x, abx (only) (anything else)
|
||||
* a[`]]x a]x (only) (anything else)
|
||||
* a``x a`x (only) (anything else)
|
||||
* oh`! oh! (only) (anything else)
|
||||
* is`?it is?it (only) (anything else)
|
||||
* !a?c a, ac, ab, abb, acb, a.foo abc, a.c, azc
|
||||
*
|
||||
* History
|
||||
* 1.0, 1997-01-03, David Tribble.
|
||||
* First cut.
|
||||
*
|
||||
* 1.1, 1997-01-03, David Tribble.
|
||||
* Added '^Z' pattern character.
|
||||
* Added fpattern_matchn().
|
||||
*
|
||||
* 1.2, 1997-01-26, David Tribble.
|
||||
* Changed range negation character from '^' to '!', ala Unix.
|
||||
*
|
||||
* 1.3, 1997-08-02, David Tribble.
|
||||
* Added 'FPAT_XXX' macro constants.
|
||||
*
|
||||
* 1.4, 2001-11-21, David Tribble.
|
||||
* Revised slightly for Win32 compilations.
|
||||
*
|
||||
* Limitations
|
||||
* This code is copyrighted by the author, but permission is hereby granted
|
||||
* for its unlimited use provided that the original copyright and
|
||||
* authorship notices are retained intact.
|
||||
*
|
||||
* Queries about this source code can be sent to <david@tribble.com>.
|
||||
*
|
||||
* Copyright ©1997-2001 by David R. Tribble, all rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef drt_fpattern_h
|
||||
#define drt_fpattern_h 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
/* Identification */
|
||||
|
||||
#ifndef NO_H_IDENT
|
||||
static const char drt_fpattern_h_id[] =
|
||||
"@(#)drt/src/lib/fpattern.h $Revision: 1.4 $ $Date: 2001/11/12 06:00:00 $";
|
||||
#endif
|
||||
|
||||
|
||||
/* Manifest constants */
|
||||
|
||||
#define FPAT_QUOTE '\\' /* Quotes a special char */
|
||||
#define FPAT_QUOTE2 '`' /* Quotes a special char */
|
||||
#define FPAT_DEL '/' /* Path delimiter */
|
||||
#define FPAT_DEL2 '\\' /* Path delimiter */
|
||||
#define FPAT_DOT '.' /* Dot char */
|
||||
#define FPAT_NOT '!' /* Exclusion */
|
||||
#define FPAT_ANY '?' /* Any one char */
|
||||
#define FPAT_CLOS '*' /* Zero or more chars */
|
||||
#define FPAT_CLOSP '\x1A' /* Zero or more nondelimiters */
|
||||
#define FPAT_SET_L '[' /* Set/range open bracket */
|
||||
#define FPAT_SET_R ']' /* Set/range close bracket */
|
||||
#define FPAT_SET_NOT '!' /* Set exclusion */
|
||||
#define FPAT_SET_THRU '-' /* Set range of chars */
|
||||
|
||||
|
||||
/* Model-dependent extern aliases */
|
||||
|
||||
#ifdef __MSDOS__
|
||||
|
||||
#if defined(__SMALL__)
|
||||
#define fpattern_isvalid Sfpattern_isvalid
|
||||
#define fpattern_match Sfpattern_match
|
||||
#define fpattern_matchn Sfpattern_matchn
|
||||
#elif defined(__LARGE__)
|
||||
#define fpattern_isvalid Lfpattern_isvalid
|
||||
#define fpattern_match Lfpattern_match
|
||||
#define fpattern_matchn Lfpattern_matchn
|
||||
#elif defined(__COMPACT__)
|
||||
#define fpattern_isvalid Cfpattern_isvalid
|
||||
#define fpattern_match Cfpattern_match
|
||||
#define fpattern_matchn Cfpattern_matchn
|
||||
#elif defined(__MEDIUM__)
|
||||
#define fpattern_isvalid Mfpattern_isvalid
|
||||
#define fpattern_match Mfpattern_match
|
||||
#define fpattern_matchn Mfpattern_matchn
|
||||
#elif defined(__HUGE__)
|
||||
#define fpattern_isvalid Hfpattern_isvalid
|
||||
#define fpattern_match Hfpattern_match
|
||||
#define fpattern_matchn Hfpattern_matchn
|
||||
#elif defined(__TINY__)
|
||||
#define fpattern_isvalid Tfpattern_isvalid
|
||||
#define fpattern_match Tfpattern_match
|
||||
#define fpattern_matchn Tfpattern_matchn
|
||||
#else
|
||||
/* Memory model is not defined, use extern names as is. */
|
||||
#endif
|
||||
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
|
||||
/* Public variables */
|
||||
|
||||
/* (None) */
|
||||
|
||||
|
||||
/* Public functions */
|
||||
|
||||
extern int fpattern_isvalid(const char *pat);
|
||||
extern int fpattern_match(const char *pat, const char *fname);
|
||||
extern int fpattern_matchn(const char *pat, const char *fname);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* drt_fpattern_h */
|
||||
|
||||
/* End fpattern.h */
|
||||
Vendored
+824
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user