bfs: Use the QueryParserUtils instead of its own copy.

* Ingo copied the methods into a shared location, and then obviously
  "forgot" to let BFS use them. As a side note for Ingo: the complete
  error GCC reported was "std::fssh_size_t" not defined with the macro
  wrapper as code location. The actual problem was a "using std::size_t"
  in some C++ header that accidentally got included after the wrapper.
* The shared Query code is not yet used. That'll be done another time.
* Renamed BFS_SHELL define to FS_SHELL, such that QueryParserUtils can be
  used in any file system shell, not just the bfs_shell.
This commit is contained in:
Axel Dörfler 2014-07-03 17:16:19 +02:00
parent ba32021824
commit de9c061339
16 changed files with 102 additions and 432 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2001-2009, Axel Dörfler, axeld@pinc-software.de.
* Copyright 2001-2014, Axel Dörfler, axeld@pinc-software.de.
* Copyright 2010, Clemens Zeidler <haiku@clemens-zeidler.de>
* Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de.
* This file may be used under the terms of the MIT License.
@ -27,24 +27,30 @@
// The API is not fully available, just the Query and the Expression class
// are.
#ifdef FS_SHELL
# include <new>
#include <dirent.h>
#include <stdlib.h>
#include <string.h>
# include "fssh_api_wrapper.h"
# include "fssh_auto_deleter.h"
#else
# include <dirent.h>
# include <stdlib.h>
# include <string.h>
#include <algorithm>
#include <new>
# include <algorithm>
# include <new>
#include <fs_interface.h>
#include <fs_query.h>
#include <TypeConstants.h>
# include <fs_interface.h>
# include <fs_query.h>
# include <TypeConstants.h>
#include <util/SinglyLinkedList.h>
#include <util/Stack.h>
# include <util/SinglyLinkedList.h>
# include <util/Stack.h>
#include <query_private.h>
# include <query_private.h>
#include <lock.h>
# include <lock.h>
#endif // !FS_SHELL
#include <file_systems/QueryParserUtils.h>

View File

@ -1,5 +1,5 @@
/*
* Copyright 2001-2009, Axel Dörfler, axeld@pinc-software.de.
* Copyright 2001-2014, Axel Dörfler, axeld@pinc-software.de.
* Copyright 2010, Clemens Zeidler <haiku@clemens-zeidler.de>
* Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de.
* This file may be used under the terms of the MIT License.
@ -8,9 +8,17 @@
#define _FILE_SYSTEMS_QUERY_PARSER_UTILS_H
#include <sys/cdefs.h>
#ifdef FS_SHELL
# include <new>
# include "fssh_api_wrapper.h"
# include "fssh_auto_deleter.h"
#else
# include <sys/cdefs.h>
# include <SupportDefs.h>
#endif // !FS_SHELL
#include <SupportDefs.h>
namespace QueryParser {

View File

@ -10,19 +10,22 @@
//! B+Tree implementation
#include "Debug.h"
#include "BPlusTree.h"
#include <file_systems/QueryParserUtils.h>
#include "Debug.h"
#include "Utility.h"
#if !_BOOT_MODE
#include "Inode.h"
# include "Inode.h"
#else
#include "Stream.h"
# include "Stream.h"
// BFS::Stream from the bootloader has the same API as Inode.
#define Inode BFS::Stream
# define Inode BFS::Stream
#define strerror(x) "error message unavailable"
# define strerror(x) "error message unavailable"
namespace BFS {
#endif
@ -1032,7 +1035,7 @@ BPlusTree::_CompareKeys(const void* key1, int keyLength1, const void* key2,
type = B_DOUBLE_TYPE;
break;
}
return compareKeys(type, key1, keyLength1, key2, keyLength2);
return QueryParser::compareKeys(type, key1, keyLength1, key2, keyLength2);
}
@ -3122,97 +3125,6 @@ duplicate_array::Remove(off_t value)
}
// #pragma mark -
int32
compareKeys(type_code type, const void* key1, int keyLength1,
const void* key2, int keyLength2)
{
// if one of the keys is NULL, bail out gracefully
if (key1 == NULL || key2 == NULL) {
// even if it's most probably a bug in the calling code, we try to
// give a meaningful result
if (key1 == NULL && key2 != NULL)
return 1;
if (key2 == NULL && key1 != NULL)
return -1;
return 0;
}
switch (type) {
case B_STRING_TYPE:
{
int result = memcmp(key1, key2, min_c(keyLength1, keyLength2));
if (result == 0) {
// ignore trailing null bytes
if ((keyLength1 == keyLength2 + 1
&& ((uint8*)key1)[keyLength2] == '\0')
|| (keyLength2 == keyLength1 + 1
&& ((uint8*)key2)[keyLength1] == '\0'))
return 0;
result = keyLength1 - keyLength2;
}
return result;
}
case B_SSIZE_T_TYPE:
case B_INT32_TYPE:
return *(int32*)key1 - *(int32*)key2;
case B_SIZE_T_TYPE:
case B_UINT32_TYPE:
if (*(uint32*)key1 == *(uint32*)key2)
return 0;
if (*(uint32*)key1 > *(uint32*)key2)
return 1;
return -1;
case B_OFF_T_TYPE:
case B_INT64_TYPE:
if (*(int64*)key1 == *(int64*)key2)
return 0;
if (*(int64*)key1 > *(int64*)key2)
return 1;
return -1;
case B_UINT64_TYPE:
if (*(uint64*)key1 == *(uint64*)key2)
return 0;
if (*(uint64*)key1 > *(uint64*)key2)
return 1;
return -1;
case B_FLOAT_TYPE:
{
float result = *(float*)key1 - *(float*)key2;
if (result == 0.0f)
return 0;
return (result < 0.0f) ? -1 : 1;
}
case B_DOUBLE_TYPE:
{
double result = *(double*)key1 - *(double*)key2;
if (result == 0.0)
return 0;
return (result < 0.0) ? -1 : 1;
}
}
// if the type is unknown, the entries don't match...
return -1;
}
#if _BOOT_MODE
} // namespace BFS
#endif

View File

@ -1,5 +1,5 @@
/*
* Copyright 2001-2012, Axel Dörfler, axeld@pinc-software.de.
* Copyright 2001-2014, Axel Dörfler, axeld@pinc-software.de.
* This file may be used under the terms of the MIT License.
*/
#ifndef B_PLUS_TREE_H
@ -374,10 +374,6 @@ private:
// #pragma mark - helper classes/functions
extern int32 compareKeys(type_code type, const void* key1, int keyLength1,
const void* key2, int keyLength2);
class TreeIterator : public SinglyLinkedListLinkImpl<TreeIterator> {
public:
TreeIterator(BPlusTree* tree);

View File

@ -1,5 +1,5 @@
/*
* Copyright 2001-2013, Axel Dörfler, axeld@pinc-software.de.
* Copyright 2001-2014, Axel Dörfler, axeld@pinc-software.de.
* This file may be used under the terms of the MIT License.
*/
@ -36,7 +36,7 @@
// be improved a lot. Furthermore, the allocation policies used here should
// have some real world tests.
#if BFS_TRACING && !defined(BFS_SHELL)
#if BFS_TRACING && !defined(FS_SHELL)
namespace BFSBlockTracing {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2001-2010, Axel Dörfler, axeld@pinc-software.de.
* Copyright 2001-2014, Axel Dörfler, axeld@pinc-software.de.
* This file may be used under the terms of the MIT License.
*/
@ -7,8 +7,11 @@
//! Index access functions
#include "Debug.h"
#include "Index.h"
#include <file_systems/QueryParserUtils.h>
#include "Debug.h"
#include "Volume.h"
#include "Inode.h"
#include "BPlusTree.h"
@ -230,8 +233,13 @@ Index::Update(Transaction& transaction, const char* name, int32 type,
// If the two keys are identical, don't do anything - only compare if the
// type has been set, until we have a real type code, we can't do much
// about the comparison here
if (!compareKeys(type, oldKey, oldLength, newKey, newLength))
if (oldLength == 0) {
if (newLength == 0)
return B_OK;
} else if (newLength != 0 && !QueryParser::compareKeys(type,
oldKey, oldLength, newKey, newLength)) {
return B_OK;
}
// update all live queries about the change, if they have an index or not
fVolume->UpdateLiveQueries(inode, name, type, oldKey, oldLength,

View File

@ -1,5 +1,5 @@
/*
* Copyright 2001-2013, Axel Dörfler, axeld@pinc-software.de.
* Copyright 2001-2014, Axel Dörfler, axeld@pinc-software.de.
* This file may be used under the terms of the MIT License.
*/
@ -13,7 +13,7 @@
#include "Index.h"
#if BFS_TRACING && !defined(BFS_SHELL) && !defined(_BOOT_MODE)
#if BFS_TRACING && !defined(FS_SHELL) && !defined(_BOOT_MODE)
namespace BFSInodeTracing {
class Create : public AbstractTraceEntry {

View File

@ -1,12 +1,5 @@
SubDir HAIKU_TOP src add-ons kernel file_systems bfs ;
# R5 support has been removed!
#
# Have a look in src/tests/add-ons/kernel/file_systems/bfs/r5/
# for an R5 compatible version.
# In order to make the current BFS version R5 compatible again,
# we would need to port over the Haiku cache API to R5.
# set some additional defines
{
local defines =
@ -39,12 +32,14 @@ KernelAddon bfs :
Inode.cpp
Journal.cpp
Query.cpp
QueryParserUtils.cpp
Volume.cpp
kernel_interface.cpp
;
SEARCH on [ FGristFiles
kernel_cpp.cpp
] = [ FDirName $(HAIKU_TOP) src system kernel util ] ;
SEARCH on [ FGristFiles kernel_cpp.cpp ]
= [ FDirName $(HAIKU_TOP) src system kernel util ] ;
SEARCH on [ FGristFiles QueryParserUtils.cpp ]
+= [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems shared ] ;

View File

@ -1,5 +1,5 @@
/*
* Copyright 2001-2013, Axel Dörfler, axeld@pinc-software.de.
* Copyright 2001-2014, Axel Dörfler, axeld@pinc-software.de.
* This file may be used under the terms of the MIT License.
*/
@ -86,7 +86,7 @@ private:
};
#if BFS_TRACING && !defined(BFS_SHELL) && !defined(_BOOT_MODE)
#if BFS_TRACING && !defined(FS_SHELL) && !defined(_BOOT_MODE)
namespace BFSJournalTracing {
class LogEntry : public AbstractTraceEntry {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2001-2013, Axel Dörfler, axeld@pinc-software.de.
* Copyright 2001-2014, Axel Dörfler, axeld@pinc-software.de.
* Copyright 2010, Clemens Zeidler <haiku@clemens-zeidler.de>
* This file may be used under the terms of the MIT License.
*/
@ -15,6 +15,7 @@
#include "Query.h"
#include <file_systems/QueryParserUtils.h>
#include <query_private.h>
#include "BPlusTree.h"
@ -37,6 +38,9 @@
// are.
using namespace QueryParser;
enum ops {
OP_NONE,
@ -54,20 +58,6 @@ enum ops {
OP_LESS_THAN_OR_EQUAL,
};
enum match {
NO_MATCH = 0,
MATCH_OK = 1,
MATCH_BAD_PATTERN = -2,
MATCH_INVALID_CHARACTER
};
// return values from isValidPattern()
enum {
PATTERN_INVALID_ESCAPE = -3,
PATTERN_INVALID_RANGE,
PATTERN_INVALID_SET
};
union value {
int64 Int64;
@ -211,267 +201,9 @@ private:
// #pragma mark -
void
skipWhitespace(char** expr, int32 skip = 0)
{
char* string = (*expr) + skip;
while (*string == ' ' || *string == '\t') string++;
*expr = string;
}
void
skipWhitespaceReverse(char** expr, char* stop)
{
char* string = *expr;
while (string > stop && (*string == ' ' || *string == '\t'))
string--;
*expr = string;
}
// #pragma mark -
uint32
utf8ToUnicode(char** string)
{
uint8* bytes = (uint8*)*string;
int32 length;
uint8 mask = 0x1f;
switch (bytes[0] & 0xf0) {
case 0xc0:
case 0xd0:
length = 2;
break;
case 0xe0:
length = 3;
break;
case 0xf0:
mask = 0x0f;
length = 4;
break;
default:
// valid 1-byte character
// and invalid characters
(*string)++;
return bytes[0];
}
uint32 c = bytes[0] & mask;
int32 i = 1;
for (; i < length && (bytes[i] & 0x80) > 0; i++)
c = (c << 6) | (bytes[i] & 0x3f);
if (i < length) {
// invalid character
(*string)++;
return (uint32)bytes[0];
}
*string += length;
return c;
}
int32
getFirstPatternSymbol(char* string)
{
char c;
for (int32 index = 0; (c = *string++); index++) {
if (c == '*' || c == '?' || c == '[')
return index;
}
return -1;
}
bool
isPattern(char* string)
{
return getFirstPatternSymbol(string) >= 0 ? true : false;
}
status_t
isValidPattern(char* pattern)
{
while (*pattern) {
switch (*pattern++) {
case '\\':
// the escape character must not be at the end of the pattern
if (!*pattern++)
return PATTERN_INVALID_ESCAPE;
break;
case '[':
if (pattern[0] == ']' || !pattern[0])
return PATTERN_INVALID_SET;
while (*pattern != ']') {
if (*pattern == '\\' && !*++pattern)
return PATTERN_INVALID_ESCAPE;
if (!*pattern)
return PATTERN_INVALID_SET;
if (pattern[0] == '-' && pattern[1] == '-')
return PATTERN_INVALID_RANGE;
pattern++;
}
break;
}
}
return B_OK;
}
/*! Matches the string against the given wildcard pattern.
Returns either MATCH_OK, or NO_MATCH when everything went fine, or
values < 0 (see enum at the top of Query.cpp) if an error occurs.
*/
status_t
matchString(char* pattern, char* string)
{
while (*pattern) {
// end of string == valid end of pattern?
if (!string[0]) {
while (pattern[0] == '*')
pattern++;
return !pattern[0] ? MATCH_OK : NO_MATCH;
}
switch (*pattern++) {
case '?':
{
// match exactly one UTF-8 character; we are
// not interested in the result
utf8ToUnicode(&string);
break;
}
case '*':
{
// compact pattern
while (true) {
if (pattern[0] == '?') {
if (!*++string)
return NO_MATCH;
} else if (pattern[0] != '*')
break;
pattern++;
}
// if the pattern is done, we have matched the string
if (!pattern[0])
return MATCH_OK;
while(true) {
// we have removed all occurences of '*' and '?'
if (pattern[0] == string[0]
|| pattern[0] == '['
|| pattern[0] == '\\') {
status_t status = matchString(pattern, string);
if (status < B_OK || status == MATCH_OK)
return status;
}
// we could be nice here and just jump to the next
// UTF-8 character - but we wouldn't gain that much
// and it'd be slower (since we're checking for
// equality before entering the recursion)
if (!*++string)
return NO_MATCH;
}
break;
}
case '[':
{
bool invert = false;
if (pattern[0] == '^' || pattern[0] == '!') {
invert = true;
pattern++;
}
if (!pattern[0] || pattern[0] == ']')
return MATCH_BAD_PATTERN;
uint32 c = utf8ToUnicode(&string);
bool matched = false;
while (pattern[0] != ']') {
if (!pattern[0])
return MATCH_BAD_PATTERN;
if (pattern[0] == '\\')
pattern++;
uint32 first = utf8ToUnicode(&pattern);
// Does this character match, or is this a range?
if (first == c) {
matched = true;
break;
} else if (pattern[0] == '-' && pattern[1] != ']'
&& pattern[1]) {
pattern++;
if (pattern[0] == '\\') {
pattern++;
if (!pattern[0])
return MATCH_BAD_PATTERN;
}
uint32 last = utf8ToUnicode(&pattern);
if (c >= first && c <= last) {
matched = true;
break;
}
}
}
if (invert)
matched = !matched;
if (matched) {
while (pattern[0] != ']') {
if (!pattern[0])
return MATCH_BAD_PATTERN;
pattern++;
}
pattern++;
break;
}
return NO_MATCH;
}
case '\\':
if (!pattern[0])
return MATCH_BAD_PATTERN;
// supposed to fall through
default:
if (pattern[-1] != string[0])
return NO_MATCH;
string++;
break;
}
}
if (string[0])
return NO_MATCH;
return MATCH_OK;
}
// #pragma mark -
Equation::Equation(char** expr)
: Term(OP_EQUATION),
:
Term(OP_EQUATION),
fAttribute(NULL),
fString(NULL),
fType(0),
@ -1143,7 +875,8 @@ Equation::GetNextMatching(Volume* volume, TreeIterator* iterator,
Operator::Operator(Term* left, int8 op, Term* right)
: Term(op),
:
Term(op),
fLeft(left),
fRight(right)
{

View File

@ -1,5 +1,5 @@
/*
* Copyright 2001-2012, Axel Dörfler, axeld@pinc-software.de
* Copyright 2001-2014, Axel Dörfler, axeld@pinc-software.de
* This file may be used under the terms of the MIT License.
*/
#ifndef BFS_CONTROL_H
@ -9,7 +9,7 @@
//! additional functionality exported via ioctl()
#ifdef BFS_SHELL
#ifdef FS_SHELL
# include "system_dependencies.h"
#else
# include <SupportDefs.h>

View File

@ -1,5 +1,5 @@
/*
* Copyright 2001-2013, Axel Dörfler, axeld@pinc-software.de.
* Copyright 2001-2014, Axel Dörfler, axeld@pinc-software.de.
* This file may be used under the terms of the MIT License.
*/
@ -18,7 +18,7 @@
#include "bfs_disk_system.h"
// TODO: temporary solution as long as there is no public I/O requests API
#ifndef BFS_SHELL
#ifndef FS_SHELL
# include <io_requests.h>
# include <util/fs_trim_support.h>
#endif
@ -487,7 +487,7 @@ bfs_io(fs_volume* _volume, fs_vnode* _node, void* _cookie, io_request* request)
Volume* volume = (Volume*)_volume->private_volume;
Inode* inode = (Inode*)_node->private_node;
#ifndef BFS_SHELL
#ifndef FS_SHELL
if (io_request_is_write(request) && volume->IsReadOnly()) {
notify_io_request(request, B_READ_ONLY_DEVICE);
return B_READ_ONLY_DEVICE;
@ -495,7 +495,7 @@ bfs_io(fs_volume* _volume, fs_vnode* _node, void* _cookie, io_request* request)
#endif
if (inode->FileCache() == NULL) {
#ifndef BFS_SHELL
#ifndef FS_SHELL
notify_io_request(request, B_BAD_VALUE);
#endif
RETURN_ERROR(B_BAD_VALUE);
@ -625,7 +625,7 @@ bfs_ioctl(fs_volume* _volume, fs_vnode* _node, void* _cookie, uint32 cmd,
Volume* volume = (Volume*)_volume->private_volume;
switch (cmd) {
#ifndef BFS_SHELL
#ifndef FS_SHELL
case B_TRIM_DEVICE:
{
fs_trim_data* trimData;

View File

@ -6,14 +6,14 @@
#define _SYSTEM_DEPENDENCIES_H
#ifdef BFS_SHELL
#ifdef FS_SHELL
#include <new>
#include "fssh_api_wrapper.h"
#include "fssh_auto_deleter.h"
#else // !BFS_SHELL
#else // !FS_SHELL
#include <AutoDeleter.h>
#include <util/AutoLock.h>
@ -51,7 +51,7 @@
#include <time.h>
#include <unistd.h>
#endif // !BFS_SHELL
#endif // !FS_SHELL
#endif // _SYSTEM_DEPENDENCIES_H

View File

@ -1,18 +1,21 @@
/*
* Copyright 2001-2009, Axel Dörfler, axeld@pinc-software.de.
* Copyright 2001-2014, Axel Dörfler, axeld@pinc-software.de.
* Copyright 2010, Clemens Zeidler <haiku@clemens-zeidler.de>
* Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de.
* This file may be used under the terms of the MIT License.
*/
#include <file_systems/QueryParserUtils.h>
#include <string.h>
// This needs to be the first include because of the fs shell API wrapper
#include <algorithm>
#include <TypeConstants.h>
#include <file_systems/QueryParserUtils.h>
#ifndef FS_SHELL
# include <string.h>
# include <TypeConstants.h>
#endif
namespace QueryParser {
@ -24,7 +27,7 @@ compare_integral(const Key& a, const Key& b)
{
if (a < b)
return -1;
else if (a > b)
if (a > b)
return 1;
return 0;
}

View File

@ -1,7 +1,7 @@
SubDir HAIKU_TOP src system boot loader file_systems bfs ;
UsePrivateKernelHeaders ;
UsePrivateHeaders shared storage ;
UsePrivateHeaders file_systems shared storage ;
SubDirHdrs $(HAIKU_TOP) src add-ons kernel file_systems bfs ;
@ -17,8 +17,12 @@ BootStaticLibrary boot_bfs :
Link.cpp
Stream.cpp
BPlusTree.cpp
QueryParserUtils.cpp
: -fno-pic
;
SEARCH on [ FGristFiles BPlusTree.cpp ]
= [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems bfs ] ;
SEARCH on [ FGristFiles QueryParserUtils.cpp ]
+= [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems shared ] ;

View File

@ -9,7 +9,7 @@ DEFINES += HAIKU_BUILD_COMPATIBILITY_H ;
{
local defines =
#BFS_BIG_ENDIAN_ONLY
BFS_SHELL
FS_SHELL
;
if $(DEBUG) = 0 {
@ -42,6 +42,7 @@ if ! $(HOST_PLATFORM_BEOS_COMPATIBLE) {
UsePrivateHeaders shared storage ;
UsePrivateHeaders fs_shell ;
UseHeaders [ FDirName $(HAIKU_TOP) headers private ] : true ;
UseHeaders [ FDirName $(HAIKU_TOP) src tools fs_shell ] ;
local bfsSource =
@ -54,6 +55,7 @@ local bfsSource =
Inode.cpp
Journal.cpp
Query.cpp
QueryParserUtils.cpp
Volume.cpp
kernel_interface.cpp
@ -79,3 +81,6 @@ BuildPlatformMain <build>bfs_fuse
$(libHaikuCompat) $(HOST_LIBSUPC++) $(HOST_LIBSTDC++)
$(HOST_STATIC_LIBROOT) $(fsShellCommandLibs) fuse
;
SEARCH on [ FGristFiles QueryParserUtils.cpp ]
+= [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems shared ] ;