MGMDB Start
This commit is contained in:
commit
5d14fcdcae
8
.gitignore
vendored
Normal file
8
.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
build
|
||||||
|
*.zip
|
||||||
|
*.xcodeproj/*.pbxuser
|
||||||
|
*.xcodeproj/*.mode*
|
||||||
|
*.xcodeproj/*.perspective*
|
||||||
|
*.xcodeproj/xcuserdata
|
||||||
|
*.xcodeproj/project.xcworkspace/xcuserdata
|
||||||
|
*.xcworkspace/xcuserdata
|
24
Classes/Framework/MGMDB.h
Normal file
24
Classes/Framework/MGMDB.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
//
|
||||||
|
// MGMDB.h
|
||||||
|
// MGMDB
|
||||||
|
//
|
||||||
|
// Created by Mr. Gecko on 12/27/09.
|
||||||
|
// Copyright (c) 2011 Mr. Gecko's Media (James Coleman). http://mrgeckosmedia.com/
|
||||||
|
//
|
||||||
|
// Permission to use, copy, modify, and/or distribute this software for any purpose
|
||||||
|
// with or without fee is hereby granted, provided that the above copyright notice
|
||||||
|
// and this permission notice appear in all copies.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||||
|
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
// FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
|
||||||
|
// OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||||
|
// DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||||
|
// ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <MGMDB/MGMMyConnection.h>
|
||||||
|
#import <MGMDB/MGMMyResult.h>
|
||||||
|
|
||||||
|
#import <MGMDB/MGMLiteConnection.h>
|
||||||
|
#import <MGMDB/MGMLiteResult.h>
|
57
Classes/Framework/MGMLiteConnection.h
Normal file
57
Classes/Framework/MGMLiteConnection.h
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
//
|
||||||
|
// MGMLiteConnection.h
|
||||||
|
// MGMDB
|
||||||
|
//
|
||||||
|
// Created by Mr. Gecko on 8/13/10.
|
||||||
|
// Copyright (c) 2011 Mr. Gecko's Media (James Coleman). http://mrgeckosmedia.com/
|
||||||
|
//
|
||||||
|
// Permission to use, copy, modify, and/or distribute this software for any purpose
|
||||||
|
// with or without fee is hereby granted, provided that the above copyright notice
|
||||||
|
// and this permission notice appear in all copies.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||||
|
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
// FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
|
||||||
|
// OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||||
|
// DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||||
|
// ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
#import <MGMDB/sqlite3.h>
|
||||||
|
|
||||||
|
#define MGMLiteDebug 0
|
||||||
|
|
||||||
|
@class MGMLiteResult;
|
||||||
|
|
||||||
|
@interface MGMLiteConnection : NSObject {
|
||||||
|
sqlite3 *SQLiteConnection;
|
||||||
|
NSString *path;
|
||||||
|
BOOL isConnected;
|
||||||
|
NSCharacterSet *escapeSet;
|
||||||
|
BOOL logQuery;
|
||||||
|
}
|
||||||
|
+ (id)memoryConnection;
|
||||||
|
+ (id)connectionWithPath:(NSString *)thePath;
|
||||||
|
- (id)initWithPath:(NSString *)thePath;
|
||||||
|
|
||||||
|
- (sqlite3 *)SQLiteConnection;
|
||||||
|
- (NSString *)path;
|
||||||
|
|
||||||
|
- (NSString *)errorMessage;
|
||||||
|
- (int)errorID;
|
||||||
|
|
||||||
|
- (NSString *)escapeData:(NSData *)theData;
|
||||||
|
- (NSString *)escapeString:(NSString *)theString;
|
||||||
|
- (NSString *)quoteObject:(id)theObject;
|
||||||
|
- (NSString *)quoteChar:(const char *)theChar;
|
||||||
|
|
||||||
|
- (BOOL)logQuery;
|
||||||
|
- (void)setLogQuery:(BOOL)shouldLogQuery;
|
||||||
|
- (MGMLiteResult *)query:(NSString *)format, ...;
|
||||||
|
- (MGMLiteResult *)tables;
|
||||||
|
- (MGMLiteResult *)tablesLike:(NSString *)theName;
|
||||||
|
- (MGMLiteResult *)columnsFromTable:(NSString *)theTable;
|
||||||
|
- (int)affectedRows;
|
||||||
|
- (long long int)insertId;
|
||||||
|
@end
|
324
Classes/Framework/MGMLiteConnection.m
Normal file
324
Classes/Framework/MGMLiteConnection.m
Normal file
@ -0,0 +1,324 @@
|
|||||||
|
//
|
||||||
|
// MGMLiteConnection.m
|
||||||
|
// MGMDB
|
||||||
|
//
|
||||||
|
// Created by Mr. Gecko on 8/13/10.
|
||||||
|
// Copyright (c) 2011 Mr. Gecko's Media (James Coleman). http://mrgeckosmedia.com/
|
||||||
|
//
|
||||||
|
// Permission to use, copy, modify, and/or distribute this software for any purpose
|
||||||
|
// with or without fee is hereby granted, provided that the above copyright notice
|
||||||
|
// and this permission notice appear in all copies.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||||
|
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
// FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
|
||||||
|
// OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||||
|
// DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||||
|
// ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "MGMLiteConnection.h"
|
||||||
|
#import "MGMLiteResult.h"
|
||||||
|
|
||||||
|
@implementation MGMLiteConnection
|
||||||
|
+ (id)memoryConnection {
|
||||||
|
return [[[self alloc] initWithPath:@":memory:"] autorelease];
|
||||||
|
}
|
||||||
|
+ (id)connectionWithPath:(NSString *)thePath {
|
||||||
|
return [[[self alloc] initWithPath:thePath] autorelease];
|
||||||
|
}
|
||||||
|
- (id)initWithPath:(NSString *)thePath {
|
||||||
|
if (self = [super init]) {
|
||||||
|
logQuery = NO;
|
||||||
|
path = [thePath copy];
|
||||||
|
int result = SQLITE_INTERNAL;
|
||||||
|
result = sqlite3_open([path UTF8String], &SQLiteConnection);
|
||||||
|
if (result!=SQLITE_OK) {
|
||||||
|
[self release];
|
||||||
|
self = nil;
|
||||||
|
} else {
|
||||||
|
escapeSet = [[NSCharacterSet characterSetWithCharactersInString:@"'"] retain];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
- (void)dealloc {
|
||||||
|
if (SQLiteConnection!=NULL) {
|
||||||
|
int result = sqlite3_close(SQLiteConnection);
|
||||||
|
if (result!=SQLITE_OK)
|
||||||
|
NSLog(@"Unable to close the SQLite Database %@", path);
|
||||||
|
}
|
||||||
|
if (path!=nil)
|
||||||
|
[path release];
|
||||||
|
if (escapeSet!=nil)
|
||||||
|
[escapeSet release];
|
||||||
|
[super dealloc];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (sqlite3 *)SQLiteConnection {
|
||||||
|
return SQLiteConnection;
|
||||||
|
}
|
||||||
|
- (NSString *)path {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *)errorMessage {
|
||||||
|
return [NSString stringWithCString:sqlite3_errmsg(SQLiteConnection) encoding:NSUTF8StringEncoding];
|
||||||
|
}
|
||||||
|
- (int)errorID {
|
||||||
|
return sqlite3_errcode(SQLiteConnection);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *)escapeData:(NSData *)theData {
|
||||||
|
static const char hexdigits[] = "0123456789ABCDEF";
|
||||||
|
const size_t length = [theData length];
|
||||||
|
const char *bytes = [theData bytes];
|
||||||
|
char *stringBuffer = (char *)malloc(length * 2 + 1);
|
||||||
|
char *hexBuffer = stringBuffer;
|
||||||
|
|
||||||
|
for (int i=0; i<length; i++) {
|
||||||
|
*hexBuffer++ = hexdigits[(*bytes >> 4) & 0xF];
|
||||||
|
*hexBuffer++ = hexdigits[*bytes & 0xF];
|
||||||
|
bytes++;
|
||||||
|
}
|
||||||
|
*hexBuffer = '\0';
|
||||||
|
NSString *hex = [NSString stringWithUTF8String:stringBuffer];
|
||||||
|
free(stringBuffer);
|
||||||
|
return hex;
|
||||||
|
}
|
||||||
|
- (NSString *)escapeString:(NSString *)theString {
|
||||||
|
if (theString==nil)
|
||||||
|
return nil;
|
||||||
|
NSRange range = [theString rangeOfCharacterFromSet:escapeSet];
|
||||||
|
NSMutableString *string = [NSMutableString string];
|
||||||
|
if (range.location==NSNotFound) {
|
||||||
|
[string appendString:theString];
|
||||||
|
} else {
|
||||||
|
unsigned long len = [theString length];
|
||||||
|
for (unsigned long i=0; i<len; i++) {
|
||||||
|
unichar character = [theString characterAtIndex:i];
|
||||||
|
switch (character) {
|
||||||
|
case '\'':
|
||||||
|
[string appendString:@"''"];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
CFStringAppendCharacters((CFMutableStringRef)string, &character, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
- (NSString *)quoteObject:(id)theObject {
|
||||||
|
if (theObject==nil || [theObject isKindOfClass:[NSNull class]])
|
||||||
|
return @"NULL";
|
||||||
|
|
||||||
|
if ([theObject isKindOfClass:[NSData class]])
|
||||||
|
return [NSString stringWithFormat:@"X'%@'", [self escapeData:(NSData *)theObject]];
|
||||||
|
if ([theObject isKindOfClass:[NSString class]])
|
||||||
|
return [NSString stringWithFormat:@"'%@'", [self escapeString:(NSString *)theObject]];
|
||||||
|
if ([theObject isKindOfClass:[NSNumber class]])
|
||||||
|
return [NSString stringWithFormat:@"%@", theObject];
|
||||||
|
if ([theObject isKindOfClass:[NSCalendarDate class]])
|
||||||
|
return [NSString stringWithFormat:@"'%@'", [(NSCalendarDate *)theObject descriptionWithCalendarFormat:@"%Y-%m-%d %H:%M:%S"]];
|
||||||
|
|
||||||
|
return [NSString stringWithFormat:@"'%@'", [self escapeString:[theObject description]]];
|
||||||
|
}
|
||||||
|
- (NSString *)quoteChar:(const char *)theChar {
|
||||||
|
NSString *string = [NSString stringWithUTF8String:theChar];
|
||||||
|
return [self quoteObject:string];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)logQuery {
|
||||||
|
return logQuery;
|
||||||
|
}
|
||||||
|
- (void)setLogQuery:(BOOL)shouldLogQuery {
|
||||||
|
logQuery = shouldLogQuery;
|
||||||
|
}
|
||||||
|
- (MGMLiteResult *)query:(NSString *)format, ... {
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, format);
|
||||||
|
if (format==nil)
|
||||||
|
return nil;
|
||||||
|
NSMutableString *query = [NSMutableString string];
|
||||||
|
NSString *currentFormat = format;
|
||||||
|
NSRange range = [currentFormat rangeOfString:@"%"];
|
||||||
|
while (range.location!=NSNotFound) {
|
||||||
|
int offset = 1;
|
||||||
|
[query appendString:[currentFormat substringWithRange:NSMakeRange(0, range.location)]];
|
||||||
|
unichar character = [currentFormat characterAtIndex:range.location+offset];
|
||||||
|
switch (character) {
|
||||||
|
case '@':
|
||||||
|
[query appendString:[self quoteObject:va_arg(ap, id)]];
|
||||||
|
break;
|
||||||
|
case '!':
|
||||||
|
[query appendString:[va_arg(ap, id) description]];
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
[query appendString:[self quoteChar:va_arg(ap, const char *)]];
|
||||||
|
break;
|
||||||
|
case '$':
|
||||||
|
[query appendFormat:@"%s", va_arg(ap, const char *)];
|
||||||
|
break;
|
||||||
|
case '%':
|
||||||
|
[query appendString:@"%"];
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
case 'D':
|
||||||
|
case 'i':
|
||||||
|
[query appendFormat:@"%d", va_arg(ap, int)];
|
||||||
|
break;
|
||||||
|
case 'u':
|
||||||
|
case 'U':
|
||||||
|
[query appendFormat:@"%u", va_arg(ap, unsigned int)];
|
||||||
|
break;
|
||||||
|
case 'h': {
|
||||||
|
offset++;
|
||||||
|
unichar character = [currentFormat characterAtIndex:range.location+offset];
|
||||||
|
if (character=='i')
|
||||||
|
[query appendFormat:@"%hi", va_arg(ap, int)];
|
||||||
|
else if (character=='u')
|
||||||
|
[query appendFormat:@"%hu", va_arg(ap, unsigned int)];
|
||||||
|
else goto invalid;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'q': {
|
||||||
|
offset++;
|
||||||
|
unichar character = [currentFormat characterAtIndex:range.location+offset];
|
||||||
|
if (character=='i')
|
||||||
|
[query appendFormat:@"%qi", va_arg(ap, long long)];
|
||||||
|
else if (character=='u')
|
||||||
|
[query appendFormat:@"%qu", va_arg(ap, unsigned long long)];
|
||||||
|
else if (character=='x')
|
||||||
|
[query appendFormat:@"%qx", va_arg(ap, unsigned long long)];
|
||||||
|
else if (character=='X')
|
||||||
|
[query appendFormat:@"%qX", va_arg(ap, unsigned long long)];
|
||||||
|
else goto invalid;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'x':
|
||||||
|
[query appendFormat:@"%x", va_arg(ap, unsigned int)];
|
||||||
|
break;
|
||||||
|
case 'X':
|
||||||
|
[query appendFormat:@"%X", va_arg(ap, unsigned int)];
|
||||||
|
break;
|
||||||
|
case 'o':
|
||||||
|
case 'O':
|
||||||
|
[query appendFormat:@"%o", va_arg(ap, unsigned int)];
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
[query appendFormat:@"%f", va_arg(ap, double)];
|
||||||
|
break;
|
||||||
|
case 'e':
|
||||||
|
[query appendFormat:@"%e", va_arg(ap, double)];
|
||||||
|
break;
|
||||||
|
case 'E':
|
||||||
|
[query appendFormat:@"%E", va_arg(ap, double)];
|
||||||
|
break;
|
||||||
|
case 'g':
|
||||||
|
[query appendFormat:@"%g", va_arg(ap, double)];
|
||||||
|
break;
|
||||||
|
case 'G':
|
||||||
|
[query appendFormat:@"%G", va_arg(ap, double)];
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
[query appendFormat:@"%c", va_arg(ap, unsigned int)];
|
||||||
|
break;
|
||||||
|
case 'C':
|
||||||
|
[query appendFormat:@"%C", va_arg(ap, int)];
|
||||||
|
break;
|
||||||
|
case 'p':
|
||||||
|
[query appendFormat:@"%p", va_arg(ap, void *)];
|
||||||
|
break;
|
||||||
|
case 'a':
|
||||||
|
[query appendFormat:@"%a", va_arg(ap, double)];
|
||||||
|
break;
|
||||||
|
case 'A':
|
||||||
|
[query appendFormat:@"%A", va_arg(ap, double)];
|
||||||
|
break;
|
||||||
|
case 'F':
|
||||||
|
[query appendFormat:@"%F", va_arg(ap, double)];
|
||||||
|
break;
|
||||||
|
case '.': {
|
||||||
|
NSMutableString *format = [NSMutableString stringWithString:@"%."];
|
||||||
|
NSCharacterSet *set = [NSCharacterSet decimalDigitCharacterSet];
|
||||||
|
offset++;
|
||||||
|
unichar character = [currentFormat characterAtIndex:range.location+offset];
|
||||||
|
while ([set characterIsMember:character]) {
|
||||||
|
CFStringAppendCharacters((CFMutableStringRef)format, &character, 1);
|
||||||
|
offset++;
|
||||||
|
character = [currentFormat characterAtIndex:range.location+offset];
|
||||||
|
}
|
||||||
|
if (character=='f')
|
||||||
|
CFStringAppendCharacters((CFMutableStringRef)format, &character, 1);
|
||||||
|
else goto invalid;
|
||||||
|
[query appendFormat:format, va_arg(ap, double)];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case '0'...'9': {
|
||||||
|
NSMutableString *format = [NSMutableString stringWithString:@"%"];
|
||||||
|
NSCharacterSet *set = [NSCharacterSet decimalDigitCharacterSet];
|
||||||
|
unichar character = [currentFormat characterAtIndex:range.location+offset];
|
||||||
|
while ([set characterIsMember:character]) {
|
||||||
|
CFStringAppendCharacters((CFMutableStringRef)format, &character, 1);
|
||||||
|
offset++;
|
||||||
|
character = [currentFormat characterAtIndex:range.location+offset];
|
||||||
|
}
|
||||||
|
if (character=='x' || character=='X')
|
||||||
|
CFStringAppendCharacters((CFMutableStringRef)format, &character, 1);
|
||||||
|
else goto invalid;
|
||||||
|
[query appendFormat:format, va_arg(ap, unsigned int)];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
goto invalid;
|
||||||
|
}
|
||||||
|
goto good;
|
||||||
|
invalid:
|
||||||
|
NSLog(@"Query: Invalid format.");
|
||||||
|
return nil;
|
||||||
|
good:
|
||||||
|
offset++;
|
||||||
|
currentFormat = [currentFormat substringWithRange:NSMakeRange(range.location+offset, [currentFormat length]-(range.location+offset))];
|
||||||
|
range = [currentFormat rangeOfString:@"%"];
|
||||||
|
}
|
||||||
|
[query appendString:[currentFormat substringWithRange:NSMakeRange(0, [currentFormat length])]];
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
query = [[query copy] autorelease];
|
||||||
|
|
||||||
|
if (logQuery)
|
||||||
|
NSLog(@"Query: %@", query);
|
||||||
|
|
||||||
|
if (query==nil || [query isEqualToString:@""])
|
||||||
|
return nil;
|
||||||
|
sqlite3_stmt *result;
|
||||||
|
int status = sqlite3_prepare(SQLiteConnection, [query UTF8String], -1, &result, NULL);
|
||||||
|
if (status!=SQLITE_OK)
|
||||||
|
return nil;
|
||||||
|
return [MGMLiteResult resultWithConnection:self result:result];
|
||||||
|
}
|
||||||
|
- (MGMLiteResult *)tables {
|
||||||
|
return [self tablesLike:nil];
|
||||||
|
}
|
||||||
|
- (MGMLiteResult *)tablesLike:(NSString *)theName {
|
||||||
|
MGMLiteResult *theResult = nil;
|
||||||
|
|
||||||
|
if (theName==nil || [theName isEqualToString:@""])
|
||||||
|
theResult = [self query:@"SELECT name FROM sqlite_master WHERE type='table'"];
|
||||||
|
else
|
||||||
|
theResult = [self query:@"SELECT name FROM sqlite_master WHERE type='table' AND name LIKE %@", theName];
|
||||||
|
|
||||||
|
return theResult;
|
||||||
|
}
|
||||||
|
- (MGMLiteResult *)columnsFromTable:(NSString *)theTable {
|
||||||
|
return [self query:@"PRAGMA table_info(%@)", theTable];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (int)affectedRows {
|
||||||
|
return sqlite3_changes(SQLiteConnection);
|
||||||
|
}
|
||||||
|
- (long long int)insertId {
|
||||||
|
return sqlite3_last_insert_rowid(SQLiteConnection);
|
||||||
|
}
|
||||||
|
@end
|
49
Classes/Framework/MGMLiteResult.h
Normal file
49
Classes/Framework/MGMLiteResult.h
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
//
|
||||||
|
// MGMLiteResult.h
|
||||||
|
// MGMDB
|
||||||
|
//
|
||||||
|
// Created by Mr. Gecko on 8/13/10.
|
||||||
|
// Copyright (c) 2011 Mr. Gecko's Media (James Coleman). http://mrgeckosmedia.com/
|
||||||
|
//
|
||||||
|
// Permission to use, copy, modify, and/or distribute this software for any purpose
|
||||||
|
// with or without fee is hereby granted, provided that the above copyright notice
|
||||||
|
// and this permission notice appear in all copies.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||||
|
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
// FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
|
||||||
|
// OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||||
|
// DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||||
|
// ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
#import <MGMDB/sqlite3.h>
|
||||||
|
|
||||||
|
@class MGMLiteConnection;
|
||||||
|
|
||||||
|
@interface MGMLiteResult : NSObject {
|
||||||
|
MGMLiteConnection *connection;
|
||||||
|
sqlite3_stmt *result;
|
||||||
|
NSArray *columnNames;
|
||||||
|
int columnCount;
|
||||||
|
}
|
||||||
|
+ (id)resultWithConnection:(MGMLiteConnection *)theConnection result:(sqlite3_stmt *)theResult;
|
||||||
|
- (id)initWithConnection:(MGMLiteConnection *)theConnection result:(sqlite3_stmt *)theResult;
|
||||||
|
|
||||||
|
- (int)dataCount;
|
||||||
|
- (int)columnCount;
|
||||||
|
- (NSString *)columnName:(int)theColumn;
|
||||||
|
- (NSArray *)columnNames;
|
||||||
|
|
||||||
|
- (NSNumber *)integerAtColumn:(int)theColumn;
|
||||||
|
- (NSNumber *)doubleAtColumn:(int)theColumn;
|
||||||
|
- (NSString *)stringAtColumn:(int)theColumn;
|
||||||
|
- (NSData *)dataAtColumn:(int)theColumn;
|
||||||
|
- (id)objectAtColumn:(int)theColumn;
|
||||||
|
|
||||||
|
- (NSArray *)nextRowAsArray;
|
||||||
|
- (NSDictionary *)nextRow;
|
||||||
|
- (int)step;
|
||||||
|
- (int)reset;
|
||||||
|
@end
|
172
Classes/Framework/MGMLiteResult.m
Normal file
172
Classes/Framework/MGMLiteResult.m
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
//
|
||||||
|
// MGMLiteResult.m
|
||||||
|
// MGMDB
|
||||||
|
//
|
||||||
|
// Created by Mr. Gecko on 8/13/10.
|
||||||
|
// Copyright (c) 2011 Mr. Gecko's Media (James Coleman). http://mrgeckosmedia.com/
|
||||||
|
//
|
||||||
|
// Permission to use, copy, modify, and/or distribute this software for any purpose
|
||||||
|
// with or without fee is hereby granted, provided that the above copyright notice
|
||||||
|
// and this permission notice appear in all copies.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||||
|
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
// FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
|
||||||
|
// OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||||
|
// DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||||
|
// ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "MGMLiteResult.h"
|
||||||
|
#import "MGMLiteConnection.h"
|
||||||
|
|
||||||
|
@implementation MGMLiteResult
|
||||||
|
+ (id)resultWithConnection:(MGMLiteConnection *)theConnection result:(sqlite3_stmt *)theResult {
|
||||||
|
return [[[self alloc] initWithConnection:theConnection result:theResult] autorelease];
|
||||||
|
}
|
||||||
|
- (id)initWithConnection:(MGMLiteConnection *)theConnection result:(sqlite3_stmt *)theResult {
|
||||||
|
if (self = [super init]) {
|
||||||
|
connection = [theConnection retain];
|
||||||
|
result = theResult;
|
||||||
|
if (result==NULL) {
|
||||||
|
[self release];
|
||||||
|
self = nil;
|
||||||
|
} else {
|
||||||
|
columnCount = [self columnCount];
|
||||||
|
columnNames = [[self columnNames] retain];
|
||||||
|
int status = [self step];
|
||||||
|
if (status==SQLITE_ROW) {
|
||||||
|
[self reset];
|
||||||
|
} else if (status==SQLITE_DONE) {
|
||||||
|
[self release];
|
||||||
|
self = nil;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
- (void)dealloc {
|
||||||
|
if (connection!=nil)
|
||||||
|
[connection release];
|
||||||
|
if (result!=NULL)
|
||||||
|
sqlite3_finalize(result);
|
||||||
|
if (columnNames!=nil)
|
||||||
|
[columnNames release];
|
||||||
|
[super dealloc];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (int)dataCount {
|
||||||
|
if (result!=NULL)
|
||||||
|
return sqlite3_data_count(result);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
- (int)columnCount {
|
||||||
|
if (result!=NULL)
|
||||||
|
return sqlite3_column_count(result);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
- (NSString *)columnName:(int)theColumn {
|
||||||
|
NSString *name = [NSString stringWithCString:sqlite3_column_name(result, theColumn) encoding:NSUTF8StringEncoding];
|
||||||
|
if (name!=NULL && ![name isEqualToString:@""])
|
||||||
|
return name;
|
||||||
|
return [[NSNumber numberWithInt:theColumn] stringValue];
|
||||||
|
}
|
||||||
|
- (NSArray *)columnNames {
|
||||||
|
columnCount = [self columnCount];
|
||||||
|
NSMutableArray *names = nil;
|
||||||
|
if (result!=NULL) {
|
||||||
|
names = [NSMutableArray array];
|
||||||
|
for (int i=0; i<columnCount; i++) {
|
||||||
|
[names addObject:[self columnName:i]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSNumber *)integerAtColumn:(int)theColumn {
|
||||||
|
return [NSNumber numberWithLongLong:sqlite3_column_int64(result, theColumn)];
|
||||||
|
}
|
||||||
|
- (NSNumber *)doubleAtColumn:(int)theColumn {
|
||||||
|
return [NSNumber numberWithDouble:sqlite3_column_double(result, theColumn)];
|
||||||
|
}
|
||||||
|
- (NSString *)stringAtColumn:(int)theColumn {
|
||||||
|
const char *text = (const char *)sqlite3_column_text(result, theColumn);
|
||||||
|
if (text!=NULL)
|
||||||
|
return [NSString stringWithUTF8String:text];
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
- (NSData *)dataAtColumn:(int)theColumn {
|
||||||
|
const void *bytes = sqlite3_column_blob(result, theColumn);
|
||||||
|
int length = sqlite3_column_bytes(result, theColumn);
|
||||||
|
if (bytes!=NULL && length!=0)
|
||||||
|
return [NSData dataWithBytes:bytes length:length];
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
- (id)objectAtColumn:(int)theColumn {
|
||||||
|
int type = sqlite3_column_type(result, theColumn);
|
||||||
|
id object = nil;
|
||||||
|
switch (type) {
|
||||||
|
case SQLITE_INTEGER:
|
||||||
|
object = [self integerAtColumn:theColumn];
|
||||||
|
break;
|
||||||
|
case SQLITE_FLOAT:
|
||||||
|
object = [self doubleAtColumn:theColumn];
|
||||||
|
break;
|
||||||
|
case SQLITE_TEXT:
|
||||||
|
object = [self stringAtColumn:theColumn];
|
||||||
|
break;
|
||||||
|
case SQLITE_BLOB:
|
||||||
|
object = [self dataAtColumn:theColumn];
|
||||||
|
break;
|
||||||
|
case SQLITE_NULL:
|
||||||
|
object = [NSNull null];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (object==nil) {
|
||||||
|
object = [NSNull null];
|
||||||
|
}
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSArray *)nextRowAsArray {
|
||||||
|
int status = [self step];
|
||||||
|
if (status==SQLITE_ROW) {
|
||||||
|
int dataCount = [self dataCount];
|
||||||
|
if (dataCount>=1) {
|
||||||
|
NSMutableArray *rowArray = [NSMutableArray array];
|
||||||
|
for (int i=0; i<dataCount; i++) {
|
||||||
|
id object = [self objectAtColumn:i];
|
||||||
|
[rowArray addObject:object];
|
||||||
|
}
|
||||||
|
return rowArray;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
- (NSDictionary *)nextRow {
|
||||||
|
int status = [self step];
|
||||||
|
if (status==SQLITE_ROW) {
|
||||||
|
int dataCount = [self dataCount];
|
||||||
|
if (dataCount>=1) {
|
||||||
|
NSMutableDictionary *rowDictionary = [NSMutableDictionary dictionary];
|
||||||
|
for (int i=0; i<dataCount; i++) {
|
||||||
|
id object = [self objectAtColumn:i];
|
||||||
|
[rowDictionary setObject:object forKey:[self columnName:i]];
|
||||||
|
}
|
||||||
|
return rowDictionary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
- (int)step {
|
||||||
|
int status = SQLITE_BUSY;
|
||||||
|
while (status==SQLITE_BUSY) {
|
||||||
|
status = sqlite3_step(result);
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
- (int)reset {
|
||||||
|
return sqlite3_reset(result);
|
||||||
|
}
|
||||||
|
@end
|
80
Classes/Framework/MGMMyConnection.h
Normal file
80
Classes/Framework/MGMMyConnection.h
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
//
|
||||||
|
// MGMMyConnection.h
|
||||||
|
// MGMDB
|
||||||
|
//
|
||||||
|
// Created by Mr. Gecko on 1/20/10.
|
||||||
|
// Copyright (c) 2011 Mr. Gecko's Media (James Coleman). http://mrgeckosmedia.com/
|
||||||
|
//
|
||||||
|
// Permission to use, copy, modify, and/or distribute this software for any purpose
|
||||||
|
// with or without fee is hereby granted, provided that the above copyright notice
|
||||||
|
// and this permission notice appear in all copies.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||||
|
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
// FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
|
||||||
|
// OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||||
|
// DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||||
|
// ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
#import <MGMDB/mysql.h>
|
||||||
|
|
||||||
|
@class MGMMyResult;
|
||||||
|
|
||||||
|
@interface MGMMyConnection : NSObject {
|
||||||
|
MYSQL *MySQLConnection;
|
||||||
|
BOOL isConnected;
|
||||||
|
NSTimeZone *timeZone;
|
||||||
|
NSCharacterSet *escapeSet;
|
||||||
|
BOOL logQuery;
|
||||||
|
}
|
||||||
|
+ (id)connectionWithHost:(NSString *)theHost port:(int)thePort username:(NSString *)theUsername password:(NSString *)thePassword;
|
||||||
|
- (id)initWithHost:(NSString *)theHost port:(int)thePort username:(NSString *)theUsername password:(NSString *)thePassword;
|
||||||
|
+ (id)connectionWithSocket:(NSString *)theSocket username:(NSString *)theUsername password:(NSString *)thePassword;
|
||||||
|
- (id)initWithSocket:(NSString *)theSocket username:(NSString *)theUsername password:(NSString *)thePassword;
|
||||||
|
|
||||||
|
- (BOOL)connectWithHost:(NSString *)theHost port:(int)thePort username:(NSString *)theUsername password:(NSString *)thePassword;
|
||||||
|
- (BOOL)connectWithSocket:(NSString *)theSocket username:(NSString *)theUsername password:(NSString *)thePassword;
|
||||||
|
|
||||||
|
- (MYSQL *)MySQLConnection;
|
||||||
|
- (NSStringEncoding)stringEncodingWithCharSet:(NSString *)theCharSet;
|
||||||
|
|
||||||
|
- (BOOL)isConnected;
|
||||||
|
- (void)disconnect;
|
||||||
|
- (NSString *)errorMessage;
|
||||||
|
- (unsigned int)errorID;
|
||||||
|
|
||||||
|
- (NSString *)escapeData:(NSData *)theData;
|
||||||
|
- (NSString *)escapeString:(NSString *)theString;
|
||||||
|
- (NSString *)quoteObject:(id)theObject;
|
||||||
|
- (NSString *)quoteChar:(const char *)theChar;
|
||||||
|
|
||||||
|
- (MGMMyResult *)query:(NSString *)format, ...;
|
||||||
|
- (my_ulonglong)affectedRows;
|
||||||
|
- (my_ulonglong)insertId;
|
||||||
|
- (BOOL)selectDataBase:(NSString *)theDataBase;
|
||||||
|
- (MGMMyResult *)dataBases;
|
||||||
|
- (MGMMyResult *)dataBasesLike:(NSString *)theName;
|
||||||
|
- (BOOL)createDataBase:(NSString *)theDataBase;
|
||||||
|
- (BOOL)deleteDataBase:(NSString *)theDataBase;
|
||||||
|
- (MGMMyResult *)tables;
|
||||||
|
- (MGMMyResult *)tablesLike:(NSString *)theName;
|
||||||
|
- (MGMMyResult *)tablesFromDataBase:(NSString *)theDataBase;
|
||||||
|
- (MGMMyResult *)tablesFromDataBase:(NSString *)theDataBase like:(NSString *)theName;
|
||||||
|
- (MGMMyResult *)columnsFromTable:(NSString *)theTable;
|
||||||
|
- (MGMMyResult *)columnsFromTable:(NSString *)theTable like:(NSString *)theName;
|
||||||
|
|
||||||
|
- (NSString *)clientInfo;
|
||||||
|
- (NSString *)hostInfo;
|
||||||
|
- (NSString *)serverInfo;
|
||||||
|
- (NSNumber *)protoInfo;
|
||||||
|
- (NSString *)status;
|
||||||
|
- (NSNumber *)threadID;
|
||||||
|
|
||||||
|
- (MGMMyResult *)processes;
|
||||||
|
- (BOOL)killProcess:(unsigned long)processID;
|
||||||
|
|
||||||
|
- (NSTimeZone *)timeZone;
|
||||||
|
- (void)getTimeZone;
|
||||||
|
@end
|
602
Classes/Framework/MGMMyConnection.m
Normal file
602
Classes/Framework/MGMMyConnection.m
Normal file
@ -0,0 +1,602 @@
|
|||||||
|
//
|
||||||
|
// MGMMyConnection.m
|
||||||
|
// MGMDB
|
||||||
|
//
|
||||||
|
// Created by Mr. Gecko on 1/20/10.
|
||||||
|
// Copyright (c) 2011 Mr. Gecko's Media (James Coleman). http://mrgeckosmedia.com/
|
||||||
|
//
|
||||||
|
// Permission to use, copy, modify, and/or distribute this software for any purpose
|
||||||
|
// with or without fee is hereby granted, provided that the above copyright notice
|
||||||
|
// and this permission notice appear in all copies.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||||
|
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
// FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
|
||||||
|
// OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||||
|
// DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||||
|
// ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "MGMMyConnection.h"
|
||||||
|
#import "MGMMyResult.h"
|
||||||
|
|
||||||
|
@implementation MGMMyConnection
|
||||||
|
- (id)init {
|
||||||
|
if (self = [super init]) {
|
||||||
|
timeZone = [[NSTimeZone defaultTimeZone] retain];
|
||||||
|
isConnected = NO;
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
+ (id)connectionWithHost:(NSString *)theHost port:(int)thePort username:(NSString *)theUsername password:(NSString *)thePassword {
|
||||||
|
return [[[self alloc] initWithHost:theHost port:thePort username:theUsername password:thePassword] autorelease];
|
||||||
|
}
|
||||||
|
- (id)initWithHost:(NSString *)theHost port:(int)thePort username:(NSString *)theUsername password:(NSString *)thePassword {
|
||||||
|
if (self = [self init]) {
|
||||||
|
logQuery = NO;
|
||||||
|
[self connectWithHost:theHost port:thePort username:theUsername password:thePassword];
|
||||||
|
escapeSet = [[NSCharacterSet characterSetWithCharactersInString:@"'\"\\"] retain];
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
+ (id)connectionWithSocket:(NSString *)theSocket username:(NSString *)theUsername password:(NSString *)thePassword {
|
||||||
|
return [[[self alloc] initWithSocket:theSocket username:theUsername password:thePassword] autorelease];
|
||||||
|
}
|
||||||
|
- (id)initWithSocket:(NSString *)theSocket username:(NSString *)theUsername password:(NSString *)thePassword {
|
||||||
|
if (self = [self init]) {
|
||||||
|
logQuery = NO;
|
||||||
|
[self connectWithSocket:theSocket username:theUsername password:thePassword];
|
||||||
|
escapeSet = [[NSCharacterSet characterSetWithCharactersInString:@"'\"\\"] retain];
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
- (void)dealloc {
|
||||||
|
if (isConnected) {
|
||||||
|
mysql_close(MySQLConnection);
|
||||||
|
MySQLConnection = NULL;
|
||||||
|
}
|
||||||
|
[timeZone release];
|
||||||
|
[super dealloc];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)connectWithHost:(NSString *)theHost port:(int)thePort username:(NSString *)theUsername password:(NSString *)thePassword {
|
||||||
|
if (isConnected) {
|
||||||
|
isConnected = NO;
|
||||||
|
mysql_close(MySQLConnection);
|
||||||
|
MySQLConnection = NULL;
|
||||||
|
}
|
||||||
|
if (MySQLConnection==NULL) {
|
||||||
|
MySQLConnection = mysql_init(NULL);
|
||||||
|
}
|
||||||
|
if (MySQLConnection!=NULL) {
|
||||||
|
if (thePort==0)
|
||||||
|
thePort = 3306;
|
||||||
|
if (theHost==nil || [theHost isEqualToString:@""])
|
||||||
|
return NO;
|
||||||
|
|
||||||
|
const char *username = NULL;
|
||||||
|
if (theUsername!=nil || [theUsername isEqualToString:@""])
|
||||||
|
username = [theUsername cStringUsingEncoding:NSUTF8StringEncoding];
|
||||||
|
const char *password = NULL;
|
||||||
|
if (thePassword!=nil || [thePassword isEqualToString:@""])
|
||||||
|
password = [thePassword cStringUsingEncoding:NSUTF8StringEncoding];
|
||||||
|
|
||||||
|
void *theRet = mysql_real_connect(MySQLConnection, [theHost cStringUsingEncoding:NSUTF8StringEncoding], username, password, NULL, thePort, MYSQL_UNIX_ADDR, CLIENT_COMPRESS);
|
||||||
|
isConnected = (theRet==MySQLConnection);
|
||||||
|
if (isConnected)
|
||||||
|
[self getTimeZone];
|
||||||
|
}
|
||||||
|
|
||||||
|
return isConnected;
|
||||||
|
}
|
||||||
|
- (BOOL)connectWithSocket:(NSString *)theSocket username:(NSString *)theUsername password:(NSString *)thePassword {
|
||||||
|
if (isConnected) {
|
||||||
|
isConnected = NO;
|
||||||
|
mysql_close(MySQLConnection);
|
||||||
|
MySQLConnection = NULL;
|
||||||
|
}
|
||||||
|
if (MySQLConnection==NULL) {
|
||||||
|
MySQLConnection = mysql_init(NULL);
|
||||||
|
}
|
||||||
|
if (MySQLConnection!=NULL) {
|
||||||
|
const char *socket = NULL;
|
||||||
|
if (theSocket==nil || [theSocket isEqualToString:@""])
|
||||||
|
socket = MYSQL_UNIX_ADDR;
|
||||||
|
else
|
||||||
|
socket = [theSocket cStringUsingEncoding:NSUTF8StringEncoding];
|
||||||
|
|
||||||
|
const char *username = NULL;
|
||||||
|
if (theUsername!=nil || [theUsername isEqualToString:@""])
|
||||||
|
username = [theUsername cStringUsingEncoding:NSUTF8StringEncoding];
|
||||||
|
const char *password = NULL;
|
||||||
|
if (thePassword!=nil || [thePassword isEqualToString:@""])
|
||||||
|
password = [thePassword cStringUsingEncoding:NSUTF8StringEncoding];
|
||||||
|
|
||||||
|
void *theRet = mysql_real_connect(MySQLConnection, NULL, username, password, NULL, 0, socket, CLIENT_COMPRESS);
|
||||||
|
isConnected = (theRet==MySQLConnection);
|
||||||
|
if (isConnected)
|
||||||
|
[self getTimeZone];
|
||||||
|
}
|
||||||
|
|
||||||
|
return isConnected;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (MYSQL *)MySQLConnection {
|
||||||
|
return MySQLConnection;
|
||||||
|
}
|
||||||
|
- (NSStringEncoding)stringEncodingWithCharSet:(NSString *)theCharSet {
|
||||||
|
if ([theCharSet isEqualToString:@"utf8"])
|
||||||
|
return NSUTF8StringEncoding;
|
||||||
|
if ([theCharSet isEqualToString:@"ucs2"])
|
||||||
|
return NSUnicodeStringEncoding;
|
||||||
|
if ([theCharSet isEqualToString:@"ascii"])
|
||||||
|
return NSASCIIStringEncoding;
|
||||||
|
if ([theCharSet isEqualToString:@"latin1"])
|
||||||
|
return NSISOLatin1StringEncoding;
|
||||||
|
if ([theCharSet isEqualToString:@"macroman"])
|
||||||
|
return NSMacOSRomanStringEncoding;
|
||||||
|
if ([theCharSet isEqualToString:@"latin2"])
|
||||||
|
return NSISOLatin2StringEncoding;
|
||||||
|
if ([theCharSet isEqualToString:@"cp1250"])
|
||||||
|
return NSWindowsCP1250StringEncoding;
|
||||||
|
if ([theCharSet isEqualToString:@"win1250"])
|
||||||
|
return NSWindowsCP1250StringEncoding;
|
||||||
|
if ([theCharSet isEqualToString:@"cp1257"])
|
||||||
|
return CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingWindowsBalticRim);
|
||||||
|
if ([theCharSet isEqualToString:@"latin5"])
|
||||||
|
return NSWindowsCP1254StringEncoding;
|
||||||
|
if ([theCharSet isEqualToString:@"greek"])
|
||||||
|
return NSWindowsCP1253StringEncoding;
|
||||||
|
if ([theCharSet isEqualToString:@"win1251ukr"])
|
||||||
|
return NSWindowsCP1251StringEncoding;
|
||||||
|
if ([theCharSet isEqualToString:@"cp1251"])
|
||||||
|
return NSWindowsCP1251StringEncoding;
|
||||||
|
if ([theCharSet isEqualToString:@"koi8_ru"])
|
||||||
|
return CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingKOI8_R);
|
||||||
|
if ([theCharSet isEqualToString:@"koi8_ukr"])
|
||||||
|
return CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingKOI8_R);
|
||||||
|
if ([theCharSet isEqualToString:@"cp1256"])
|
||||||
|
return CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingWindowsArabic);
|
||||||
|
if ([theCharSet isEqualToString:@"hebrew"])
|
||||||
|
return CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingISOLatinHebrew);
|
||||||
|
if ([theCharSet isEqualToString:@"ujis"])
|
||||||
|
return NSJapaneseEUCStringEncoding;
|
||||||
|
if ([theCharSet isEqualToString:@"sjis"])
|
||||||
|
return NSShiftJISStringEncoding;
|
||||||
|
if ([theCharSet isEqualToString:@"big5"])
|
||||||
|
return CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingBig5);
|
||||||
|
if ([theCharSet isEqualToString:@"euc_kr"])
|
||||||
|
return CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingEUC_KR);
|
||||||
|
|
||||||
|
return NSISOLatin1StringEncoding;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)isConnected {
|
||||||
|
return (isConnected ? mysql_ping(MySQLConnection)==0 : NO);
|
||||||
|
}
|
||||||
|
- (void)disconnect {
|
||||||
|
if (isConnected) {
|
||||||
|
mysql_close(MySQLConnection);
|
||||||
|
MySQLConnection = NULL;
|
||||||
|
isConnected = NO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *)errorMessage {
|
||||||
|
if (isConnected)
|
||||||
|
return [NSString stringWithCString:mysql_error(MySQLConnection) encoding:NSUTF8StringEncoding];
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
- (unsigned int)errorID {
|
||||||
|
if (isConnected)
|
||||||
|
return mysql_errno(MySQLConnection);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *)escapeData:(NSData *)theData {
|
||||||
|
static const char hexdigits[] = "0123456789ABCDEF";
|
||||||
|
const size_t length = [theData length];
|
||||||
|
const char *bytes = [theData bytes];
|
||||||
|
char *stringBuffer = (char *)malloc(length * 2 + 1);
|
||||||
|
char *hexBuffer = stringBuffer;
|
||||||
|
|
||||||
|
for (int i=0; i<length; i++) {
|
||||||
|
*hexBuffer++ = hexdigits[(*bytes >> 4) & 0xF];
|
||||||
|
*hexBuffer++ = hexdigits[*bytes & 0xF];
|
||||||
|
bytes++;
|
||||||
|
}
|
||||||
|
*hexBuffer = '\0';
|
||||||
|
NSString *hex = [NSString stringWithUTF8String:stringBuffer];
|
||||||
|
free(stringBuffer);
|
||||||
|
return hex;
|
||||||
|
}
|
||||||
|
- (NSString *)escapeString:(NSString *)theString {
|
||||||
|
if (theString==nil)
|
||||||
|
return nil;
|
||||||
|
NSRange range = [theString rangeOfCharacterFromSet:escapeSet];
|
||||||
|
NSMutableString *string = [NSMutableString string];
|
||||||
|
if (range.location==NSNotFound) {
|
||||||
|
[string appendString:theString];
|
||||||
|
} else {
|
||||||
|
unsigned long len = [theString length];
|
||||||
|
for (unsigned long i=0; i<len; i++) {
|
||||||
|
unichar character = [theString characterAtIndex:i];
|
||||||
|
switch (character) {
|
||||||
|
case '0':
|
||||||
|
[string appendString:@"\\0"];
|
||||||
|
break;
|
||||||
|
case '\'':
|
||||||
|
[string appendString:@"\\'"];
|
||||||
|
break;
|
||||||
|
case '"':
|
||||||
|
[string appendString:@"\\\""];
|
||||||
|
break;
|
||||||
|
case '\\':
|
||||||
|
[string appendString:@"\\\\"];
|
||||||
|
break;
|
||||||
|
case '\n':
|
||||||
|
[string appendString:@"\\n"];
|
||||||
|
break;
|
||||||
|
case '\r':
|
||||||
|
[string appendString:@"\\r"];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (character<0x20) {
|
||||||
|
[string appendFormat:@"\\u%04x", character];
|
||||||
|
} else {
|
||||||
|
CFStringAppendCharacters((CFMutableStringRef)string, &character, 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
- (NSString *)quoteObject:(id)theObject {
|
||||||
|
if (theObject==nil || [theObject isKindOfClass:[NSNull class]])
|
||||||
|
return @"NULL";
|
||||||
|
|
||||||
|
if ([theObject isKindOfClass:[NSData class]])
|
||||||
|
return [NSString stringWithFormat:@"X'%@'", [self escapeData:(NSData *)theObject]];
|
||||||
|
if ([theObject isKindOfClass:[NSString class]])
|
||||||
|
return [NSString stringWithFormat:@"'%@'", [self escapeString:(NSString *)theObject]];
|
||||||
|
if ([theObject isKindOfClass:[NSNumber class]])
|
||||||
|
return [NSString stringWithFormat:@"%@", theObject];
|
||||||
|
if ([theObject isKindOfClass:[NSCalendarDate class]])
|
||||||
|
return [NSString stringWithFormat:@"'%@'", [(NSCalendarDate *)theObject descriptionWithCalendarFormat:@"%Y-%m-%d %H:%M:%S"]];
|
||||||
|
|
||||||
|
return [NSString stringWithFormat:@"'%@'", [self escapeString:[theObject description]]];
|
||||||
|
}
|
||||||
|
- (NSString *)quoteChar:(const char *)theChar {
|
||||||
|
NSString *string = [NSString stringWithUTF8String:theChar];
|
||||||
|
return [self quoteObject:string];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)logQuery {
|
||||||
|
return logQuery;
|
||||||
|
}
|
||||||
|
- (void)setLogQuery:(BOOL)shouldLogQuery {
|
||||||
|
logQuery = shouldLogQuery;
|
||||||
|
}
|
||||||
|
- (MGMMyResult *)query:(NSString *)format, ... {
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, format);
|
||||||
|
if (format==nil)
|
||||||
|
return nil;
|
||||||
|
NSMutableString *query = [NSMutableString string];
|
||||||
|
NSString *currentFormat = format;
|
||||||
|
NSRange range = [currentFormat rangeOfString:@"%"];
|
||||||
|
while (range.location!=NSNotFound) {
|
||||||
|
int offset = 1;
|
||||||
|
[query appendString:[currentFormat substringWithRange:NSMakeRange(0, range.location)]];
|
||||||
|
unichar character = [currentFormat characterAtIndex:range.location+offset];
|
||||||
|
switch (character) {
|
||||||
|
case '@':
|
||||||
|
[query appendString:[self quoteObject:va_arg(ap, id)]];
|
||||||
|
break;
|
||||||
|
case '!':
|
||||||
|
[query appendString:[va_arg(ap, id) description]];
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
[query appendString:[self quoteChar:va_arg(ap, const char *)]];
|
||||||
|
break;
|
||||||
|
case '$':
|
||||||
|
[query appendFormat:@"%s", va_arg(ap, const char *)];
|
||||||
|
break;
|
||||||
|
case '%':
|
||||||
|
[query appendString:@"%"];
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
case 'D':
|
||||||
|
case 'i':
|
||||||
|
[query appendFormat:@"%d", va_arg(ap, int)];
|
||||||
|
break;
|
||||||
|
case 'u':
|
||||||
|
case 'U':
|
||||||
|
[query appendFormat:@"%u", va_arg(ap, unsigned int)];
|
||||||
|
break;
|
||||||
|
case 'h': {
|
||||||
|
offset++;
|
||||||
|
unichar character = [currentFormat characterAtIndex:range.location+offset];
|
||||||
|
if (character=='i')
|
||||||
|
[query appendFormat:@"%hi", va_arg(ap, int)];
|
||||||
|
else if (character=='u')
|
||||||
|
[query appendFormat:@"%hu", va_arg(ap, unsigned int)];
|
||||||
|
else goto invalid;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'q': {
|
||||||
|
offset++;
|
||||||
|
unichar character = [currentFormat characterAtIndex:range.location+offset];
|
||||||
|
if (character=='i')
|
||||||
|
[query appendFormat:@"%qi", va_arg(ap, long long)];
|
||||||
|
else if (character=='u')
|
||||||
|
[query appendFormat:@"%qu", va_arg(ap, unsigned long long)];
|
||||||
|
else if (character=='x')
|
||||||
|
[query appendFormat:@"%qx", va_arg(ap, unsigned long long)];
|
||||||
|
else if (character=='X')
|
||||||
|
[query appendFormat:@"%qX", va_arg(ap, unsigned long long)];
|
||||||
|
else goto invalid;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'x':
|
||||||
|
[query appendFormat:@"%x", va_arg(ap, unsigned int)];
|
||||||
|
break;
|
||||||
|
case 'X':
|
||||||
|
[query appendFormat:@"%X", va_arg(ap, unsigned int)];
|
||||||
|
break;
|
||||||
|
case 'o':
|
||||||
|
case 'O':
|
||||||
|
[query appendFormat:@"%o", va_arg(ap, unsigned int)];
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
[query appendFormat:@"%f", va_arg(ap, double)];
|
||||||
|
break;
|
||||||
|
case 'e':
|
||||||
|
[query appendFormat:@"%e", va_arg(ap, double)];
|
||||||
|
break;
|
||||||
|
case 'E':
|
||||||
|
[query appendFormat:@"%E", va_arg(ap, double)];
|
||||||
|
break;
|
||||||
|
case 'g':
|
||||||
|
[query appendFormat:@"%g", va_arg(ap, double)];
|
||||||
|
break;
|
||||||
|
case 'G':
|
||||||
|
[query appendFormat:@"%G", va_arg(ap, double)];
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
[query appendFormat:@"%c", va_arg(ap, unsigned int)];
|
||||||
|
break;
|
||||||
|
case 'C':
|
||||||
|
[query appendFormat:@"%C", va_arg(ap, int)];
|
||||||
|
break;
|
||||||
|
case 'p':
|
||||||
|
[query appendFormat:@"%p", va_arg(ap, void *)];
|
||||||
|
break;
|
||||||
|
case 'a':
|
||||||
|
[query appendFormat:@"%a", va_arg(ap, double)];
|
||||||
|
break;
|
||||||
|
case 'A':
|
||||||
|
[query appendFormat:@"%A", va_arg(ap, double)];
|
||||||
|
break;
|
||||||
|
case 'F':
|
||||||
|
[query appendFormat:@"%F", va_arg(ap, double)];
|
||||||
|
break;
|
||||||
|
case '.': {
|
||||||
|
NSMutableString *format = [NSMutableString stringWithString:@"%."];
|
||||||
|
NSCharacterSet *set = [NSCharacterSet decimalDigitCharacterSet];
|
||||||
|
offset++;
|
||||||
|
unichar character = [currentFormat characterAtIndex:range.location+offset];
|
||||||
|
while ([set characterIsMember:character]) {
|
||||||
|
CFStringAppendCharacters((CFMutableStringRef)format, &character, 1);
|
||||||
|
offset++;
|
||||||
|
character = [currentFormat characterAtIndex:range.location+offset];
|
||||||
|
}
|
||||||
|
if (character=='f')
|
||||||
|
CFStringAppendCharacters((CFMutableStringRef)format, &character, 1);
|
||||||
|
else goto invalid;
|
||||||
|
[query appendFormat:format, va_arg(ap, double)];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case '0'...'9': {
|
||||||
|
NSMutableString *format = [NSMutableString stringWithString:@"%"];
|
||||||
|
NSCharacterSet *set = [NSCharacterSet decimalDigitCharacterSet];
|
||||||
|
unichar character = [currentFormat characterAtIndex:range.location+offset];
|
||||||
|
while ([set characterIsMember:character]) {
|
||||||
|
CFStringAppendCharacters((CFMutableStringRef)format, &character, 1);
|
||||||
|
offset++;
|
||||||
|
character = [currentFormat characterAtIndex:range.location+offset];
|
||||||
|
}
|
||||||
|
if (character=='x' || character=='X')
|
||||||
|
CFStringAppendCharacters((CFMutableStringRef)format, &character, 1);
|
||||||
|
else goto invalid;
|
||||||
|
[query appendFormat:format, va_arg(ap, unsigned int)];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
goto invalid;
|
||||||
|
}
|
||||||
|
goto good;
|
||||||
|
invalid:
|
||||||
|
NSLog(@"Query: Invalid format.");
|
||||||
|
return nil;
|
||||||
|
good:
|
||||||
|
offset++;
|
||||||
|
currentFormat = [currentFormat substringWithRange:NSMakeRange(range.location+offset, [currentFormat length]-(range.location+offset))];
|
||||||
|
range = [currentFormat rangeOfString:@"%"];
|
||||||
|
}
|
||||||
|
[query appendString:[currentFormat substringWithRange:NSMakeRange(0, [currentFormat length])]];
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
query = [[query copy] autorelease];
|
||||||
|
|
||||||
|
if (logQuery)
|
||||||
|
NSLog(@"Query: %@", query);
|
||||||
|
|
||||||
|
if (query==nil || [query isEqualToString:@""])
|
||||||
|
return nil;
|
||||||
|
if (mysql_query(MySQLConnection, [query cStringUsingEncoding:NSUTF8StringEncoding])!=0)
|
||||||
|
return nil;
|
||||||
|
return [MGMMyResult resultWithConnection:self];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (my_ulonglong)affectedRows {
|
||||||
|
if (isConnected)
|
||||||
|
return mysql_affected_rows(MySQLConnection);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
- (my_ulonglong)insertId {
|
||||||
|
if (isConnected)
|
||||||
|
return mysql_insert_id(MySQLConnection);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)selectDataBase:(NSString *)theDataBase {
|
||||||
|
if (theDataBase==nil || [theDataBase isEqualToString:@""])
|
||||||
|
return NO;
|
||||||
|
|
||||||
|
if (isConnected) {
|
||||||
|
if (mysql_select_db(MySQLConnection, [theDataBase cStringUsingEncoding:NSUTF8StringEncoding])!=0)
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
- (MGMMyResult *)dataBases {
|
||||||
|
return [self dataBasesLike:nil];
|
||||||
|
}
|
||||||
|
- (MGMMyResult *)dataBasesLike:(NSString *)theName {
|
||||||
|
MGMMyResult *theResult = nil;
|
||||||
|
const char *name = NULL;
|
||||||
|
if (theName!=nil && ![theName isEqualToString:@""])
|
||||||
|
name = [theName cStringUsingEncoding:NSUTF8StringEncoding];
|
||||||
|
|
||||||
|
MYSQL_RES *result = mysql_list_dbs(MySQLConnection, name);
|
||||||
|
if (result!=NULL)
|
||||||
|
theResult = [MGMMyResult resultWithConnection:self result:result];
|
||||||
|
|
||||||
|
return theResult;
|
||||||
|
}
|
||||||
|
- (BOOL)createDataBase:(NSString *)theDataBase {
|
||||||
|
if (theDataBase==nil || [theDataBase isEqualToString:@""])
|
||||||
|
return NO;
|
||||||
|
return ([self query:@"CREATE DATABASE %@", theDataBase]!=nil);
|
||||||
|
}
|
||||||
|
- (BOOL)deleteDataBase:(NSString *)theDataBase {
|
||||||
|
if (theDataBase==nil || [theDataBase isEqualToString:@""])
|
||||||
|
return NO;
|
||||||
|
return ([self query:@"DROP DATABASE %@", theDataBase]!=nil);
|
||||||
|
}
|
||||||
|
- (MGMMyResult *)tables {
|
||||||
|
return [self tablesLike:nil];
|
||||||
|
}
|
||||||
|
- (MGMMyResult *)tablesLike:(NSString *)theName {
|
||||||
|
MGMMyResult *theResult = nil;
|
||||||
|
const char *name = NULL;
|
||||||
|
if (theName!=nil && ![theName isEqualToString:@""])
|
||||||
|
name = [theName cStringUsingEncoding:NSUTF8StringEncoding];
|
||||||
|
|
||||||
|
MYSQL_RES *result = mysql_list_tables(MySQLConnection, name);
|
||||||
|
if (result!=NULL)
|
||||||
|
theResult = [MGMMyResult resultWithConnection:self result:result];
|
||||||
|
|
||||||
|
return theResult;
|
||||||
|
}
|
||||||
|
- (MGMMyResult *)tablesFromDataBase:(NSString *)theDataBase {
|
||||||
|
return [self tablesFromDataBase:theDataBase like:nil];
|
||||||
|
}
|
||||||
|
- (MGMMyResult *)tablesFromDataBase:(NSString *)theDataBase like:(NSString *)theName {
|
||||||
|
MGMMyResult *theResult = nil;
|
||||||
|
|
||||||
|
if (theName==nil || [theName isEqualToString:@""])
|
||||||
|
theResult = [self query:@"SHOW TABLES FROM %!", theDataBase];
|
||||||
|
else
|
||||||
|
theResult = [self query:@"SHOW TABLES FROM %! LIKE %@", theDataBase, theName];
|
||||||
|
|
||||||
|
return theResult;
|
||||||
|
}
|
||||||
|
- (MGMMyResult *)columnsFromTable:(NSString *)theTable {
|
||||||
|
return [self columnsFromTable:theTable like:nil];
|
||||||
|
}
|
||||||
|
- (MGMMyResult *)columnsFromTable:(NSString *)theTable like:(NSString *)theName {
|
||||||
|
MGMMyResult *theResult = nil;
|
||||||
|
|
||||||
|
if (theName==nil || [theName isEqualToString:@""])
|
||||||
|
theResult = [self query:@"SHOW COLUMNS FROM %!", theTable];
|
||||||
|
else
|
||||||
|
theResult = [self query:@"SHOW COLUMNS FROM %! LIKE %@", theTable, theName];
|
||||||
|
|
||||||
|
return theResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *)clientInfo {
|
||||||
|
return [NSString stringWithCString:mysql_get_client_info() encoding:NSUTF8StringEncoding];
|
||||||
|
}
|
||||||
|
- (NSString *)hostInfo {
|
||||||
|
return [NSString stringWithCString:mysql_get_host_info(MySQLConnection) encoding:NSUTF8StringEncoding];
|
||||||
|
}
|
||||||
|
- (NSString *)serverInfo {
|
||||||
|
if (isConnected)
|
||||||
|
return [NSString stringWithCString: mysql_get_server_info(MySQLConnection) encoding:NSUTF8StringEncoding];
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
- (NSNumber *)protoInfo {
|
||||||
|
return [NSNumber numberWithUnsignedInt:mysql_get_proto_info(MySQLConnection)];
|
||||||
|
}
|
||||||
|
- (NSString *)status {
|
||||||
|
return [NSString stringWithCString:mysql_stat(MySQLConnection) encoding:NSUTF8StringEncoding];
|
||||||
|
}
|
||||||
|
- (NSNumber *)threadID {
|
||||||
|
return [NSNumber numberWithUnsignedLong:mysql_thread_id(MySQLConnection)];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (MGMMyResult *)processes {
|
||||||
|
MGMMyResult *theResult = nil;
|
||||||
|
|
||||||
|
MYSQL_RES *result = mysql_list_processes(MySQLConnection);
|
||||||
|
if (result!=NULL)
|
||||||
|
theResult = [MGMMyResult resultWithConnection:self result:result];
|
||||||
|
|
||||||
|
return theResult;
|
||||||
|
}
|
||||||
|
- (BOOL)killProcess:(unsigned long)processID {
|
||||||
|
int errorCode = mysql_kill(MySQLConnection, processID);
|
||||||
|
return (errorCode==0 ? YES : NO);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSTimeZone *)timeZone {
|
||||||
|
return timeZone;
|
||||||
|
}
|
||||||
|
- (void)getTimeZone {
|
||||||
|
if ([self isConnected]) {
|
||||||
|
MGMMyResult *timeZoneResult = [self query:@"SHOW VARIABLES LIKE '%%time_zone'"];
|
||||||
|
NSString *systemTimeZone = nil, *myTimeZone = nil;
|
||||||
|
NSArray *row;
|
||||||
|
|
||||||
|
while (row = [timeZoneResult nextRowAsArray]) {
|
||||||
|
if ([[row objectAtIndex:0] isEqualToString:@"system_time_zone"]) {
|
||||||
|
systemTimeZone = [row objectAtIndex:1];
|
||||||
|
} else if ([[row objectAtIndex:0] isEqualToString:@"time_zone"]) {
|
||||||
|
myTimeZone = [row objectAtIndex:1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (myTimeZone==nil || [myTimeZone isEqualToString:@"SYSTEM"]) {
|
||||||
|
if (systemTimeZone==nil) {
|
||||||
|
timeZoneResult = [self query:@"SHOW VARIABLES LIKE 'timezone'"];
|
||||||
|
row = [timeZoneResult nextRowAsArray];
|
||||||
|
if (row!=nil) {
|
||||||
|
myTimeZone = [row objectAtIndex:1];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
myTimeZone = systemTimeZone;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (myTimeZone!=nil) {
|
||||||
|
if (timeZone!=nil) {
|
||||||
|
[timeZone release];
|
||||||
|
timeZone = nil;
|
||||||
|
}
|
||||||
|
timeZone = [[NSTimeZone timeZoneWithName:myTimeZone] retain];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@end
|
43
Classes/Framework/MGMMyResult.h
Normal file
43
Classes/Framework/MGMMyResult.h
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
//
|
||||||
|
// MGMMyResult.h
|
||||||
|
// MGMDB
|
||||||
|
//
|
||||||
|
// Created by Mr. Gecko on 2/13/10.
|
||||||
|
// Copyright (c) 2011 Mr. Gecko's Media (James Coleman). http://mrgeckosmedia.com/
|
||||||
|
//
|
||||||
|
// Permission to use, copy, modify, and/or distribute this software for any purpose
|
||||||
|
// with or without fee is hereby granted, provided that the above copyright notice
|
||||||
|
// and this permission notice appear in all copies.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||||
|
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
// FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
|
||||||
|
// OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||||
|
// DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||||
|
// ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
#import <MGMDB/mysql.h>
|
||||||
|
|
||||||
|
@class MGMMyConnection;
|
||||||
|
|
||||||
|
@interface MGMMyResult : NSObject {
|
||||||
|
MGMMyConnection *connection;
|
||||||
|
MYSQL_RES *result;
|
||||||
|
NSArray *columnNames;
|
||||||
|
unsigned int columnCount;
|
||||||
|
}
|
||||||
|
+ (id)resultWithConnection:(MGMMyConnection *)theConnection;
|
||||||
|
- (id)initWithConnection:(MGMMyConnection *)theConnection;
|
||||||
|
+ (id)resultWithConnection:(MGMMyConnection *)theConnection result:(MYSQL_RES *)theResult;
|
||||||
|
- (id)initWithConnection:(MGMMyConnection *)theConnection result:(MYSQL_RES *)theResult;
|
||||||
|
|
||||||
|
- (my_ulonglong)rowCount;
|
||||||
|
- (unsigned int)columnCount;
|
||||||
|
- (NSArray *)columnNames;
|
||||||
|
|
||||||
|
- (NSArray *)nextRowAsArray;
|
||||||
|
- (NSDictionary *)nextRow;
|
||||||
|
- (void)seekToRow:(my_ulonglong)theRow;
|
||||||
|
@end
|
242
Classes/Framework/MGMMyResult.m
Normal file
242
Classes/Framework/MGMMyResult.m
Normal file
@ -0,0 +1,242 @@
|
|||||||
|
//
|
||||||
|
// MGMMyResult.m
|
||||||
|
// MGMDB
|
||||||
|
//
|
||||||
|
// Created by Mr. Gecko on 2/13/10.
|
||||||
|
// Copyright (c) 2011 Mr. Gecko's Media (James Coleman). http://mrgeckosmedia.com/
|
||||||
|
//
|
||||||
|
// Permission to use, copy, modify, and/or distribute this software for any purpose
|
||||||
|
// with or without fee is hereby granted, provided that the above copyright notice
|
||||||
|
// and this permission notice appear in all copies.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||||
|
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
// FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
|
||||||
|
// OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||||
|
// DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||||
|
// ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "MGMMyResult.h"
|
||||||
|
#import "MGMMyConnection.h"
|
||||||
|
|
||||||
|
@implementation MGMMyResult
|
||||||
|
+ (id)resultWithConnection:(MGMMyConnection *)theConnection {
|
||||||
|
return [[[self alloc] initWithConnection:theConnection] autorelease];
|
||||||
|
}
|
||||||
|
- (id)initWithConnection:(MGMMyConnection *)theConnection {
|
||||||
|
if (self = [super init]) {
|
||||||
|
connection = [theConnection retain];
|
||||||
|
result = mysql_store_result([connection MySQLConnection]);
|
||||||
|
if (result==NULL) {
|
||||||
|
[self release];
|
||||||
|
self = nil;
|
||||||
|
} else {
|
||||||
|
columnCount = [self columnCount];
|
||||||
|
columnNames = [[self columnNames] retain];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
+ (id)resultWithConnection:(MGMMyConnection *)theConnection result:(MYSQL_RES *)theResult {
|
||||||
|
return [[[self alloc] initWithConnection:theConnection result:theResult] autorelease];
|
||||||
|
}
|
||||||
|
- (id)initWithConnection:(MGMMyConnection *)theConnection result:(MYSQL_RES *)theResult {
|
||||||
|
if (self = [super init]) {
|
||||||
|
connection = [theConnection retain];
|
||||||
|
result = theResult;
|
||||||
|
if (result==NULL) {
|
||||||
|
[self release];
|
||||||
|
self = nil;
|
||||||
|
} else {
|
||||||
|
columnCount = [self columnCount];
|
||||||
|
columnNames = [[self columnNames] retain];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
- (void)dealloc {
|
||||||
|
mysql_free_result(result);
|
||||||
|
[columnNames release];
|
||||||
|
[connection release];
|
||||||
|
[super dealloc];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (my_ulonglong)rowCount {
|
||||||
|
if (result!=NULL)
|
||||||
|
return mysql_num_rows(result);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
- (unsigned int)columnCount {
|
||||||
|
if (result!=NULL)
|
||||||
|
return mysql_num_fields(result);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
- (NSArray *)columnNames {
|
||||||
|
columnCount = [self columnCount];
|
||||||
|
NSMutableArray *names = nil;
|
||||||
|
if (result!=NULL) {
|
||||||
|
names = [NSMutableArray array];
|
||||||
|
MYSQL_FIELD *columns = mysql_fetch_fields(result);
|
||||||
|
for (int i=0; i<columnCount; i++) {
|
||||||
|
NSString *name = [NSString stringWithCString:columns[i].name encoding:NSUTF8StringEncoding];
|
||||||
|
if (![name isEqualToString:@""])
|
||||||
|
[names addObject:name];
|
||||||
|
else
|
||||||
|
[names addObject:[[NSNumber numberWithInt:i] stringValue]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id)objectAtColumn:(struct st_mysql_field)theColumn bytes:(char *)theBytes length:(unsigned long)theLength {
|
||||||
|
id object = nil;
|
||||||
|
switch (theColumn.type) {
|
||||||
|
case FIELD_TYPE_TINY:
|
||||||
|
case FIELD_TYPE_SHORT:
|
||||||
|
case FIELD_TYPE_INT24:
|
||||||
|
case FIELD_TYPE_LONG:
|
||||||
|
if (theColumn.flags & UNSIGNED_FLAG)
|
||||||
|
object = [NSNumber numberWithUnsignedLong:strtoul(theBytes, NULL, 0)];
|
||||||
|
else
|
||||||
|
object = [NSNumber numberWithLong:strtol(theBytes, NULL, 0)];
|
||||||
|
break;
|
||||||
|
case FIELD_TYPE_LONGLONG:
|
||||||
|
if (theColumn.flags & UNSIGNED_FLAG)
|
||||||
|
object = [NSNumber numberWithUnsignedLongLong:strtoull(theBytes, NULL, 0)];
|
||||||
|
else
|
||||||
|
object = [NSNumber numberWithLongLong:strtoll(theBytes, NULL, 0)];
|
||||||
|
break;
|
||||||
|
case FIELD_TYPE_DECIMAL:
|
||||||
|
object = [NSDecimalNumber decimalNumberWithString:[NSString stringWithCString:theBytes encoding:NSUTF8StringEncoding]];
|
||||||
|
break;
|
||||||
|
case FIELD_TYPE_FLOAT:
|
||||||
|
object = [NSNumber numberWithFloat:atof(theBytes)];
|
||||||
|
break;
|
||||||
|
case FIELD_TYPE_DOUBLE:
|
||||||
|
object = [NSNumber numberWithDouble:atof(theBytes)];
|
||||||
|
break;
|
||||||
|
case FIELD_TYPE_TIMESTAMP:
|
||||||
|
case FIELD_TYPE_DATETIME: {
|
||||||
|
NSDateFormatter *formatter = [NSDateFormatter new];
|
||||||
|
[formatter setDateFormat:@"yyy-MM-dd HH:mm:ss"];
|
||||||
|
[formatter setTimeZone:[connection timeZone]];
|
||||||
|
object = [formatter dateFromString:[NSString stringWithCString:theBytes encoding:NSUTF8StringEncoding]];
|
||||||
|
[formatter release];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FIELD_TYPE_DATE: {
|
||||||
|
NSDateFormatter *formatter = [NSDateFormatter new];
|
||||||
|
[formatter setDateFormat:@"yyy-MM-dd"];
|
||||||
|
[formatter setTimeZone:[connection timeZone]];
|
||||||
|
object = [formatter dateFromString:[NSString stringWithCString:theBytes encoding:NSUTF8StringEncoding]];
|
||||||
|
[formatter release];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FIELD_TYPE_TIME: {
|
||||||
|
NSDateFormatter *formatter = [NSDateFormatter new];
|
||||||
|
[formatter setDateFormat:@"HH:mm:ss"];
|
||||||
|
[formatter setTimeZone:[connection timeZone]];
|
||||||
|
object = [formatter dateFromString:[NSString stringWithCString:theBytes encoding:NSUTF8StringEncoding]];
|
||||||
|
[formatter release];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FIELD_TYPE_YEAR: {
|
||||||
|
NSDateFormatter *formatter = [NSDateFormatter new];
|
||||||
|
[formatter setDateFormat:@"yyy"];
|
||||||
|
[formatter setTimeZone:[connection timeZone]];
|
||||||
|
object = [formatter dateFromString:[NSString stringWithCString:theBytes encoding:NSUTF8StringEncoding]];
|
||||||
|
[formatter release];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FIELD_TYPE_SET:
|
||||||
|
case FIELD_TYPE_ENUM:
|
||||||
|
case FIELD_TYPE_VAR_STRING:
|
||||||
|
case FIELD_TYPE_STRING:
|
||||||
|
object = [NSString stringWithCString:theBytes encoding:NSUTF8StringEncoding];
|
||||||
|
break;
|
||||||
|
case FIELD_TYPE_NEWDATE:
|
||||||
|
case FIELD_TYPE_TINY_BLOB:
|
||||||
|
case FIELD_TYPE_BLOB:
|
||||||
|
case FIELD_TYPE_MEDIUM_BLOB:
|
||||||
|
case FIELD_TYPE_LONG_BLOB:
|
||||||
|
if (theColumn.flags & BINARY_FLAG)
|
||||||
|
object = [NSData dataWithBytes:theBytes length:theLength];
|
||||||
|
else
|
||||||
|
object = [NSString stringWithCString:theBytes encoding:NSUTF8StringEncoding];
|
||||||
|
break;
|
||||||
|
case FIELD_TYPE_NULL:
|
||||||
|
object = nil;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
object = [NSData dataWithBytes:theBytes length:theLength];
|
||||||
|
NSLog(@"Unknown Type %d for Column %s", theColumn.type, theColumn.name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (object==nil) {
|
||||||
|
object = [NSNull null];
|
||||||
|
}
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSArray *)nextRowAsArray {
|
||||||
|
NSMutableArray *rowArray = nil;
|
||||||
|
|
||||||
|
if (result!=NULL) {
|
||||||
|
rowArray = [NSMutableArray array];
|
||||||
|
MYSQL_ROW row = mysql_fetch_row(result);
|
||||||
|
if (row==NULL)
|
||||||
|
return nil;
|
||||||
|
unsigned long *lengths = mysql_fetch_lengths(result);
|
||||||
|
MYSQL_FIELD *columns = mysql_fetch_fields(result);
|
||||||
|
for (int i=0; i<columnCount; i++) {
|
||||||
|
id rowObject;
|
||||||
|
if (row[i]==NULL) {
|
||||||
|
rowObject = [NSNull null];
|
||||||
|
} else {
|
||||||
|
char *rowBytes = calloc(sizeof(char),lengths[i]+1);
|
||||||
|
memcpy(rowBytes, row[i], lengths[i]);
|
||||||
|
rowBytes[lengths[i]] = '\0';
|
||||||
|
rowObject = [self objectAtColumn:columns[i] bytes:rowBytes length:lengths[i]];
|
||||||
|
free(rowBytes);
|
||||||
|
}
|
||||||
|
[rowArray addObject:rowObject];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rowArray;
|
||||||
|
}
|
||||||
|
- (NSDictionary *)nextRow {
|
||||||
|
NSMutableDictionary *rowDictionary = nil;
|
||||||
|
|
||||||
|
if (result!=NULL) {
|
||||||
|
rowDictionary = [NSMutableDictionary dictionary];
|
||||||
|
MYSQL_ROW row = mysql_fetch_row(result);
|
||||||
|
if (row==NULL)
|
||||||
|
return nil;
|
||||||
|
unsigned long *lengths = mysql_fetch_lengths(result);
|
||||||
|
MYSQL_FIELD *columns = mysql_fetch_fields(result);
|
||||||
|
for (int i=0; i<columnCount; i++) {
|
||||||
|
id rowObject;
|
||||||
|
if (row[i]==NULL) {
|
||||||
|
rowObject = [NSNull null];
|
||||||
|
} else {
|
||||||
|
char *rowBytes = calloc(sizeof(char),lengths[i]+1);
|
||||||
|
memcpy(rowBytes, row[i], lengths[i]);
|
||||||
|
rowBytes[lengths[i]] = '\0';
|
||||||
|
rowObject = [self objectAtColumn:columns[i] bytes:rowBytes length:lengths[i]];
|
||||||
|
free(rowBytes);
|
||||||
|
}
|
||||||
|
[rowDictionary setObject:rowObject forKey:[columnNames objectAtIndex:i]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rowDictionary;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)seekToRow:(my_ulonglong)theRow {
|
||||||
|
theRow = (theRow>[self rowCount] ? [self rowCount]-1 : theRow);
|
||||||
|
mysql_data_seek(result, theRow);
|
||||||
|
}
|
||||||
|
@end
|
27
Classes/Test/MGMController.h
Normal file
27
Classes/Test/MGMController.h
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
//
|
||||||
|
// MGMController.h
|
||||||
|
// MGMDB
|
||||||
|
//
|
||||||
|
// Created by Mr. Gecko on 2/12/10.
|
||||||
|
// Copyright (c) 2011 Mr. Gecko's Media (James Coleman). http://mrgeckosmedia.com/
|
||||||
|
//
|
||||||
|
// Permission to use, copy, modify, and/or distribute this software for any purpose
|
||||||
|
// with or without fee is hereby granted, provided that the above copyright notice
|
||||||
|
// and this permission notice appear in all copies.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||||
|
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
// FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
|
||||||
|
// OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||||
|
// DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||||
|
// ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
|
@interface MGMController : NSObject {
|
||||||
|
IBOutlet NSWindow *mainWindow;
|
||||||
|
IBOutlet NSTextView *debugLog;
|
||||||
|
}
|
||||||
|
- (void)debug:(NSString *)format, ...;
|
||||||
|
@end
|
104
Classes/Test/MGMController.m
Normal file
104
Classes/Test/MGMController.m
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
//
|
||||||
|
// MGMController.m
|
||||||
|
// MGMDB
|
||||||
|
//
|
||||||
|
// Created by Mr. Gecko on 2/12/10.
|
||||||
|
// Copyright (c) 2011 Mr. Gecko's Media (James Coleman). http://mrgeckosmedia.com/
|
||||||
|
//
|
||||||
|
// Permission to use, copy, modify, and/or distribute this software for any purpose
|
||||||
|
// with or without fee is hereby granted, provided that the above copyright notice
|
||||||
|
// and this permission notice appear in all copies.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||||
|
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
// FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
|
||||||
|
// OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||||
|
// DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||||
|
// ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "MGMController.h"
|
||||||
|
#import "MGMDB.h"
|
||||||
|
#import <AddressBook/AddressBook.h>
|
||||||
|
|
||||||
|
@implementation MGMController
|
||||||
|
- (void)awakeFromNib {
|
||||||
|
[self debug:@"Connecting to MySQL.\n"];
|
||||||
|
MGMMyConnection *myConnection = [MGMMyConnection connectionWithHost:@"127.0.0.1" port:0 username:@"test" password:@"test"];
|
||||||
|
if ([myConnection isConnected]) {
|
||||||
|
[self debug:@"Connected... Selecting test database.\n"];
|
||||||
|
if ([myConnection selectDataBase:@"test"]) {
|
||||||
|
[self debug:@"Successful... Adding row to test table.\n"];
|
||||||
|
[myConnection query:@"INSERT INTO `test` (`name`,`value`) VALUES (%@,%@)", @"test", @"This is a test of the database. If it doesn't work, we'll know after this."];
|
||||||
|
if ([myConnection errorID]==noErr) {
|
||||||
|
[self debug:@"Successful... Selecting row to see if it returns correct value.\n"];
|
||||||
|
MGMMyResult *result = [myConnection query:@"SELECT * FROM `test` WHERE `name`=%@", @"test"];
|
||||||
|
if (result!=nil) {
|
||||||
|
NSDictionary *data = [result nextRow];
|
||||||
|
if (data!=nil)
|
||||||
|
[self debug:@"Successful... The value returned was %@\n", data];
|
||||||
|
else
|
||||||
|
[self debug:@"The result was null, something is wrong here...\n"];
|
||||||
|
[myConnection query:@"DELETE FROM `test` WHERE `name`=%@", @"test"];
|
||||||
|
} else {
|
||||||
|
[self debug:@"Unable to select row: %@\n", [myConnection errorMessage]];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
[self debug:@"Unable to add to table: %@\n", [myConnection errorMessage]];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
[self debug:@"Unable to select database: %@\n", [myConnection errorMessage]];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
[self debug:@"Unable to connect to database: %@\n", [myConnection errorMessage]];
|
||||||
|
}
|
||||||
|
|
||||||
|
[self debug:@"\n"];
|
||||||
|
[self debug:@"Opening SQLite Database.\n"];
|
||||||
|
MGMLiteConnection *liteConnection = [MGMLiteConnection connectionWithPath:[@"~/Desktop/MGMTest.db" stringByExpandingTildeInPath]];
|
||||||
|
if (liteConnection!=nil) {
|
||||||
|
[self debug:@"Successful... Creating test table.\n"];
|
||||||
|
[liteConnection query:@"CREATE TABLE `test` (`name` TEXT, `value` TEXT)"];
|
||||||
|
if ([liteConnection errorID]==noErr) {
|
||||||
|
[self debug:@"Successful... Adding row to test table.\n"];
|
||||||
|
[liteConnection query:@"INSERT INTO `test` (`name`,`value`) VALUES (%@,%@)", @"test", @"This is a test of the database. If it doesn't work, we'll know after this."];
|
||||||
|
if ([liteConnection errorID]==noErr) {
|
||||||
|
[self debug:@"Successful... Selecting row to see if it returns correct value.\n"];
|
||||||
|
MGMLiteResult *result = [liteConnection query:@"SELECT * FROM `test` WHERE `name`=%@", @"test"];
|
||||||
|
if (result!=nil) {
|
||||||
|
NSDictionary *data = [result nextRow];
|
||||||
|
if (data!=nil)
|
||||||
|
[self debug:@"Successful... The value returned was %@\n", data];
|
||||||
|
else
|
||||||
|
[self debug:@"The result was null, something is wrong here...\n"];
|
||||||
|
} else {
|
||||||
|
[self debug:@"Unable to select row: %@\n", [myConnection errorMessage]];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
[self debug:@"Unable to add to table: %@\n", [myConnection errorMessage]];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
[self debug:@"Unable to create table: %@\n", [liteConnection errorMessage]];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
[self debug:@"Unable to open database.\n"];
|
||||||
|
}
|
||||||
|
[[NSFileManager defaultManager] removeFileAtPath:[@"~/Desktop/MGMTest.db" stringByExpandingTildeInPath] handler:0];
|
||||||
|
}
|
||||||
|
- (void)dealloc {
|
||||||
|
[super dealloc];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)debug:(NSString *)format, ... {
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, format);
|
||||||
|
if (format==nil)
|
||||||
|
return;
|
||||||
|
NSString *info = [[NSString alloc] initWithFormat:format arguments:ap];
|
||||||
|
va_end(ap);
|
||||||
|
NSLog(@"%@", info);
|
||||||
|
[debugLog insertText:info];
|
||||||
|
[debugLog display];
|
||||||
|
[info release];
|
||||||
|
}
|
||||||
|
@end
|
7
License.txt
Normal file
7
License.txt
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
ISC License (ISCL)
|
||||||
|
|
||||||
|
Copyright (c) 2011 Mr. Gecko's Media (James Coleman). http://mrgeckosmedia.com/
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
1
LicenseMySQL.txt
Normal file
1
LicenseMySQL.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
MySQL is under both the MySQL FLOSS Licenses and GNU GPL Licenses, both which can be found under the MySQL directory as COPYING and EXCEPTIONS-CLIENT.
|
7
LicenseSQLite.txt
Normal file
7
LicenseSQLite.txt
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
2001 September 15
|
||||||
|
|
||||||
|
The author disclaims copyright to this source code. In place of a legal notice, here is a blessing:
|
||||||
|
|
||||||
|
May you do good and not evil.
|
||||||
|
May you find forgiveness for yourself and forgive others.
|
||||||
|
May you share freely, never taking more than you give.
|
1278
MGMDB.xcodeproj/project.pbxproj
Normal file
1278
MGMDB.xcodeproj/project.pbxproj
Normal file
File diff suppressed because it is too large
Load Diff
352
MySQL/COPYING
Normal file
352
MySQL/COPYING
Normal file
@ -0,0 +1,352 @@
|
|||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 2, June 1991
|
||||||
|
|
||||||
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||||
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
========
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your freedom
|
||||||
|
to share and change it. By contrast, the GNU General Public License is
|
||||||
|
intended to guarantee your freedom to share and change free
|
||||||
|
software--to make sure the software is free for all its users. This
|
||||||
|
General Public License applies to most of the Free Software
|
||||||
|
Foundation's software and to any other program whose authors commit to
|
||||||
|
using it. (Some other Free Software Foundation software is covered by
|
||||||
|
the GNU Library General Public License instead.) You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not price.
|
||||||
|
Our General Public Licenses are designed to make sure that you have
|
||||||
|
the freedom to distribute copies of free software (and charge for this
|
||||||
|
service if you wish), that you receive source code or can get it if you
|
||||||
|
want it, that you can change the software or use pieces of it in new
|
||||||
|
free programs; and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid anyone
|
||||||
|
to deny you these rights or to ask you to surrender the rights. These
|
||||||
|
restrictions translate to certain responsibilities for you if you
|
||||||
|
distribute copies of the software, or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether gratis
|
||||||
|
or for a fee, you must give the recipients all the rights that you
|
||||||
|
have. You must make sure that they, too, receive or can get the source
|
||||||
|
code. And you must show them these terms so they know their rights.
|
||||||
|
|
||||||
|
We protect your rights with two steps: (1) copyright the software, and
|
||||||
|
(2) offer you this license which gives you legal permission to copy,
|
||||||
|
distribute and/or modify the software.
|
||||||
|
|
||||||
|
Also, for each author's protection and ours, we want to make certain
|
||||||
|
that everyone understands that there is no warranty for this free
|
||||||
|
software. If the software is modified by someone else and passed on, we
|
||||||
|
want its recipients to know that what they have is not the original, so
|
||||||
|
that any problems introduced by others will not reflect on the original
|
||||||
|
authors' reputations.
|
||||||
|
|
||||||
|
Finally, any free program is threatened constantly by software patents.
|
||||||
|
We wish to avoid the danger that redistributors of a free program will
|
||||||
|
individually obtain patent licenses, in effect making the program
|
||||||
|
proprietary. To prevent this, we have made it clear that any patent
|
||||||
|
must be licensed for everyone's free use or not licensed at all.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
0. This License applies to any program or other work which contains a
|
||||||
|
notice placed by the copyright holder saying it may be distributed
|
||||||
|
under the terms of this General Public License. The "Program",
|
||||||
|
below, refers to any such program or work, and a "work based on
|
||||||
|
the Program" means either the Program or any derivative work under
|
||||||
|
copyright law: that is to say, a work containing the Program or a
|
||||||
|
portion of it, either verbatim or with modifications and/or
|
||||||
|
translated into another language. (Hereinafter, translation is
|
||||||
|
included without limitation in the term "modification".) Each
|
||||||
|
licensee is addressed as "you".
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are
|
||||||
|
not covered by this License; they are outside its scope. The act
|
||||||
|
of running the Program is not restricted, and the output from the
|
||||||
|
Program is covered only if its contents constitute a work based on
|
||||||
|
the Program (independent of having been made by running the
|
||||||
|
Program). Whether that is true depends on what the Program does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Program's
|
||||||
|
source code as you receive it, in any medium, provided that you
|
||||||
|
conspicuously and appropriately publish on each copy an appropriate
|
||||||
|
copyright notice and disclaimer of warranty; keep intact all the
|
||||||
|
notices that refer to this License and to the absence of any
|
||||||
|
warranty; and give any other recipients of the Program a copy of
|
||||||
|
this License along with the Program.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy,
|
||||||
|
and you may at your option offer warranty protection in exchange
|
||||||
|
for a fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Program or any portion
|
||||||
|
of it, thus forming a work based on the Program, and copy and
|
||||||
|
distribute such modifications or work under the terms of Section 1
|
||||||
|
above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a. You must cause the modified files to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
b. You must cause any work that you distribute or publish, that
|
||||||
|
in whole or in part contains or is derived from the Program
|
||||||
|
or any part thereof, to be licensed as a whole at no charge
|
||||||
|
to all third parties under the terms of this License.
|
||||||
|
|
||||||
|
c. If the modified program normally reads commands interactively
|
||||||
|
when run, you must cause it, when started running for such
|
||||||
|
interactive use in the most ordinary way, to print or display
|
||||||
|
an announcement including an appropriate copyright notice and
|
||||||
|
a notice that there is no warranty (or else, saying that you
|
||||||
|
provide a warranty) and that users may redistribute the
|
||||||
|
program under these conditions, and telling the user how to
|
||||||
|
view a copy of this License. (Exception: if the Program
|
||||||
|
itself is interactive but does not normally print such an
|
||||||
|
announcement, your work based on the Program is not required
|
||||||
|
to print an announcement.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the
|
||||||
|
Program, and can be reasonably considered independent and separate
|
||||||
|
works in themselves, then this License, and its terms, do not
|
||||||
|
apply to those sections when you distribute them as separate
|
||||||
|
works. But when you distribute the same sections as part of a
|
||||||
|
whole which is a work based on the Program, the distribution of
|
||||||
|
the whole must be on the terms of this License, whose permissions
|
||||||
|
for other licensees extend to the entire whole, and thus to each
|
||||||
|
and every part regardless of who wrote it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or
|
||||||
|
contest your rights to work written entirely by you; rather, the
|
||||||
|
intent is to exercise the right to control the distribution of
|
||||||
|
derivative or collective works based on the Program.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the
|
||||||
|
Program with the Program (or with a work based on the Program) on
|
||||||
|
a volume of a storage or distribution medium does not bring the
|
||||||
|
other work under the scope of this License.
|
||||||
|
|
||||||
|
3. You may copy and distribute the Program (or a work based on it,
|
||||||
|
under Section 2) in object code or executable form under the terms
|
||||||
|
of Sections 1 and 2 above provided that you also do one of the
|
||||||
|
following:
|
||||||
|
|
||||||
|
a. Accompany it with the complete corresponding machine-readable
|
||||||
|
source code, which must be distributed under the terms of
|
||||||
|
Sections 1 and 2 above on a medium customarily used for
|
||||||
|
software interchange; or,
|
||||||
|
|
||||||
|
b. Accompany it with a written offer, valid for at least three
|
||||||
|
years, to give any third-party, for a charge no more than your
|
||||||
|
cost of physically performing source distribution, a complete
|
||||||
|
machine-readable copy of the corresponding source code, to be
|
||||||
|
distributed under the terms of Sections 1 and 2 above on a
|
||||||
|
medium customarily used for software interchange; or,
|
||||||
|
|
||||||
|
c. Accompany it with the information you received as to the offer
|
||||||
|
to distribute corresponding source code. (This alternative is
|
||||||
|
allowed only for noncommercial distribution and only if you
|
||||||
|
received the program in object code or executable form with
|
||||||
|
such an offer, in accord with Subsection b above.)
|
||||||
|
|
||||||
|
The source code for a work means the preferred form of the work for
|
||||||
|
making modifications to it. For an executable work, complete
|
||||||
|
source code means all the source code for all modules it contains,
|
||||||
|
plus any associated interface definition files, plus the scripts
|
||||||
|
used to control compilation and installation of the executable.
|
||||||
|
However, as a special exception, the source code distributed need
|
||||||
|
not include anything that is normally distributed (in either
|
||||||
|
source or binary form) with the major components (compiler,
|
||||||
|
kernel, and so on) of the operating system on which the executable
|
||||||
|
runs, unless that component itself accompanies the executable.
|
||||||
|
|
||||||
|
If distribution of executable or object code is made by offering
|
||||||
|
access to copy from a designated place, then offering equivalent
|
||||||
|
access to copy the source code from the same place counts as
|
||||||
|
distribution of the source code, even though third parties are not
|
||||||
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
4. You may not copy, modify, sublicense, or distribute the Program
|
||||||
|
except as expressly provided under this License. Any attempt
|
||||||
|
otherwise to copy, modify, sublicense or distribute the Program is
|
||||||
|
void, and will automatically terminate your rights under this
|
||||||
|
License. However, parties who have received copies, or rights,
|
||||||
|
from you under this License will not have their licenses
|
||||||
|
terminated so long as such parties remain in full compliance.
|
||||||
|
|
||||||
|
5. You are not required to accept this License, since you have not
|
||||||
|
signed it. However, nothing else grants you permission to modify
|
||||||
|
or distribute the Program or its derivative works. These actions
|
||||||
|
are prohibited by law if you do not accept this License.
|
||||||
|
Therefore, by modifying or distributing the Program (or any work
|
||||||
|
based on the Program), you indicate your acceptance of this
|
||||||
|
License to do so, and all its terms and conditions for copying,
|
||||||
|
distributing or modifying the Program or works based on it.
|
||||||
|
|
||||||
|
6. Each time you redistribute the Program (or any work based on the
|
||||||
|
Program), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute or modify the Program
|
||||||
|
subject to these terms and conditions. You may not impose any
|
||||||
|
further restrictions on the recipients' exercise of the rights
|
||||||
|
granted herein. You are not responsible for enforcing compliance
|
||||||
|
by third parties to this License.
|
||||||
|
|
||||||
|
7. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent
|
||||||
|
issues), conditions are imposed on you (whether by court order,
|
||||||
|
agreement or otherwise) that contradict the conditions of this
|
||||||
|
License, they do not excuse you from the conditions of this
|
||||||
|
License. If you cannot distribute so as to satisfy simultaneously
|
||||||
|
your obligations under this License and any other pertinent
|
||||||
|
obligations, then as a consequence you may not distribute the
|
||||||
|
Program at all. For example, if a patent license would not permit
|
||||||
|
royalty-free redistribution of the Program by all those who
|
||||||
|
receive copies directly or indirectly through you, then the only
|
||||||
|
way you could satisfy both it and this License would be to refrain
|
||||||
|
entirely from distribution of the Program.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable
|
||||||
|
under any particular circumstance, the balance of the section is
|
||||||
|
intended to apply and the section as a whole is intended to apply
|
||||||
|
in other circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of
|
||||||
|
any such claims; this section has the sole purpose of protecting
|
||||||
|
the integrity of the free software distribution system, which is
|
||||||
|
implemented by public license practices. Many people have made
|
||||||
|
generous contributions to the wide range of software distributed
|
||||||
|
through that system in reliance on consistent application of that
|
||||||
|
system; it is up to the author/donor to decide if he or she is
|
||||||
|
willing to distribute software through any other system and a
|
||||||
|
licensee cannot impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed
|
||||||
|
to be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
8. If the distribution and/or use of the Program is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces,
|
||||||
|
the original copyright holder who places the Program under this
|
||||||
|
License may add an explicit geographical distribution limitation
|
||||||
|
excluding those countries, so that distribution is permitted only
|
||||||
|
in or among countries not thus excluded. In such case, this
|
||||||
|
License incorporates the limitation as if written in the body of
|
||||||
|
this License.
|
||||||
|
|
||||||
|
9. The Free Software Foundation may publish revised and/or new
|
||||||
|
versions of the General Public License from time to time. Such
|
||||||
|
new versions will be similar in spirit to the present version, but
|
||||||
|
may differ in detail to address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the
|
||||||
|
Program specifies a version number of this License which applies
|
||||||
|
to it and "any later version", you have the option of following
|
||||||
|
the terms and conditions either of that version or of any later
|
||||||
|
version published by the Free Software Foundation. If the Program
|
||||||
|
does not specify a version number of this License, you may choose
|
||||||
|
any version ever published by the Free Software Foundation.
|
||||||
|
|
||||||
|
10. If you wish to incorporate parts of the Program into other free
|
||||||
|
programs whose distribution conditions are different, write to the
|
||||||
|
author to ask for permission. For software which is copyrighted
|
||||||
|
by the Free Software Foundation, write to the Free Software
|
||||||
|
Foundation; we sometimes make exceptions for this. Our decision
|
||||||
|
will be guided by the two goals of preserving the free status of
|
||||||
|
all derivatives of our free software and of promoting the sharing
|
||||||
|
and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||||
|
WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE
|
||||||
|
LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||||
|
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT
|
||||||
|
WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE
|
||||||
|
QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||||
|
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY
|
||||||
|
SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||||
|
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY
|
||||||
|
MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE
|
||||||
|
LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL,
|
||||||
|
INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
|
||||||
|
INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||||
|
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU
|
||||||
|
OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY
|
||||||
|
OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN
|
||||||
|
ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
=============================================
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these
|
||||||
|
terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest to
|
||||||
|
attach them to the start of each source file to most effectively convey
|
||||||
|
the exclusion of warranty; and each file should have at least the
|
||||||
|
"copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
ONE LINE TO GIVE THE PROGRAM'S NAME AND A BRIEF IDEA OF WHAT IT DOES.
|
||||||
|
Copyright (C) YYYY NAME OF AUTHOR
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If the program is interactive, make it output a short notice like this
|
||||||
|
when it starts in an interactive mode:
|
||||||
|
|
||||||
|
Gnomovision version 69, Copyright (C) 19YY NAME OF AUTHOR
|
||||||
|
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
|
This is free software, and you are welcome to redistribute it
|
||||||
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the
|
||||||
|
appropriate parts of the General Public License. Of course, the
|
||||||
|
commands you use may be called something other than `show w' and `show
|
||||||
|
c'; they could even be mouse-clicks or menu items--whatever suits your
|
||||||
|
program.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||||
|
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||||
|
|
||||||
|
SIGNATURE OF TY COON, 1 April 1989
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
|
This General Public License does not permit incorporating your program
|
||||||
|
into proprietary programs. If your program is a subroutine library,
|
||||||
|
you may consider it more useful to permit linking proprietary
|
||||||
|
applications with the library. If this is what you want to do, use the
|
||||||
|
GNU Library General Public License instead of this License.
|
||||||
|
|
119
MySQL/EXCEPTIONS-CLIENT
Normal file
119
MySQL/EXCEPTIONS-CLIENT
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
MySQL FLOSS License Exception
|
||||||
|
|
||||||
|
The MySQL AB Exception for Free/Libre and Open Source
|
||||||
|
Software-only Applications Using MySQL Client Libraries (the
|
||||||
|
"FLOSS Exception").
|
||||||
|
|
||||||
|
Version 0.6, 7 March 2007
|
||||||
|
|
||||||
|
Exception Intent
|
||||||
|
|
||||||
|
We want specified Free/Libre and Open Source Software (``FLOSS'')
|
||||||
|
applications to be able to use specified GPL-licensed MySQL client
|
||||||
|
libraries (the ``Program'') despite the fact that not all FLOSS
|
||||||
|
licenses are compatible with version 2 of the GNU General Public
|
||||||
|
License (the ``GPL'').
|
||||||
|
|
||||||
|
Legal Terms and Conditions
|
||||||
|
|
||||||
|
As a special exception to the terms and conditions of version 2.0
|
||||||
|
of the GPL:
|
||||||
|
|
||||||
|
1. You are free to distribute a Derivative Work that is formed
|
||||||
|
entirely from the Program and one or more works (each, a
|
||||||
|
"FLOSS Work") licensed under one or more of the licenses
|
||||||
|
listed below in section 1, as long as:
|
||||||
|
a. You obey the GPL in all respects for the Program and the
|
||||||
|
Derivative Work, except for identifiable sections of the
|
||||||
|
Derivative Work which are not derived from the Program,
|
||||||
|
and which can reasonably be considered independent and
|
||||||
|
separate works in themselves,
|
||||||
|
b. all identifiable sections of the Derivative Work which
|
||||||
|
are not derived from the Program, and which can
|
||||||
|
reasonably be considered independent and separate works
|
||||||
|
in themselves,
|
||||||
|
i. are distributed subject to one of the FLOSS licenses
|
||||||
|
listed below, and
|
||||||
|
ii. the object code or executable form of those sections
|
||||||
|
are accompanied by the complete corresponding
|
||||||
|
machine-readable source code for those sections on
|
||||||
|
the same medium and under the same FLOSS license as
|
||||||
|
the corresponding object code or executable forms of
|
||||||
|
those sections, and
|
||||||
|
c. any works which are aggregated with the Program or with a
|
||||||
|
Derivative Work on a volume of a storage or distribution
|
||||||
|
medium in accordance with the GPL, can reasonably be
|
||||||
|
considered independent and separate works in themselves
|
||||||
|
which are not derivatives of either the Program, a
|
||||||
|
Derivative Work or a FLOSS Work.
|
||||||
|
If the above conditions are not met, then the Program may only
|
||||||
|
be copied, modified, distributed or used under the terms and
|
||||||
|
conditions of the GPL or another valid licensing option from
|
||||||
|
MySQL AB.
|
||||||
|
|
||||||
|
2. FLOSS License List
|
||||||
|
|
||||||
|
License name Version(s)/Copyright Date
|
||||||
|
Academic Free License 2.0
|
||||||
|
Apache Software License 1.0/1.1/2.0
|
||||||
|
Apple Public Source License 2.0
|
||||||
|
Artistic license From Perl 5.8.0
|
||||||
|
BSD license "July 22 1999"
|
||||||
|
Common Development and Distribution License (CDDL) 1.0
|
||||||
|
Common Public License 1.0
|
||||||
|
Eclipse Public License 1.0
|
||||||
|
GNU Library or "Lesser" General Public License (LGPL) 2.0/2.1
|
||||||
|
Jabber Open Source License 1.0
|
||||||
|
MIT license (As listed in file MIT-License.txt) ---
|
||||||
|
Mozilla Public License (MPL) 1.0/1.1
|
||||||
|
Open Software License 2.0
|
||||||
|
OpenSSL license (with original SSLeay license) "2003" ("1998")
|
||||||
|
PHP License 3.0
|
||||||
|
Python license (CNRI Python License) ---
|
||||||
|
Python Software Foundation License 2.1.1
|
||||||
|
Sleepycat License "1999"
|
||||||
|
University of Illinois/NCSA Open Source License ---
|
||||||
|
W3C License "2001"
|
||||||
|
X11 License "2001"
|
||||||
|
Zlib/libpng License ---
|
||||||
|
Zope Public License 2.0
|
||||||
|
|
||||||
|
Due to the many variants of some of the above licenses, we
|
||||||
|
require that any version follow the 2003 version of the Free
|
||||||
|
Software Foundation's Free Software Definition
|
||||||
|
(http://www.gnu.org/philosophy/free-sw.html) or version 1.9 of
|
||||||
|
the Open Source Definition by the Open Source Initiative
|
||||||
|
(http://www.opensource.org/docs/definition.php).
|
||||||
|
|
||||||
|
3. Definitions
|
||||||
|
|
||||||
|
a. Terms used, but not defined, herein shall have the
|
||||||
|
meaning provided in the GPL.
|
||||||
|
b. Derivative Work means a derivative work under copyright
|
||||||
|
law.
|
||||||
|
|
||||||
|
4. Applicability: This FLOSS Exception applies to all Programs
|
||||||
|
that contain a notice placed by MySQL AB saying that the
|
||||||
|
Program may be distributed under the terms of this FLOSS
|
||||||
|
Exception. If you create or distribute a work which is a
|
||||||
|
Derivative Work of both the Program and any other work
|
||||||
|
licensed under the GPL, then this FLOSS Exception is not
|
||||||
|
available for that work; thus, you must remove the FLOSS
|
||||||
|
Exception notice from that work and comply with the GPL in all
|
||||||
|
respects, including by retaining all GPL notices. You may
|
||||||
|
choose to redistribute a copy of the Program exclusively under
|
||||||
|
the terms of the GPL by removing the FLOSS Exception notice
|
||||||
|
from that copy of the Program, provided that the copy has
|
||||||
|
never been modified by you or any third party.
|
||||||
|
|
||||||
|
Appendix A. Qualified Libraries and Packages
|
||||||
|
|
||||||
|
The following is a non-exhaustive list of libraries and packages
|
||||||
|
which are covered by the FLOSS License Exception. Please note that
|
||||||
|
this appendix is provided merely as an additional service to
|
||||||
|
specific FLOSS projects wishing to simplify licensing information
|
||||||
|
for their users. Compliance with one of the licenses noted under
|
||||||
|
the "FLOSS license list" section remains a prerequisite.
|
||||||
|
|
||||||
|
Package Name Qualifying License and Version
|
||||||
|
Apache Portable Runtime (APR) Apache Software License 2.0
|
384
MySQL/array.c
Normal file
384
MySQL/array.c
Normal file
@ -0,0 +1,384 @@
|
|||||||
|
/* Copyright (C) 2000 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
/* Handling of arrays that can grow dynamicly. */
|
||||||
|
|
||||||
|
#include "mysys_priv.h"
|
||||||
|
#include "m_string.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
Initiate dynamic array
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
init_dynamic_array2()
|
||||||
|
array Pointer to an array
|
||||||
|
element_size Size of element
|
||||||
|
init_buffer Initial buffer pointer
|
||||||
|
init_alloc Number of initial elements
|
||||||
|
alloc_increment Increment for adding new elements
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
init_dynamic_array() initiates array and allocate space for
|
||||||
|
init_alloc eilements.
|
||||||
|
Array is usable even if space allocation failed, hence, the
|
||||||
|
function never returns TRUE.
|
||||||
|
Static buffers must begin immediately after the array structure.
|
||||||
|
|
||||||
|
RETURN VALUE
|
||||||
|
FALSE Ok
|
||||||
|
*/
|
||||||
|
|
||||||
|
my_bool init_dynamic_array2(DYNAMIC_ARRAY *array, uint element_size,
|
||||||
|
void *init_buffer, uint init_alloc,
|
||||||
|
uint alloc_increment CALLER_INFO_PROTO)
|
||||||
|
{
|
||||||
|
DBUG_ENTER("init_dynamic_array");
|
||||||
|
if (!alloc_increment)
|
||||||
|
{
|
||||||
|
alloc_increment=max((8192-MALLOC_OVERHEAD)/element_size,16);
|
||||||
|
if (init_alloc > 8 && alloc_increment > init_alloc * 2)
|
||||||
|
alloc_increment=init_alloc*2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!init_alloc)
|
||||||
|
{
|
||||||
|
init_alloc=alloc_increment;
|
||||||
|
init_buffer= 0;
|
||||||
|
}
|
||||||
|
array->elements=0;
|
||||||
|
array->max_element=init_alloc;
|
||||||
|
array->alloc_increment=alloc_increment;
|
||||||
|
array->size_of_element=element_size;
|
||||||
|
if ((array->buffer= init_buffer))
|
||||||
|
DBUG_RETURN(FALSE);
|
||||||
|
/*
|
||||||
|
Since the dynamic array is usable even if allocation fails here malloc
|
||||||
|
should not throw an error
|
||||||
|
*/
|
||||||
|
if (!(array->buffer= (uchar*) my_malloc_ci(element_size*init_alloc, MYF(0))))
|
||||||
|
array->max_element=0;
|
||||||
|
DBUG_RETURN(FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
my_bool init_dynamic_array(DYNAMIC_ARRAY *array, uint element_size,
|
||||||
|
uint init_alloc,
|
||||||
|
uint alloc_increment CALLER_INFO_PROTO)
|
||||||
|
{
|
||||||
|
/* placeholder to preserve ABI */
|
||||||
|
return my_init_dynamic_array_ci(array, element_size, init_alloc,
|
||||||
|
alloc_increment);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
Insert element at the end of array. Allocate memory if needed.
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
insert_dynamic()
|
||||||
|
array
|
||||||
|
element
|
||||||
|
|
||||||
|
RETURN VALUE
|
||||||
|
TRUE Insert failed
|
||||||
|
FALSE Ok
|
||||||
|
*/
|
||||||
|
|
||||||
|
my_bool insert_dynamic(DYNAMIC_ARRAY *array, uchar* element)
|
||||||
|
{
|
||||||
|
uchar* buffer;
|
||||||
|
if (array->elements == array->max_element)
|
||||||
|
{ /* Call only when nessesary */
|
||||||
|
if (!(buffer=alloc_dynamic(array)))
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
buffer=array->buffer+(array->elements * array->size_of_element);
|
||||||
|
array->elements++;
|
||||||
|
}
|
||||||
|
memcpy(buffer,element,(size_t) array->size_of_element);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Alloc space for next element(s)
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
alloc_dynamic()
|
||||||
|
array
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
alloc_dynamic() checks if there is empty space for at least
|
||||||
|
one element if not tries to allocate space for alloc_increment
|
||||||
|
elements at the end of array.
|
||||||
|
|
||||||
|
RETURN VALUE
|
||||||
|
pointer Pointer to empty space for element
|
||||||
|
0 Error
|
||||||
|
*/
|
||||||
|
|
||||||
|
uchar *alloc_dynamic(DYNAMIC_ARRAY *array)
|
||||||
|
{
|
||||||
|
if (array->elements == array->max_element)
|
||||||
|
{
|
||||||
|
char *new_ptr;
|
||||||
|
if (array->buffer == (uchar *)(array + 1))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
In this senerio, the buffer is statically preallocated,
|
||||||
|
so we have to create an all-new malloc since we overflowed
|
||||||
|
*/
|
||||||
|
if (!(new_ptr= (char *) my_malloc((array->max_element+
|
||||||
|
array->alloc_increment) *
|
||||||
|
array->size_of_element,
|
||||||
|
MYF(MY_WME))))
|
||||||
|
return 0;
|
||||||
|
memcpy(new_ptr, array->buffer,
|
||||||
|
array->elements * array->size_of_element);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (!(new_ptr=(char*) my_realloc(array->buffer,(array->max_element+
|
||||||
|
array->alloc_increment)*
|
||||||
|
array->size_of_element,
|
||||||
|
MYF(MY_WME | MY_ALLOW_ZERO_PTR))))
|
||||||
|
return 0;
|
||||||
|
array->buffer= (uchar*) new_ptr;
|
||||||
|
array->max_element+=array->alloc_increment;
|
||||||
|
}
|
||||||
|
return array->buffer+(array->elements++ * array->size_of_element);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Pop last element from array.
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
pop_dynamic()
|
||||||
|
array
|
||||||
|
|
||||||
|
RETURN VALUE
|
||||||
|
pointer Ok
|
||||||
|
0 Array is empty
|
||||||
|
*/
|
||||||
|
|
||||||
|
uchar *pop_dynamic(DYNAMIC_ARRAY *array)
|
||||||
|
{
|
||||||
|
if (array->elements)
|
||||||
|
return array->buffer+(--array->elements * array->size_of_element);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Replace element in array with given element and index
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
set_dynamic()
|
||||||
|
array
|
||||||
|
element Element to be inserted
|
||||||
|
idx Index where element is to be inserted
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
set_dynamic() replaces element in array.
|
||||||
|
If idx > max_element insert new element. Allocate memory if needed.
|
||||||
|
|
||||||
|
RETURN VALUE
|
||||||
|
TRUE Idx was out of range and allocation of new memory failed
|
||||||
|
FALSE Ok
|
||||||
|
*/
|
||||||
|
|
||||||
|
my_bool set_dynamic(DYNAMIC_ARRAY *array, uchar* element, uint idx)
|
||||||
|
{
|
||||||
|
if (idx >= array->elements)
|
||||||
|
{
|
||||||
|
if (idx >= array->max_element && allocate_dynamic(array, idx))
|
||||||
|
return TRUE;
|
||||||
|
bzero((uchar*) (array->buffer+array->elements*array->size_of_element),
|
||||||
|
(idx - array->elements)*array->size_of_element);
|
||||||
|
array->elements=idx+1;
|
||||||
|
}
|
||||||
|
memcpy(array->buffer+(idx * array->size_of_element),element,
|
||||||
|
(size_t) array->size_of_element);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Ensure that dynamic array has enough elements
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
allocate_dynamic()
|
||||||
|
array
|
||||||
|
max_elements Numbers of elements that is needed
|
||||||
|
|
||||||
|
NOTES
|
||||||
|
Any new allocated element are NOT initialized
|
||||||
|
|
||||||
|
RETURN VALUE
|
||||||
|
FALSE Ok
|
||||||
|
TRUE Allocation of new memory failed
|
||||||
|
*/
|
||||||
|
|
||||||
|
my_bool allocate_dynamic(DYNAMIC_ARRAY *array, uint max_elements)
|
||||||
|
{
|
||||||
|
if (max_elements >= array->max_element)
|
||||||
|
{
|
||||||
|
uint size;
|
||||||
|
uchar *new_ptr;
|
||||||
|
size= (max_elements + array->alloc_increment)/array->alloc_increment;
|
||||||
|
size*= array->alloc_increment;
|
||||||
|
if (array->buffer == (uchar *)(array + 1))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
In this senerio, the buffer is statically preallocated,
|
||||||
|
so we have to create an all-new malloc since we overflowed
|
||||||
|
*/
|
||||||
|
if (!(new_ptr= (uchar *) my_malloc(size *
|
||||||
|
array->size_of_element,
|
||||||
|
MYF(MY_WME))))
|
||||||
|
return 0;
|
||||||
|
memcpy(new_ptr, array->buffer,
|
||||||
|
array->elements * array->size_of_element);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
|
||||||
|
|
||||||
|
if (!(new_ptr= (uchar*) my_realloc(array->buffer,size*
|
||||||
|
array->size_of_element,
|
||||||
|
MYF(MY_WME | MY_ALLOW_ZERO_PTR))))
|
||||||
|
return TRUE;
|
||||||
|
array->buffer= new_ptr;
|
||||||
|
array->max_element= size;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Get an element from array by given index
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
get_dynamic()
|
||||||
|
array
|
||||||
|
uchar* Element to be returned. If idx > elements contain zeroes.
|
||||||
|
idx Index of element wanted.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void get_dynamic(DYNAMIC_ARRAY *array, uchar* element, uint idx)
|
||||||
|
{
|
||||||
|
if (idx >= array->elements)
|
||||||
|
{
|
||||||
|
DBUG_PRINT("warning",("To big array idx: %d, array size is %d",
|
||||||
|
idx,array->elements));
|
||||||
|
bzero(element,array->size_of_element);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
memcpy(element,array->buffer+idx*array->size_of_element,
|
||||||
|
(size_t) array->size_of_element);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Empty array by freeing all memory
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
delete_dynamic()
|
||||||
|
array Array to be deleted
|
||||||
|
*/
|
||||||
|
|
||||||
|
void delete_dynamic(DYNAMIC_ARRAY *array)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Just mark as empty if we are using a static buffer
|
||||||
|
*/
|
||||||
|
if (array->buffer == (uchar *)(array + 1))
|
||||||
|
array->elements= 0;
|
||||||
|
else
|
||||||
|
if (array->buffer)
|
||||||
|
{
|
||||||
|
my_free(array->buffer,MYF(MY_WME));
|
||||||
|
array->buffer=0;
|
||||||
|
array->elements=array->max_element=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Delete element by given index
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
delete_dynamic_element()
|
||||||
|
array
|
||||||
|
idx Index of element to be deleted
|
||||||
|
*/
|
||||||
|
|
||||||
|
void delete_dynamic_element(DYNAMIC_ARRAY *array, uint idx)
|
||||||
|
{
|
||||||
|
char *ptr= (char*) array->buffer+array->size_of_element*idx;
|
||||||
|
array->elements--;
|
||||||
|
memmove(ptr,ptr+array->size_of_element,
|
||||||
|
(array->elements-idx)*array->size_of_element);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Free unused memory
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
freeze_size()
|
||||||
|
array Array to be freed
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
void freeze_size(DYNAMIC_ARRAY *array)
|
||||||
|
{
|
||||||
|
uint elements=max(array->elements,1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Do nothing if we are using a static buffer
|
||||||
|
*/
|
||||||
|
if (array->buffer == (uchar *)(array + 1))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (array->buffer && array->max_element != elements)
|
||||||
|
{
|
||||||
|
array->buffer=(uchar*) my_realloc(array->buffer,
|
||||||
|
elements*array->size_of_element,
|
||||||
|
MYF(MY_WME));
|
||||||
|
array->max_element=elements;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Get the index of a dynamic element
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
get_index_dynamic()
|
||||||
|
array Array
|
||||||
|
element Whose element index
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
int get_index_dynamic(DYNAMIC_ARRAY *array, uchar* element)
|
||||||
|
{
|
||||||
|
size_t ret;
|
||||||
|
if (array->buffer > element)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
ret= (element - array->buffer) / array->size_of_element;
|
||||||
|
if (ret > array->elements)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
}
|
38
MySQL/bchange.c
Normal file
38
MySQL/bchange.c
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
/* Copyright (C) 2000 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
/* File : bchange.c
|
||||||
|
Author : Michael widenius
|
||||||
|
Updated: 1987-03-20
|
||||||
|
Defines: bchange()
|
||||||
|
|
||||||
|
bchange(dst, old_length, src, new_length, tot_length)
|
||||||
|
replaces old_length characters at dst to new_length characters from
|
||||||
|
src in a buffer with tot_length bytes.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <my_global.h>
|
||||||
|
#include "m_string.h"
|
||||||
|
|
||||||
|
void bchange(register uchar *dst, size_t old_length, register const uchar *src,
|
||||||
|
size_t new_length, size_t tot_length)
|
||||||
|
{
|
||||||
|
size_t rest=tot_length-old_length;
|
||||||
|
if (old_length < new_length)
|
||||||
|
bmove_upp(dst+rest+new_length,dst+tot_length,rest);
|
||||||
|
else
|
||||||
|
bmove(dst+new_length,dst+old_length,rest);
|
||||||
|
memcpy(dst,src,new_length);
|
||||||
|
}
|
66
MySQL/bcmp.c
Normal file
66
MySQL/bcmp.c
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
/* Copyright (C) 2000 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
/*
|
||||||
|
bcmp(s1, s2, len) returns 0 if the "len" bytes starting at "s1" are
|
||||||
|
identical to the "len" bytes starting at "s2", non-zero if they are
|
||||||
|
different.
|
||||||
|
Now only used with purify because purify gives wrong warnings when
|
||||||
|
comparing a shorter string with bcmp.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <my_global.h>
|
||||||
|
#include "m_string.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_purify
|
||||||
|
#undef bcmp
|
||||||
|
#undef HAVE_BCMP
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(bcmp) && !defined(HAVE_BCMP)
|
||||||
|
|
||||||
|
#if defined(MC68000) && defined(DS90)
|
||||||
|
|
||||||
|
int bcmp(s1,s2, len)
|
||||||
|
const char *s1;
|
||||||
|
const char *s2;
|
||||||
|
uint len; /* 0 <= len <= 65535 */
|
||||||
|
{
|
||||||
|
asm(" movl 12(a7),d0 ");
|
||||||
|
asm(" subqw #1,d0 ");
|
||||||
|
asm(" blt .L5 ");
|
||||||
|
asm(" movl 4(a7),a1 ");
|
||||||
|
asm(" movl 8(a7),a0 ");
|
||||||
|
asm(".L4: cmpmb (a0)+,(a1)+ ");
|
||||||
|
asm(" dbne d0,.L4 ");
|
||||||
|
asm(".L5: addqw #1,d0 ");
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#ifndef HAVE_purify
|
||||||
|
size_t bcmp(register const uchar *s1,register const uchar *s2,
|
||||||
|
register size_t len)
|
||||||
|
#else
|
||||||
|
size_t my_bcmp(register const uchar *s1,register const uchar *s2,
|
||||||
|
register size_t len)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
while (len-- != 0 && *s1++ == *s2++) ;
|
||||||
|
return len+1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif /* BSD_FUNCS */
|
80
MySQL/bmove.c
Normal file
80
MySQL/bmove.c
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
/* Copyright (C) 2002 MySQL AB
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Library General Public
|
||||||
|
License as published by the Free Software Foundation; version 2
|
||||||
|
of the License.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Library General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Library General Public
|
||||||
|
License along with this library; if not, write to the Free
|
||||||
|
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||||
|
MA 02111-1307, USA */
|
||||||
|
|
||||||
|
/* File : bmove.c
|
||||||
|
Author : Richard A. O'Keefe.
|
||||||
|
Michael Widenius; ifdef MC68000
|
||||||
|
Updated: 23 April 1984
|
||||||
|
Defines: bmove()
|
||||||
|
|
||||||
|
bmove(dst, src, len) moves exactly "len" bytes from the source "src"
|
||||||
|
to the destination "dst". It does not check for NUL characters as
|
||||||
|
strncpy() and strnmov() do. Thus if your C compiler doesn't support
|
||||||
|
structure assignment, you can simulate it with
|
||||||
|
bmove(&to, &from, sizeof from);
|
||||||
|
The standard 4.2bsd routine for this purpose is bcopy. But as bcopy
|
||||||
|
has its first two arguments the other way around you may find this a
|
||||||
|
bit easier to get right.
|
||||||
|
No value is returned.
|
||||||
|
|
||||||
|
Note: the "b" routines are there to exploit certain VAX order codes,
|
||||||
|
but the MOVC3 instruction will only move 65535 characters. The asm
|
||||||
|
code is presented for your interest and amusement.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <my_global.h>
|
||||||
|
#include "m_string.h"
|
||||||
|
|
||||||
|
#if !defined(HAVE_BMOVE) && !defined(bmove)
|
||||||
|
|
||||||
|
#if VaxAsm
|
||||||
|
|
||||||
|
void bmove(dst, src, len)
|
||||||
|
char *dst, *src;
|
||||||
|
uint len;
|
||||||
|
{
|
||||||
|
asm("movc3 12(ap),*8(ap),*4(ap)");
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
#if defined(MC68000) && defined(DS90)
|
||||||
|
|
||||||
|
void bmove(dst, src, len)
|
||||||
|
char *dst,*src;
|
||||||
|
uint len; /* 0 <= len <= 65535 */
|
||||||
|
{
|
||||||
|
asm(" movl 12(a7),d0 ");
|
||||||
|
asm(" subql #1,d0 ");
|
||||||
|
asm(" blt .L5 ");
|
||||||
|
asm(" movl 4(a7),a1 ");
|
||||||
|
asm(" movl 8(a7),a0 ");
|
||||||
|
asm(".L4: movb (a0)+,(a1)+ ");
|
||||||
|
asm(" dbf d0,.L4 ");
|
||||||
|
asm(".L5: ");
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
|
||||||
|
void bmove(dst, src, len)
|
||||||
|
register char *dst;
|
||||||
|
register const char *src;
|
||||||
|
register uint len;
|
||||||
|
{
|
||||||
|
while (len-- != 0) *dst++ = *src++;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
50
MySQL/bmove_upp.c
Normal file
50
MySQL/bmove_upp.c
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/* Copyright (C) 2000 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
/* File : bmove.c
|
||||||
|
Author : Michael widenius
|
||||||
|
Updated: 1987-03-20
|
||||||
|
Defines: bmove_upp()
|
||||||
|
|
||||||
|
bmove_upp(dst, src, len) moves exactly "len" bytes from the source
|
||||||
|
"src-len" to the destination "dst-len" counting downwards.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <my_global.h>
|
||||||
|
#include "m_string.h"
|
||||||
|
|
||||||
|
#if defined(MC68000) && defined(DS90)
|
||||||
|
|
||||||
|
/* 0 <= len <= 65535 */
|
||||||
|
void bmove_upp(byte *dst, const byte *src,uint len)
|
||||||
|
{
|
||||||
|
asm(" movl 12(a7),d0 ");
|
||||||
|
asm(" subql #1,d0 ");
|
||||||
|
asm(" blt .L5 ");
|
||||||
|
asm(" movl 4(a7),a1 ");
|
||||||
|
asm(" movl 8(a7),a0 ");
|
||||||
|
asm(".L4: movb -(a0),-(a1) ");
|
||||||
|
asm(" dbf d0,.L4 ");
|
||||||
|
asm(".L5: ");
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
|
||||||
|
void bmove_upp(register uchar *dst, register const uchar *src,
|
||||||
|
register size_t len)
|
||||||
|
{
|
||||||
|
while (len-- != 0) *--dst = *--src;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
197
MySQL/charset-def.c
Normal file
197
MySQL/charset-def.c
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
/* Copyright (C) 2000 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
#include "mysys_priv.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
Include all compiled character sets into the client
|
||||||
|
If a client don't want to use all of them, he can define his own
|
||||||
|
init_compiled_charsets() that only adds those that he wants
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_UCA_COLLATIONS
|
||||||
|
|
||||||
|
#ifdef HAVE_CHARSET_ucs2
|
||||||
|
extern CHARSET_INFO my_charset_ucs2_icelandic_uca_ci;
|
||||||
|
extern CHARSET_INFO my_charset_ucs2_latvian_uca_ci;
|
||||||
|
extern CHARSET_INFO my_charset_ucs2_romanian_uca_ci;
|
||||||
|
extern CHARSET_INFO my_charset_ucs2_slovenian_uca_ci;
|
||||||
|
extern CHARSET_INFO my_charset_ucs2_polish_uca_ci;
|
||||||
|
extern CHARSET_INFO my_charset_ucs2_estonian_uca_ci;
|
||||||
|
extern CHARSET_INFO my_charset_ucs2_spanish_uca_ci;
|
||||||
|
extern CHARSET_INFO my_charset_ucs2_swedish_uca_ci;
|
||||||
|
extern CHARSET_INFO my_charset_ucs2_turkish_uca_ci;
|
||||||
|
extern CHARSET_INFO my_charset_ucs2_czech_uca_ci;
|
||||||
|
extern CHARSET_INFO my_charset_ucs2_danish_uca_ci;
|
||||||
|
extern CHARSET_INFO my_charset_ucs2_lithuanian_uca_ci;
|
||||||
|
extern CHARSET_INFO my_charset_ucs2_slovak_uca_ci;
|
||||||
|
extern CHARSET_INFO my_charset_ucs2_spanish2_uca_ci;
|
||||||
|
extern CHARSET_INFO my_charset_ucs2_roman_uca_ci;
|
||||||
|
extern CHARSET_INFO my_charset_ucs2_persian_uca_ci;
|
||||||
|
extern CHARSET_INFO my_charset_ucs2_esperanto_uca_ci;
|
||||||
|
extern CHARSET_INFO my_charset_ucs2_hungarian_uca_ci;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_CHARSET_utf8
|
||||||
|
extern CHARSET_INFO my_charset_utf8_icelandic_uca_ci;
|
||||||
|
extern CHARSET_INFO my_charset_utf8_latvian_uca_ci;
|
||||||
|
extern CHARSET_INFO my_charset_utf8_romanian_uca_ci;
|
||||||
|
extern CHARSET_INFO my_charset_utf8_slovenian_uca_ci;
|
||||||
|
extern CHARSET_INFO my_charset_utf8_polish_uca_ci;
|
||||||
|
extern CHARSET_INFO my_charset_utf8_estonian_uca_ci;
|
||||||
|
extern CHARSET_INFO my_charset_utf8_spanish_uca_ci;
|
||||||
|
extern CHARSET_INFO my_charset_utf8_swedish_uca_ci;
|
||||||
|
extern CHARSET_INFO my_charset_utf8_turkish_uca_ci;
|
||||||
|
extern CHARSET_INFO my_charset_utf8_czech_uca_ci;
|
||||||
|
extern CHARSET_INFO my_charset_utf8_danish_uca_ci;
|
||||||
|
extern CHARSET_INFO my_charset_utf8_lithuanian_uca_ci;
|
||||||
|
extern CHARSET_INFO my_charset_utf8_slovak_uca_ci;
|
||||||
|
extern CHARSET_INFO my_charset_utf8_spanish2_uca_ci;
|
||||||
|
extern CHARSET_INFO my_charset_utf8_roman_uca_ci;
|
||||||
|
extern CHARSET_INFO my_charset_utf8_persian_uca_ci;
|
||||||
|
extern CHARSET_INFO my_charset_utf8_esperanto_uca_ci;
|
||||||
|
extern CHARSET_INFO my_charset_utf8_hungarian_uca_ci;
|
||||||
|
#ifdef HAVE_UTF8_GENERAL_CS
|
||||||
|
extern CHARSET_INFO my_charset_utf8_general_cs;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* HAVE_UCA_COLLATIONS */
|
||||||
|
|
||||||
|
my_bool init_compiled_charsets(myf flags __attribute__((unused)))
|
||||||
|
{
|
||||||
|
CHARSET_INFO *cs;
|
||||||
|
|
||||||
|
add_compiled_collation(&my_charset_bin);
|
||||||
|
add_compiled_collation(&my_charset_filename);
|
||||||
|
|
||||||
|
add_compiled_collation(&my_charset_latin1);
|
||||||
|
add_compiled_collation(&my_charset_latin1_bin);
|
||||||
|
add_compiled_collation(&my_charset_latin1_german2_ci);
|
||||||
|
|
||||||
|
#ifdef HAVE_CHARSET_big5
|
||||||
|
add_compiled_collation(&my_charset_big5_chinese_ci);
|
||||||
|
add_compiled_collation(&my_charset_big5_bin);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_CHARSET_cp1250
|
||||||
|
add_compiled_collation(&my_charset_cp1250_czech_ci);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_CHARSET_cp932
|
||||||
|
add_compiled_collation(&my_charset_cp932_japanese_ci);
|
||||||
|
add_compiled_collation(&my_charset_cp932_bin);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_CHARSET_latin2
|
||||||
|
add_compiled_collation(&my_charset_latin2_czech_ci);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_CHARSET_eucjpms
|
||||||
|
add_compiled_collation(&my_charset_eucjpms_japanese_ci);
|
||||||
|
add_compiled_collation(&my_charset_eucjpms_bin);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_CHARSET_euckr
|
||||||
|
add_compiled_collation(&my_charset_euckr_korean_ci);
|
||||||
|
add_compiled_collation(&my_charset_euckr_bin);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_CHARSET_gb2312
|
||||||
|
add_compiled_collation(&my_charset_gb2312_chinese_ci);
|
||||||
|
add_compiled_collation(&my_charset_gb2312_bin);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_CHARSET_gbk
|
||||||
|
add_compiled_collation(&my_charset_gbk_chinese_ci);
|
||||||
|
add_compiled_collation(&my_charset_gbk_bin);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_CHARSET_sjis
|
||||||
|
add_compiled_collation(&my_charset_sjis_japanese_ci);
|
||||||
|
add_compiled_collation(&my_charset_sjis_bin);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_CHARSET_tis620
|
||||||
|
add_compiled_collation(&my_charset_tis620_thai_ci);
|
||||||
|
add_compiled_collation(&my_charset_tis620_bin);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_CHARSET_ucs2
|
||||||
|
add_compiled_collation(&my_charset_ucs2_general_ci);
|
||||||
|
add_compiled_collation(&my_charset_ucs2_bin);
|
||||||
|
#ifdef HAVE_UCA_COLLATIONS
|
||||||
|
add_compiled_collation(&my_charset_ucs2_unicode_ci);
|
||||||
|
add_compiled_collation(&my_charset_ucs2_icelandic_uca_ci);
|
||||||
|
add_compiled_collation(&my_charset_ucs2_latvian_uca_ci);
|
||||||
|
add_compiled_collation(&my_charset_ucs2_romanian_uca_ci);
|
||||||
|
add_compiled_collation(&my_charset_ucs2_slovenian_uca_ci);
|
||||||
|
add_compiled_collation(&my_charset_ucs2_polish_uca_ci);
|
||||||
|
add_compiled_collation(&my_charset_ucs2_estonian_uca_ci);
|
||||||
|
add_compiled_collation(&my_charset_ucs2_spanish_uca_ci);
|
||||||
|
add_compiled_collation(&my_charset_ucs2_swedish_uca_ci);
|
||||||
|
add_compiled_collation(&my_charset_ucs2_turkish_uca_ci);
|
||||||
|
add_compiled_collation(&my_charset_ucs2_czech_uca_ci);
|
||||||
|
add_compiled_collation(&my_charset_ucs2_danish_uca_ci);
|
||||||
|
add_compiled_collation(&my_charset_ucs2_lithuanian_uca_ci);
|
||||||
|
add_compiled_collation(&my_charset_ucs2_slovak_uca_ci);
|
||||||
|
add_compiled_collation(&my_charset_ucs2_spanish2_uca_ci);
|
||||||
|
add_compiled_collation(&my_charset_ucs2_roman_uca_ci);
|
||||||
|
add_compiled_collation(&my_charset_ucs2_persian_uca_ci);
|
||||||
|
add_compiled_collation(&my_charset_ucs2_esperanto_uca_ci);
|
||||||
|
add_compiled_collation(&my_charset_ucs2_hungarian_uca_ci);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_CHARSET_ujis
|
||||||
|
add_compiled_collation(&my_charset_ujis_japanese_ci);
|
||||||
|
add_compiled_collation(&my_charset_ujis_bin);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_CHARSET_utf8
|
||||||
|
add_compiled_collation(&my_charset_utf8_general_ci);
|
||||||
|
add_compiled_collation(&my_charset_utf8_bin);
|
||||||
|
#ifdef HAVE_UTF8_GENERAL_CS
|
||||||
|
add_compiled_collation(&my_charset_utf8_general_cs);
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_UCA_COLLATIONS
|
||||||
|
add_compiled_collation(&my_charset_utf8_unicode_ci);
|
||||||
|
add_compiled_collation(&my_charset_utf8_icelandic_uca_ci);
|
||||||
|
add_compiled_collation(&my_charset_utf8_latvian_uca_ci);
|
||||||
|
add_compiled_collation(&my_charset_utf8_romanian_uca_ci);
|
||||||
|
add_compiled_collation(&my_charset_utf8_slovenian_uca_ci);
|
||||||
|
add_compiled_collation(&my_charset_utf8_polish_uca_ci);
|
||||||
|
add_compiled_collation(&my_charset_utf8_estonian_uca_ci);
|
||||||
|
add_compiled_collation(&my_charset_utf8_spanish_uca_ci);
|
||||||
|
add_compiled_collation(&my_charset_utf8_swedish_uca_ci);
|
||||||
|
add_compiled_collation(&my_charset_utf8_turkish_uca_ci);
|
||||||
|
add_compiled_collation(&my_charset_utf8_czech_uca_ci);
|
||||||
|
add_compiled_collation(&my_charset_utf8_danish_uca_ci);
|
||||||
|
add_compiled_collation(&my_charset_utf8_lithuanian_uca_ci);
|
||||||
|
add_compiled_collation(&my_charset_utf8_slovak_uca_ci);
|
||||||
|
add_compiled_collation(&my_charset_utf8_spanish2_uca_ci);
|
||||||
|
add_compiled_collation(&my_charset_utf8_roman_uca_ci);
|
||||||
|
add_compiled_collation(&my_charset_utf8_persian_uca_ci);
|
||||||
|
add_compiled_collation(&my_charset_utf8_esperanto_uca_ci);
|
||||||
|
add_compiled_collation(&my_charset_utf8_hungarian_uca_ci);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Copy compiled charsets */
|
||||||
|
for (cs=compiled_charsets; cs->name; cs++)
|
||||||
|
add_compiled_collation(cs);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
890
MySQL/charset.c
Normal file
890
MySQL/charset.c
Normal file
@ -0,0 +1,890 @@
|
|||||||
|
/* Copyright (C) 2000 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
#define SHAREDIR "share/"
|
||||||
|
#define DEFAULT_CHARSET_HOME "sys:/mysql/"
|
||||||
|
|
||||||
|
#include "mysys_priv.h"
|
||||||
|
#include "mysys_err.h"
|
||||||
|
#include <m_ctype.h>
|
||||||
|
#include <m_string.h>
|
||||||
|
#include <my_dir.h>
|
||||||
|
#include <my_xml.h>
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
The code below implements this functionality:
|
||||||
|
|
||||||
|
- Initializing charset related structures
|
||||||
|
- Loading dynamic charsets
|
||||||
|
- Searching for a proper CHARSET_INFO
|
||||||
|
using charset name, collation name or collation ID
|
||||||
|
- Setting server default character set
|
||||||
|
*/
|
||||||
|
|
||||||
|
my_bool my_charset_same(CHARSET_INFO *cs1, CHARSET_INFO *cs2)
|
||||||
|
{
|
||||||
|
return ((cs1 == cs2) || !strcmp(cs1->csname,cs2->csname));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static uint
|
||||||
|
get_collation_number_internal(const char *name)
|
||||||
|
{
|
||||||
|
CHARSET_INFO **cs;
|
||||||
|
for (cs= all_charsets;
|
||||||
|
cs < all_charsets+array_elements(all_charsets)-1 ;
|
||||||
|
cs++)
|
||||||
|
{
|
||||||
|
if ( cs[0] && cs[0]->name &&
|
||||||
|
!my_strcasecmp(&my_charset_latin1, cs[0]->name, name))
|
||||||
|
return cs[0]->number;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static my_bool init_state_maps(CHARSET_INFO *cs)
|
||||||
|
{
|
||||||
|
uint i;
|
||||||
|
uchar *state_map;
|
||||||
|
uchar *ident_map;
|
||||||
|
|
||||||
|
if (!(cs->state_map= (uchar*) my_once_alloc(256, MYF(MY_WME))))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (!(cs->ident_map= (uchar*) my_once_alloc(256, MYF(MY_WME))))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
state_map= cs->state_map;
|
||||||
|
ident_map= cs->ident_map;
|
||||||
|
|
||||||
|
/* Fill state_map with states to get a faster parser */
|
||||||
|
for (i=0; i < 256 ; i++)
|
||||||
|
{
|
||||||
|
if (my_isalpha(cs,i))
|
||||||
|
state_map[i]=(uchar) MY_LEX_IDENT;
|
||||||
|
else if (my_isdigit(cs,i))
|
||||||
|
state_map[i]=(uchar) MY_LEX_NUMBER_IDENT;
|
||||||
|
#if defined(USE_MB) && defined(USE_MB_IDENT)
|
||||||
|
else if (my_mbcharlen(cs, i)>1)
|
||||||
|
state_map[i]=(uchar) MY_LEX_IDENT;
|
||||||
|
#endif
|
||||||
|
else if (my_isspace(cs,i))
|
||||||
|
state_map[i]=(uchar) MY_LEX_SKIP;
|
||||||
|
else
|
||||||
|
state_map[i]=(uchar) MY_LEX_CHAR;
|
||||||
|
}
|
||||||
|
state_map[(uchar)'_']=state_map[(uchar)'$']=(uchar) MY_LEX_IDENT;
|
||||||
|
state_map[(uchar)'\'']=(uchar) MY_LEX_STRING;
|
||||||
|
state_map[(uchar)'.']=(uchar) MY_LEX_REAL_OR_POINT;
|
||||||
|
state_map[(uchar)'>']=state_map[(uchar)'=']=state_map[(uchar)'!']= (uchar) MY_LEX_CMP_OP;
|
||||||
|
state_map[(uchar)'<']= (uchar) MY_LEX_LONG_CMP_OP;
|
||||||
|
state_map[(uchar)'&']=state_map[(uchar)'|']=(uchar) MY_LEX_BOOL;
|
||||||
|
state_map[(uchar)'#']=(uchar) MY_LEX_COMMENT;
|
||||||
|
state_map[(uchar)';']=(uchar) MY_LEX_SEMICOLON;
|
||||||
|
state_map[(uchar)':']=(uchar) MY_LEX_SET_VAR;
|
||||||
|
state_map[0]=(uchar) MY_LEX_EOL;
|
||||||
|
state_map[(uchar)'\\']= (uchar) MY_LEX_ESCAPE;
|
||||||
|
state_map[(uchar)'/']= (uchar) MY_LEX_LONG_COMMENT;
|
||||||
|
state_map[(uchar)'*']= (uchar) MY_LEX_END_LONG_COMMENT;
|
||||||
|
state_map[(uchar)'@']= (uchar) MY_LEX_USER_END;
|
||||||
|
state_map[(uchar) '`']= (uchar) MY_LEX_USER_VARIABLE_DELIMITER;
|
||||||
|
state_map[(uchar)'"']= (uchar) MY_LEX_STRING_OR_DELIMITER;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Create a second map to make it faster to find identifiers
|
||||||
|
*/
|
||||||
|
for (i=0; i < 256 ; i++)
|
||||||
|
{
|
||||||
|
ident_map[i]= (uchar) (state_map[i] == MY_LEX_IDENT ||
|
||||||
|
state_map[i] == MY_LEX_NUMBER_IDENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Special handling of hex and binary strings */
|
||||||
|
state_map[(uchar)'x']= state_map[(uchar)'X']= (uchar) MY_LEX_IDENT_OR_HEX;
|
||||||
|
state_map[(uchar)'b']= state_map[(uchar)'B']= (uchar) MY_LEX_IDENT_OR_BIN;
|
||||||
|
state_map[(uchar)'n']= state_map[(uchar)'N']= (uchar) MY_LEX_IDENT_OR_NCHAR;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void simple_cs_init_functions(CHARSET_INFO *cs)
|
||||||
|
{
|
||||||
|
if (cs->state & MY_CS_BINSORT)
|
||||||
|
cs->coll= &my_collation_8bit_bin_handler;
|
||||||
|
else
|
||||||
|
cs->coll= &my_collation_8bit_simple_ci_handler;
|
||||||
|
|
||||||
|
cs->cset= &my_charset_8bit_handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static int cs_copy_data(CHARSET_INFO *to, CHARSET_INFO *from)
|
||||||
|
{
|
||||||
|
to->number= from->number ? from->number : to->number;
|
||||||
|
|
||||||
|
if (from->csname)
|
||||||
|
if (!(to->csname= my_once_strdup(from->csname,MYF(MY_WME))))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
if (from->name)
|
||||||
|
if (!(to->name= my_once_strdup(from->name,MYF(MY_WME))))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
if (from->comment)
|
||||||
|
if (!(to->comment= my_once_strdup(from->comment,MYF(MY_WME))))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
if (from->ctype)
|
||||||
|
{
|
||||||
|
if (!(to->ctype= (uchar*) my_once_memdup((char*) from->ctype,
|
||||||
|
MY_CS_CTYPE_TABLE_SIZE,
|
||||||
|
MYF(MY_WME))))
|
||||||
|
goto err;
|
||||||
|
if (init_state_maps(to))
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
if (from->to_lower)
|
||||||
|
if (!(to->to_lower= (uchar*) my_once_memdup((char*) from->to_lower,
|
||||||
|
MY_CS_TO_LOWER_TABLE_SIZE,
|
||||||
|
MYF(MY_WME))))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
if (from->to_upper)
|
||||||
|
if (!(to->to_upper= (uchar*) my_once_memdup((char*) from->to_upper,
|
||||||
|
MY_CS_TO_UPPER_TABLE_SIZE,
|
||||||
|
MYF(MY_WME))))
|
||||||
|
goto err;
|
||||||
|
if (from->sort_order)
|
||||||
|
{
|
||||||
|
if (!(to->sort_order= (uchar*) my_once_memdup((char*) from->sort_order,
|
||||||
|
MY_CS_SORT_ORDER_TABLE_SIZE,
|
||||||
|
MYF(MY_WME))))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
}
|
||||||
|
if (from->tab_to_uni)
|
||||||
|
{
|
||||||
|
uint sz= MY_CS_TO_UNI_TABLE_SIZE*sizeof(uint16);
|
||||||
|
if (!(to->tab_to_uni= (uint16*) my_once_memdup((char*)from->tab_to_uni,
|
||||||
|
sz, MYF(MY_WME))))
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
if (from->tailoring)
|
||||||
|
if (!(to->tailoring= my_once_strdup(from->tailoring,MYF(MY_WME))))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err:
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static my_bool simple_cs_is_full(CHARSET_INFO *cs)
|
||||||
|
{
|
||||||
|
return ((cs->csname && cs->tab_to_uni && cs->ctype && cs->to_upper &&
|
||||||
|
cs->to_lower) &&
|
||||||
|
(cs->number && cs->name &&
|
||||||
|
(cs->sort_order || (cs->state & MY_CS_BINSORT) )));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
copy_uca_collation(CHARSET_INFO *to, CHARSET_INFO *from)
|
||||||
|
{
|
||||||
|
to->cset= from->cset;
|
||||||
|
to->coll= from->coll;
|
||||||
|
to->strxfrm_multiply= from->strxfrm_multiply;
|
||||||
|
to->min_sort_char= from->min_sort_char;
|
||||||
|
to->max_sort_char= from->max_sort_char;
|
||||||
|
to->mbminlen= from->mbminlen;
|
||||||
|
to->mbmaxlen= from->mbmaxlen;
|
||||||
|
to->state|= MY_CS_AVAILABLE | MY_CS_LOADED |
|
||||||
|
MY_CS_STRNXFRM | MY_CS_UNICODE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int add_collation(CHARSET_INFO *cs)
|
||||||
|
{
|
||||||
|
if (cs->name && (cs->number ||
|
||||||
|
(cs->number=get_collation_number_internal(cs->name))))
|
||||||
|
{
|
||||||
|
if (!all_charsets[cs->number])
|
||||||
|
{
|
||||||
|
if (!(all_charsets[cs->number]=
|
||||||
|
(CHARSET_INFO*) my_once_alloc(sizeof(CHARSET_INFO),MYF(0))))
|
||||||
|
return MY_XML_ERROR;
|
||||||
|
bzero((void*)all_charsets[cs->number],sizeof(CHARSET_INFO));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cs->primary_number == cs->number)
|
||||||
|
cs->state |= MY_CS_PRIMARY;
|
||||||
|
|
||||||
|
if (cs->binary_number == cs->number)
|
||||||
|
cs->state |= MY_CS_BINSORT;
|
||||||
|
|
||||||
|
all_charsets[cs->number]->state|= cs->state;
|
||||||
|
|
||||||
|
if (!(all_charsets[cs->number]->state & MY_CS_COMPILED))
|
||||||
|
{
|
||||||
|
CHARSET_INFO *newcs= all_charsets[cs->number];
|
||||||
|
if (cs_copy_data(all_charsets[cs->number],cs))
|
||||||
|
return MY_XML_ERROR;
|
||||||
|
|
||||||
|
if (!strcmp(cs->csname,"ucs2") )
|
||||||
|
{
|
||||||
|
#if defined(HAVE_CHARSET_ucs2) && defined(HAVE_UCA_COLLATIONS)
|
||||||
|
copy_uca_collation(newcs, &my_charset_ucs2_unicode_ci);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else if (!strcmp(cs->csname, "utf8"))
|
||||||
|
{
|
||||||
|
#if defined (HAVE_CHARSET_utf8) && defined(HAVE_UCA_COLLATIONS)
|
||||||
|
copy_uca_collation(newcs, &my_charset_utf8_unicode_ci);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uchar *sort_order= all_charsets[cs->number]->sort_order;
|
||||||
|
simple_cs_init_functions(all_charsets[cs->number]);
|
||||||
|
newcs->mbminlen= 1;
|
||||||
|
newcs->mbmaxlen= 1;
|
||||||
|
if (simple_cs_is_full(all_charsets[cs->number]))
|
||||||
|
{
|
||||||
|
all_charsets[cs->number]->state |= MY_CS_LOADED;
|
||||||
|
}
|
||||||
|
all_charsets[cs->number]->state|= MY_CS_AVAILABLE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Check if case sensitive sort order: A < a < B.
|
||||||
|
We need MY_CS_FLAG for regex library, and for
|
||||||
|
case sensitivity flag for 5.0 client protocol,
|
||||||
|
to support isCaseSensitive() method in JDBC driver
|
||||||
|
*/
|
||||||
|
if (sort_order && sort_order['A'] < sort_order['a'] &&
|
||||||
|
sort_order['a'] < sort_order['B'])
|
||||||
|
all_charsets[cs->number]->state|= MY_CS_CSSORT;
|
||||||
|
|
||||||
|
if (my_charset_is_8bit_pure_ascii(all_charsets[cs->number]))
|
||||||
|
all_charsets[cs->number]->state|= MY_CS_PUREASCII;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
We need the below to make get_charset_name()
|
||||||
|
and get_charset_number() working even if a
|
||||||
|
character set has not been really incompiled.
|
||||||
|
The above functions are used for example
|
||||||
|
in error message compiler extra/comp_err.c.
|
||||||
|
If a character set was compiled, this information
|
||||||
|
will get lost and overwritten in add_compiled_collation().
|
||||||
|
*/
|
||||||
|
CHARSET_INFO *dst= all_charsets[cs->number];
|
||||||
|
dst->number= cs->number;
|
||||||
|
if (cs->comment)
|
||||||
|
if (!(dst->comment= my_once_strdup(cs->comment,MYF(MY_WME))))
|
||||||
|
return MY_XML_ERROR;
|
||||||
|
if (cs->csname)
|
||||||
|
if (!(dst->csname= my_once_strdup(cs->csname,MYF(MY_WME))))
|
||||||
|
return MY_XML_ERROR;
|
||||||
|
if (cs->name)
|
||||||
|
if (!(dst->name= my_once_strdup(cs->name,MYF(MY_WME))))
|
||||||
|
return MY_XML_ERROR;
|
||||||
|
}
|
||||||
|
cs->number= 0;
|
||||||
|
cs->primary_number= 0;
|
||||||
|
cs->binary_number= 0;
|
||||||
|
cs->name= NULL;
|
||||||
|
cs->state= 0;
|
||||||
|
cs->sort_order= NULL;
|
||||||
|
cs->state= 0;
|
||||||
|
}
|
||||||
|
return MY_XML_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define MY_MAX_ALLOWED_BUF 1024*1024
|
||||||
|
#define MY_CHARSET_INDEX "Index.xml"
|
||||||
|
|
||||||
|
const char *charsets_dir= NULL;
|
||||||
|
static int charset_initialized=0;
|
||||||
|
|
||||||
|
|
||||||
|
static my_bool my_read_charset_file(const char *filename, myf myflags)
|
||||||
|
{
|
||||||
|
uchar *buf;
|
||||||
|
int fd;
|
||||||
|
size_t len, tmp_len;
|
||||||
|
MY_STAT stat_info;
|
||||||
|
|
||||||
|
if (!my_stat(filename, &stat_info, MYF(myflags)) ||
|
||||||
|
((len= (uint)stat_info.st_size) > MY_MAX_ALLOWED_BUF) ||
|
||||||
|
!(buf= (uchar*) my_malloc(len,myflags)))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if ((fd=my_open(filename,O_RDONLY,myflags)) < 0)
|
||||||
|
goto error;
|
||||||
|
tmp_len=my_read(fd, buf, len, myflags);
|
||||||
|
my_close(fd,myflags);
|
||||||
|
if (tmp_len != len)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (my_parse_charset_xml((char*) buf,len,add_collation))
|
||||||
|
{
|
||||||
|
#ifdef NOT_YET
|
||||||
|
printf("ERROR at line %d pos %d '%s'\n",
|
||||||
|
my_xml_error_lineno(&p)+1,
|
||||||
|
my_xml_error_pos(&p),
|
||||||
|
my_xml_error_string(&p));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
my_free(buf, myflags);
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
error:
|
||||||
|
my_free(buf, myflags);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char *get_charsets_dir(char *buf)
|
||||||
|
{
|
||||||
|
const char *sharedir= SHAREDIR;
|
||||||
|
char *res;
|
||||||
|
DBUG_ENTER("get_charsets_dir");
|
||||||
|
|
||||||
|
if (charsets_dir != NULL)
|
||||||
|
strmake(buf, charsets_dir, FN_REFLEN-1);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (test_if_hard_path(sharedir) ||
|
||||||
|
is_prefix(sharedir, DEFAULT_CHARSET_HOME))
|
||||||
|
strxmov(buf, sharedir, "/", CHARSET_DIR, NullS);
|
||||||
|
else
|
||||||
|
strxmov(buf, DEFAULT_CHARSET_HOME, "/", sharedir, "/", CHARSET_DIR,
|
||||||
|
NullS);
|
||||||
|
}
|
||||||
|
res= convert_dirname(buf,buf,NullS);
|
||||||
|
DBUG_PRINT("info",("charsets dir: '%s'", buf));
|
||||||
|
DBUG_RETURN(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
CHARSET_INFO *all_charsets[256]={NULL};
|
||||||
|
CHARSET_INFO *default_charset_info = &my_charset_latin1;
|
||||||
|
|
||||||
|
void add_compiled_collation(CHARSET_INFO *cs)
|
||||||
|
{
|
||||||
|
all_charsets[cs->number]= cs;
|
||||||
|
cs->state|= MY_CS_AVAILABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *cs_alloc(size_t size)
|
||||||
|
{
|
||||||
|
return my_once_alloc(size, MYF(MY_WME));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __NETWARE__
|
||||||
|
my_bool STDCALL init_available_charsets(myf myflags)
|
||||||
|
#else
|
||||||
|
static my_bool init_available_charsets(myf myflags)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
char fname[FN_REFLEN + sizeof(MY_CHARSET_INDEX)];
|
||||||
|
my_bool error=FALSE;
|
||||||
|
/*
|
||||||
|
We have to use charset_initialized to not lock on THR_LOCK_charset
|
||||||
|
inside get_internal_charset...
|
||||||
|
*/
|
||||||
|
if (!charset_initialized)
|
||||||
|
{
|
||||||
|
CHARSET_INFO **cs;
|
||||||
|
/*
|
||||||
|
To make things thread safe we are not allowing other threads to interfere
|
||||||
|
while we may changing the cs_info_table
|
||||||
|
*/
|
||||||
|
pthread_mutex_lock(&THR_LOCK_charset);
|
||||||
|
if (!charset_initialized)
|
||||||
|
{
|
||||||
|
bzero(&all_charsets,sizeof(all_charsets));
|
||||||
|
init_compiled_charsets(myflags);
|
||||||
|
|
||||||
|
/* Copy compiled charsets */
|
||||||
|
for (cs=all_charsets;
|
||||||
|
cs < all_charsets+array_elements(all_charsets)-1 ;
|
||||||
|
cs++)
|
||||||
|
{
|
||||||
|
if (*cs)
|
||||||
|
{
|
||||||
|
if (cs[0]->ctype)
|
||||||
|
if (init_state_maps(*cs))
|
||||||
|
*cs= NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
strmov(get_charsets_dir(fname), MY_CHARSET_INDEX);
|
||||||
|
error= my_read_charset_file(fname,myflags);
|
||||||
|
charset_initialized=1;
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&THR_LOCK_charset);
|
||||||
|
}
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void free_charsets(void)
|
||||||
|
{
|
||||||
|
charset_initialized=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint get_collation_number(const char *name)
|
||||||
|
{
|
||||||
|
init_available_charsets(MYF(0));
|
||||||
|
return get_collation_number_internal(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint get_charset_number(const char *charset_name, uint cs_flags)
|
||||||
|
{
|
||||||
|
CHARSET_INFO **cs;
|
||||||
|
init_available_charsets(MYF(0));
|
||||||
|
|
||||||
|
for (cs= all_charsets;
|
||||||
|
cs < all_charsets+array_elements(all_charsets)-1 ;
|
||||||
|
cs++)
|
||||||
|
{
|
||||||
|
if ( cs[0] && cs[0]->csname && (cs[0]->state & cs_flags) &&
|
||||||
|
!my_strcasecmp(&my_charset_latin1, cs[0]->csname, charset_name))
|
||||||
|
return cs[0]->number;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char *get_charset_name(uint charset_number)
|
||||||
|
{
|
||||||
|
CHARSET_INFO *cs;
|
||||||
|
init_available_charsets(MYF(0));
|
||||||
|
|
||||||
|
cs=all_charsets[charset_number];
|
||||||
|
if (cs && (cs->number == charset_number) && cs->name )
|
||||||
|
return (char*) cs->name;
|
||||||
|
|
||||||
|
return (char*) "?"; /* this mimics find_type() */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static CHARSET_INFO *get_internal_charset(uint cs_number, myf flags)
|
||||||
|
{
|
||||||
|
char buf[FN_REFLEN];
|
||||||
|
CHARSET_INFO *cs;
|
||||||
|
|
||||||
|
if ((cs= all_charsets[cs_number]))
|
||||||
|
{
|
||||||
|
if (cs->state & MY_CS_READY) /* if CS is already initialized */
|
||||||
|
return cs;
|
||||||
|
|
||||||
|
/*
|
||||||
|
To make things thread safe we are not allowing other threads to interfere
|
||||||
|
while we may changing the cs_info_table
|
||||||
|
*/
|
||||||
|
pthread_mutex_lock(&THR_LOCK_charset);
|
||||||
|
|
||||||
|
if (!(cs->state & (MY_CS_COMPILED|MY_CS_LOADED))) /* if CS is not in memory */
|
||||||
|
{
|
||||||
|
strxmov(get_charsets_dir(buf), cs->csname, ".xml", NullS);
|
||||||
|
my_read_charset_file(buf,flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cs->state & MY_CS_AVAILABLE)
|
||||||
|
{
|
||||||
|
if (!(cs->state & MY_CS_READY))
|
||||||
|
{
|
||||||
|
if ((cs->cset->init && cs->cset->init(cs, cs_alloc)) ||
|
||||||
|
(cs->coll->init && cs->coll->init(cs, cs_alloc)))
|
||||||
|
cs= NULL;
|
||||||
|
else
|
||||||
|
cs->state|= MY_CS_READY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
cs= NULL;
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&THR_LOCK_charset);
|
||||||
|
}
|
||||||
|
return cs;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CHARSET_INFO *get_charset(uint cs_number, myf flags)
|
||||||
|
{
|
||||||
|
CHARSET_INFO *cs;
|
||||||
|
if (cs_number == default_charset_info->number)
|
||||||
|
return default_charset_info;
|
||||||
|
|
||||||
|
(void) init_available_charsets(MYF(0)); /* If it isn't initialized */
|
||||||
|
|
||||||
|
if (!cs_number || cs_number >= array_elements(all_charsets)-1)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
cs=get_internal_charset(cs_number, flags);
|
||||||
|
|
||||||
|
if (!cs && (flags & MY_WME))
|
||||||
|
{
|
||||||
|
char index_file[FN_REFLEN + sizeof(MY_CHARSET_INDEX)], cs_string[23];
|
||||||
|
strmov(get_charsets_dir(index_file),MY_CHARSET_INDEX);
|
||||||
|
cs_string[0]='#';
|
||||||
|
int10_to_str(cs_number, cs_string+1, 10);
|
||||||
|
my_error(EE_UNKNOWN_CHARSET, MYF(ME_BELL), cs_string, index_file);
|
||||||
|
}
|
||||||
|
return cs;
|
||||||
|
}
|
||||||
|
|
||||||
|
CHARSET_INFO *get_charset_by_name(const char *cs_name, myf flags)
|
||||||
|
{
|
||||||
|
uint cs_number;
|
||||||
|
CHARSET_INFO *cs;
|
||||||
|
(void) init_available_charsets(MYF(0)); /* If it isn't initialized */
|
||||||
|
|
||||||
|
cs_number=get_collation_number(cs_name);
|
||||||
|
cs= cs_number ? get_internal_charset(cs_number,flags) : NULL;
|
||||||
|
|
||||||
|
if (!cs && (flags & MY_WME))
|
||||||
|
{
|
||||||
|
char index_file[FN_REFLEN + sizeof(MY_CHARSET_INDEX)];
|
||||||
|
strmov(get_charsets_dir(index_file),MY_CHARSET_INDEX);
|
||||||
|
my_error(EE_UNKNOWN_COLLATION, MYF(ME_BELL), cs_name, index_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
return cs;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CHARSET_INFO *get_charset_by_csname(const char *cs_name,
|
||||||
|
uint cs_flags,
|
||||||
|
myf flags)
|
||||||
|
{
|
||||||
|
uint cs_number;
|
||||||
|
CHARSET_INFO *cs;
|
||||||
|
DBUG_ENTER("get_charset_by_csname");
|
||||||
|
DBUG_PRINT("enter",("name: '%s'", cs_name));
|
||||||
|
|
||||||
|
(void) init_available_charsets(MYF(0)); /* If it isn't initialized */
|
||||||
|
|
||||||
|
cs_number= get_charset_number(cs_name, cs_flags);
|
||||||
|
cs= cs_number ? get_internal_charset(cs_number, flags) : NULL;
|
||||||
|
|
||||||
|
if (!cs && (flags & MY_WME))
|
||||||
|
{
|
||||||
|
char index_file[FN_REFLEN + sizeof(MY_CHARSET_INDEX)];
|
||||||
|
strmov(get_charsets_dir(index_file),MY_CHARSET_INDEX);
|
||||||
|
my_error(EE_UNKNOWN_CHARSET, MYF(ME_BELL), cs_name, index_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
DBUG_RETURN(cs);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Resolve character set by the character set name (utf8, latin1, ...).
|
||||||
|
|
||||||
|
The function tries to resolve character set by the specified name. If
|
||||||
|
there is character set with the given name, it is assigned to the "cs"
|
||||||
|
parameter and FALSE is returned. If there is no such character set,
|
||||||
|
"default_cs" is assigned to the "cs" and TRUE is returned.
|
||||||
|
|
||||||
|
@param[in] cs_name Character set name.
|
||||||
|
@param[in] default_cs Default character set.
|
||||||
|
@param[out] cs Variable to store character set.
|
||||||
|
|
||||||
|
@return FALSE if character set was resolved successfully; TRUE if there
|
||||||
|
is no character set with given name.
|
||||||
|
*/
|
||||||
|
|
||||||
|
my_bool resolve_charset(const char *cs_name,
|
||||||
|
CHARSET_INFO *default_cs,
|
||||||
|
CHARSET_INFO **cs)
|
||||||
|
{
|
||||||
|
*cs= get_charset_by_csname(cs_name, MY_CS_PRIMARY, MYF(0));
|
||||||
|
|
||||||
|
if (*cs == NULL)
|
||||||
|
{
|
||||||
|
*cs= default_cs;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Resolve collation by the collation name (utf8_general_ci, ...).
|
||||||
|
|
||||||
|
The function tries to resolve collation by the specified name. If there
|
||||||
|
is collation with the given name, it is assigned to the "cl" parameter
|
||||||
|
and FALSE is returned. If there is no such collation, "default_cl" is
|
||||||
|
assigned to the "cl" and TRUE is returned.
|
||||||
|
|
||||||
|
@param[out] cl Variable to store collation.
|
||||||
|
@param[in] cl_name Collation name.
|
||||||
|
@param[in] default_cl Default collation.
|
||||||
|
|
||||||
|
@return FALSE if collation was resolved successfully; TRUE if there is no
|
||||||
|
collation with given name.
|
||||||
|
*/
|
||||||
|
|
||||||
|
my_bool resolve_collation(const char *cl_name,
|
||||||
|
CHARSET_INFO *default_cl,
|
||||||
|
CHARSET_INFO **cl)
|
||||||
|
{
|
||||||
|
*cl= get_charset_by_name(cl_name, MYF(0));
|
||||||
|
|
||||||
|
if (*cl == NULL)
|
||||||
|
{
|
||||||
|
*cl= default_cl;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Escape string with backslashes (\)
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
escape_string_for_mysql()
|
||||||
|
charset_info Charset of the strings
|
||||||
|
to Buffer for escaped string
|
||||||
|
to_length Length of destination buffer, or 0
|
||||||
|
from The string to escape
|
||||||
|
length The length of the string to escape
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
This escapes the contents of a string by adding backslashes before special
|
||||||
|
characters, and turning others into specific escape sequences, such as
|
||||||
|
turning newlines into \n and null bytes into \0.
|
||||||
|
|
||||||
|
NOTE
|
||||||
|
To maintain compatibility with the old C API, to_length may be 0 to mean
|
||||||
|
"big enough"
|
||||||
|
|
||||||
|
RETURN VALUES
|
||||||
|
(size_t) -1 The escaped string did not fit in the to buffer
|
||||||
|
# The length of the escaped string
|
||||||
|
*/
|
||||||
|
|
||||||
|
size_t escape_string_for_mysql(CHARSET_INFO *charset_info,
|
||||||
|
char *to, size_t to_length,
|
||||||
|
const char *from, size_t length)
|
||||||
|
{
|
||||||
|
const char *to_start= to;
|
||||||
|
const char *end, *to_end=to_start + (to_length ? to_length-1 : 2*length);
|
||||||
|
my_bool overflow= FALSE;
|
||||||
|
#ifdef USE_MB
|
||||||
|
my_bool use_mb_flag= use_mb(charset_info);
|
||||||
|
#endif
|
||||||
|
for (end= from + length; from < end; from++)
|
||||||
|
{
|
||||||
|
char escape= 0;
|
||||||
|
#ifdef USE_MB
|
||||||
|
int tmp_length;
|
||||||
|
if (use_mb_flag && (tmp_length= my_ismbchar(charset_info, from, end)))
|
||||||
|
{
|
||||||
|
if (to + tmp_length > to_end)
|
||||||
|
{
|
||||||
|
overflow= TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
while (tmp_length--)
|
||||||
|
*to++= *from++;
|
||||||
|
from--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
If the next character appears to begin a multi-byte character, we
|
||||||
|
escape that first byte of that apparent multi-byte character. (The
|
||||||
|
character just looks like a multi-byte character -- if it were actually
|
||||||
|
a multi-byte character, it would have been passed through in the test
|
||||||
|
above.)
|
||||||
|
|
||||||
|
Without this check, we can create a problem by converting an invalid
|
||||||
|
multi-byte character into a valid one. For example, 0xbf27 is not
|
||||||
|
a valid GBK character, but 0xbf5c is. (0x27 = ', 0x5c = \)
|
||||||
|
*/
|
||||||
|
if (use_mb_flag && (tmp_length= my_mbcharlen(charset_info, *from)) > 1)
|
||||||
|
escape= *from;
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
switch (*from) {
|
||||||
|
case 0: /* Must be escaped for 'mysql' */
|
||||||
|
escape= '0';
|
||||||
|
break;
|
||||||
|
case '\n': /* Must be escaped for logs */
|
||||||
|
escape= 'n';
|
||||||
|
break;
|
||||||
|
case '\r':
|
||||||
|
escape= 'r';
|
||||||
|
break;
|
||||||
|
case '\\':
|
||||||
|
escape= '\\';
|
||||||
|
break;
|
||||||
|
case '\'':
|
||||||
|
escape= '\'';
|
||||||
|
break;
|
||||||
|
case '"': /* Better safe than sorry */
|
||||||
|
escape= '"';
|
||||||
|
break;
|
||||||
|
case '\032': /* This gives problems on Win32 */
|
||||||
|
escape= 'Z';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (escape)
|
||||||
|
{
|
||||||
|
if (to + 2 > to_end)
|
||||||
|
{
|
||||||
|
overflow= TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*to++= '\\';
|
||||||
|
*to++= escape;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (to + 1 > to_end)
|
||||||
|
{
|
||||||
|
overflow= TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*to++= *from;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*to= 0;
|
||||||
|
return overflow ? (size_t) -1 : (size_t) (to - to_start);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef BACKSLASH_MBTAIL
|
||||||
|
static CHARSET_INFO *fs_cset_cache= NULL;
|
||||||
|
|
||||||
|
CHARSET_INFO *fs_character_set()
|
||||||
|
{
|
||||||
|
if (!fs_cset_cache)
|
||||||
|
{
|
||||||
|
char buf[10]= "cp";
|
||||||
|
GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_IDEFAULTANSICODEPAGE,
|
||||||
|
buf+2, sizeof(buf)-3);
|
||||||
|
/*
|
||||||
|
We cannot call get_charset_by_name here
|
||||||
|
because fs_character_set() is executed before
|
||||||
|
LOCK_THD_charset mutex initialization, which
|
||||||
|
is used inside get_charset_by_name.
|
||||||
|
As we're now interested in cp932 only,
|
||||||
|
let's just detect it using strcmp().
|
||||||
|
*/
|
||||||
|
fs_cset_cache= !strcmp(buf, "cp932") ?
|
||||||
|
&my_charset_cp932_japanese_ci : &my_charset_bin;
|
||||||
|
}
|
||||||
|
return fs_cset_cache;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
Escape apostrophes by doubling them up
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
escape_quotes_for_mysql()
|
||||||
|
charset_info Charset of the strings
|
||||||
|
to Buffer for escaped string
|
||||||
|
to_length Length of destination buffer, or 0
|
||||||
|
from The string to escape
|
||||||
|
length The length of the string to escape
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
This escapes the contents of a string by doubling up any apostrophes that
|
||||||
|
it contains. This is used when the NO_BACKSLASH_ESCAPES SQL_MODE is in
|
||||||
|
effect on the server.
|
||||||
|
|
||||||
|
NOTE
|
||||||
|
To be consistent with escape_string_for_mysql(), to_length may be 0 to
|
||||||
|
mean "big enough"
|
||||||
|
|
||||||
|
RETURN VALUES
|
||||||
|
~0 The escaped string did not fit in the to buffer
|
||||||
|
>=0 The length of the escaped string
|
||||||
|
*/
|
||||||
|
|
||||||
|
size_t escape_quotes_for_mysql(CHARSET_INFO *charset_info,
|
||||||
|
char *to, size_t to_length,
|
||||||
|
const char *from, size_t length)
|
||||||
|
{
|
||||||
|
const char *to_start= to;
|
||||||
|
const char *end, *to_end=to_start + (to_length ? to_length-1 : 2*length);
|
||||||
|
my_bool overflow= FALSE;
|
||||||
|
#ifdef USE_MB
|
||||||
|
my_bool use_mb_flag= use_mb(charset_info);
|
||||||
|
#endif
|
||||||
|
for (end= from + length; from < end; from++)
|
||||||
|
{
|
||||||
|
#ifdef USE_MB
|
||||||
|
int tmp_length;
|
||||||
|
if (use_mb_flag && (tmp_length= my_ismbchar(charset_info, from, end)))
|
||||||
|
{
|
||||||
|
if (to + tmp_length > to_end)
|
||||||
|
{
|
||||||
|
overflow= TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
while (tmp_length--)
|
||||||
|
*to++= *from++;
|
||||||
|
from--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
We don't have the same issue here with a non-multi-byte character being
|
||||||
|
turned into a multi-byte character by the addition of an escaping
|
||||||
|
character, because we are only escaping the ' character with itself.
|
||||||
|
*/
|
||||||
|
#endif
|
||||||
|
if (*from == '\'')
|
||||||
|
{
|
||||||
|
if (to + 2 > to_end)
|
||||||
|
{
|
||||||
|
overflow= TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*to++= '\'';
|
||||||
|
*to++= '\'';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (to + 1 > to_end)
|
||||||
|
{
|
||||||
|
overflow= TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*to++= *from;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*to= 0;
|
||||||
|
return overflow ? (ulong)~0 : (ulong) (to - to_start);
|
||||||
|
}
|
3266
MySQL/client.c
Normal file
3266
MySQL/client.c
Normal file
File diff suppressed because it is too large
Load Diff
69
MySQL/client_settings.h
Normal file
69
MySQL/client_settings.h
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
/* Copyright (C) 2003-2005 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
extern uint mysql_port;
|
||||||
|
extern char * mysql_unix_port;
|
||||||
|
|
||||||
|
#define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | \
|
||||||
|
CLIENT_TRANSACTIONS | \
|
||||||
|
CLIENT_PROTOCOL_41 | CLIENT_SECURE_CONNECTION)
|
||||||
|
|
||||||
|
sig_handler my_pipe_sig_handler(int sig);
|
||||||
|
void read_user_name(char *name);
|
||||||
|
my_bool handle_local_infile(MYSQL *mysql, const char *net_filename);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Let the user specify that we don't want SIGPIPE; This doesn't however work
|
||||||
|
with threaded applications as we can have multiple read in progress.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined(__WIN__) && defined(SIGPIPE) && !defined(THREAD)
|
||||||
|
#define init_sigpipe_variables sig_return old_signal_handler=(sig_return) 0;
|
||||||
|
#define set_sigpipe(mysql) if ((mysql)->client_flag & CLIENT_IGNORE_SIGPIPE) old_signal_handler=signal(SIGPIPE, my_pipe_sig_handler)
|
||||||
|
#define reset_sigpipe(mysql) if ((mysql)->client_flag & CLIENT_IGNORE_SIGPIPE) signal(SIGPIPE,old_signal_handler);
|
||||||
|
#else
|
||||||
|
#define init_sigpipe_variables
|
||||||
|
#define set_sigpipe(mysql)
|
||||||
|
#define reset_sigpipe(mysql)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void mysql_read_default_options(struct st_mysql_options *options,
|
||||||
|
const char *filename,const char *group);
|
||||||
|
void mysql_detach_stmt_list(LIST **stmt_list, const char *func_name);
|
||||||
|
MYSQL * STDCALL
|
||||||
|
cli_mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
|
||||||
|
const char *passwd, const char *db,
|
||||||
|
uint port, const char *unix_socket,ulong client_flag);
|
||||||
|
|
||||||
|
void cli_mysql_close(MYSQL *mysql);
|
||||||
|
|
||||||
|
MYSQL_FIELD * cli_list_fields(MYSQL *mysql);
|
||||||
|
my_bool cli_read_prepare_result(MYSQL *mysql, MYSQL_STMT *stmt);
|
||||||
|
MYSQL_DATA * cli_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
|
||||||
|
uint fields);
|
||||||
|
int cli_stmt_execute(MYSQL_STMT *stmt);
|
||||||
|
int cli_read_binary_rows(MYSQL_STMT *stmt);
|
||||||
|
int cli_unbuffered_fetch(MYSQL *mysql, char **row);
|
||||||
|
const char * cli_read_statistics(MYSQL *mysql);
|
||||||
|
int cli_read_change_user_result(MYSQL *mysql, char *buff, const char *passwd);
|
||||||
|
|
||||||
|
#ifdef EMBEDDED_LIBRARY
|
||||||
|
int init_embedded_server(int argc, char **argv, char **groups);
|
||||||
|
void end_embedded_server();
|
||||||
|
#endif /*EMBEDDED_LIBRARY*/
|
||||||
|
|
||||||
|
C_MODE_START
|
||||||
|
extern int mysql_init_character_set(MYSQL *mysql);
|
||||||
|
C_MODE_END
|
145
MySQL/conf_to_src.c
Normal file
145
MySQL/conf_to_src.c
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
/* Copyright (C) 2000-2004 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation.
|
||||||
|
|
||||||
|
There are special exceptions to the terms and conditions of the GPL as it
|
||||||
|
is applied to this software. View the full text of the exception in file
|
||||||
|
EXCEPTIONS-CLIENT in the directory of this software distribution.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
/* can't use -lmysys because this prog is used to create -lstrings */
|
||||||
|
|
||||||
|
|
||||||
|
#include <my_global.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#define CHARSETS_SUBDIR "sql/share/charsets"
|
||||||
|
#define CTYPE_TABLE_SIZE 257
|
||||||
|
#define TO_LOWER_TABLE_SIZE 256
|
||||||
|
#define TO_UPPER_TABLE_SIZE 256
|
||||||
|
#define SORT_ORDER_TABLE_SIZE 256
|
||||||
|
#define ROW_LEN 16
|
||||||
|
|
||||||
|
void print_arrays_for(char *set);
|
||||||
|
|
||||||
|
char *prog;
|
||||||
|
char buf[1024], *p, *endptr;
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
prog = *argv;
|
||||||
|
|
||||||
|
if (argc < 2) {
|
||||||
|
fprintf(stderr, "usage: %s source-dir [charset [, charset]]\n", prog);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
--argc; ++argv; /* skip program name */
|
||||||
|
|
||||||
|
if (chdir(*argv) != 0) {
|
||||||
|
fprintf(stderr, "%s: can't cd to %s\n", prog, *argv);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
--argc; ++argv;
|
||||||
|
|
||||||
|
if (chdir(CHARSETS_SUBDIR) != 0) {
|
||||||
|
fprintf(stderr, "%s: can't cd to %s\n", prog, CHARSETS_SUBDIR);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (argc--)
|
||||||
|
print_arrays_for(*argv++);
|
||||||
|
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
print_array(FILE *f, const char *set, const char *name, int n)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char val[100];
|
||||||
|
|
||||||
|
printf("uchar %s_%s[] = {\n", name, set);
|
||||||
|
|
||||||
|
p = buf;
|
||||||
|
*buf = '\0';
|
||||||
|
for (i = 0; i < n; ++i)
|
||||||
|
{
|
||||||
|
/* get a word from f */
|
||||||
|
endptr = p;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
while (isspace(*endptr))
|
||||||
|
++endptr;
|
||||||
|
if (*endptr && *endptr != '#') /* not comment */
|
||||||
|
break;
|
||||||
|
if ((fgets(buf, sizeof(buf), f)) == NULL)
|
||||||
|
return; /* XXX: break silently */
|
||||||
|
endptr = buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = val;
|
||||||
|
while (!isspace(*endptr))
|
||||||
|
*p++ = *endptr++;
|
||||||
|
*p = '\0';
|
||||||
|
p = endptr;
|
||||||
|
|
||||||
|
/* write the value out */
|
||||||
|
|
||||||
|
if (i == 0 || i % ROW_LEN == n % ROW_LEN)
|
||||||
|
printf(" ");
|
||||||
|
|
||||||
|
printf("%3d", (unsigned char) strtol(val, (char **) NULL, 16));
|
||||||
|
|
||||||
|
if (i < n - 1)
|
||||||
|
printf(",");
|
||||||
|
|
||||||
|
if ((i+1) % ROW_LEN == n % ROW_LEN)
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("};\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
print_arrays_for(char *set)
|
||||||
|
{
|
||||||
|
FILE *f;
|
||||||
|
|
||||||
|
sprintf(buf, "%s.conf", set);
|
||||||
|
|
||||||
|
if ((f = fopen(buf, "r")) == NULL) {
|
||||||
|
fprintf(stderr, "%s: can't read conf file for charset %s\n", prog, set);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\
|
||||||
|
/* The %s character set. Generated automatically by configure and\n\
|
||||||
|
* the %s program\n\
|
||||||
|
*/\n\n",
|
||||||
|
set, prog);
|
||||||
|
|
||||||
|
/* it would be nice if this used the code in mysys/charset.c, but... */
|
||||||
|
print_array(f, set, "ctype", CTYPE_TABLE_SIZE);
|
||||||
|
print_array(f, set, "to_lower", TO_LOWER_TABLE_SIZE);
|
||||||
|
print_array(f, set, "to_upper", TO_UPPER_TABLE_SIZE);
|
||||||
|
print_array(f, set, "sort_order", SORT_ORDER_TABLE_SIZE);
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
6446
MySQL/ctype-big5.c
Normal file
6446
MySQL/ctype-big5.c
Normal file
File diff suppressed because it is too large
Load Diff
582
MySQL/ctype-bin.c
Normal file
582
MySQL/ctype-bin.c
Normal file
@ -0,0 +1,582 @@
|
|||||||
|
/* Copyright (C) 2002 MySQL AB & tommy@valley.ne.jp.
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Library General Public
|
||||||
|
License as published by the Free Software Foundation; version 2
|
||||||
|
of the License.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Library General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Library General Public
|
||||||
|
License along with this library; if not, write to the Free
|
||||||
|
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||||
|
MA 02111-1307, USA */
|
||||||
|
|
||||||
|
/* This file is for binary pseudo charset, created by bar@mysql.com */
|
||||||
|
|
||||||
|
|
||||||
|
#include <my_global.h>
|
||||||
|
#include "m_string.h"
|
||||||
|
#include "m_ctype.h"
|
||||||
|
|
||||||
|
static uchar ctype_bin[]=
|
||||||
|
{
|
||||||
|
0,
|
||||||
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 32, 32,
|
||||||
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
||||||
|
72, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||||
|
132,132,132,132,132,132,132,132,132,132, 16, 16, 16, 16, 16, 16,
|
||||||
|
16,129,129,129,129,129,129, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16, 16, 16, 16, 16,
|
||||||
|
16,130,130,130,130,130,130, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 16, 16, 16, 16, 32,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Dummy array for toupper / tolower / sortorder */
|
||||||
|
|
||||||
|
static uchar bin_char_array[] =
|
||||||
|
{
|
||||||
|
0, 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,171,172,173,174,175,
|
||||||
|
176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
|
||||||
|
192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
|
||||||
|
208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
|
||||||
|
224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
|
||||||
|
240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static my_bool
|
||||||
|
my_coll_init_8bit_bin(CHARSET_INFO *cs,
|
||||||
|
void *(*alloc)(size_t) __attribute__((unused)))
|
||||||
|
{
|
||||||
|
cs->max_sort_char=255;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int my_strnncoll_binary(CHARSET_INFO * cs __attribute__((unused)),
|
||||||
|
const uchar *s, size_t slen,
|
||||||
|
const uchar *t, size_t tlen,
|
||||||
|
my_bool t_is_prefix)
|
||||||
|
{
|
||||||
|
size_t len=min(slen,tlen);
|
||||||
|
int cmp= memcmp(s,t,len);
|
||||||
|
return cmp ? cmp : (int)((t_is_prefix ? len : slen) - tlen);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t my_lengthsp_binary(CHARSET_INFO *cs __attribute__((unused)),
|
||||||
|
const char *ptr __attribute__((unused)),
|
||||||
|
size_t length)
|
||||||
|
{
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Compare two strings. Result is sign(first_argument - second_argument)
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
my_strnncollsp_binary()
|
||||||
|
cs Chararacter set
|
||||||
|
s String to compare
|
||||||
|
slen Length of 's'
|
||||||
|
t String to compare
|
||||||
|
tlen Length of 't'
|
||||||
|
|
||||||
|
NOTE
|
||||||
|
This function is used for real binary strings, i.e. for
|
||||||
|
BLOB, BINARY(N) and VARBINARY(N).
|
||||||
|
It compares trailing spaces as spaces.
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
< 0 s < t
|
||||||
|
0 s == t
|
||||||
|
> 0 s > t
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int my_strnncollsp_binary(CHARSET_INFO * cs __attribute__((unused)),
|
||||||
|
const uchar *s, size_t slen,
|
||||||
|
const uchar *t, size_t tlen,
|
||||||
|
my_bool diff_if_only_endspace_difference
|
||||||
|
__attribute__((unused)))
|
||||||
|
{
|
||||||
|
return my_strnncoll_binary(cs,s,slen,t,tlen,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int my_strnncoll_8bit_bin(CHARSET_INFO * cs __attribute__((unused)),
|
||||||
|
const uchar *s, size_t slen,
|
||||||
|
const uchar *t, size_t tlen,
|
||||||
|
my_bool t_is_prefix)
|
||||||
|
{
|
||||||
|
size_t len=min(slen,tlen);
|
||||||
|
int cmp= memcmp(s,t,len);
|
||||||
|
return cmp ? cmp : (int)((t_is_prefix ? len : slen) - tlen);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Compare two strings. Result is sign(first_argument - second_argument)
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
my_strnncollsp_8bit_bin()
|
||||||
|
cs Chararacter set
|
||||||
|
s String to compare
|
||||||
|
slen Length of 's'
|
||||||
|
t String to compare
|
||||||
|
tlen Length of 't'
|
||||||
|
diff_if_only_endspace_difference
|
||||||
|
Set to 1 if the strings should be regarded as different
|
||||||
|
if they only difference in end space
|
||||||
|
|
||||||
|
NOTE
|
||||||
|
This function is used for character strings with binary collations.
|
||||||
|
The shorter string is extended with end space to be as long as the longer
|
||||||
|
one.
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
< 0 s < t
|
||||||
|
0 s == t
|
||||||
|
> 0 s > t
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int my_strnncollsp_8bit_bin(CHARSET_INFO * cs __attribute__((unused)),
|
||||||
|
const uchar *a, size_t a_length,
|
||||||
|
const uchar *b, size_t b_length,
|
||||||
|
my_bool diff_if_only_endspace_difference)
|
||||||
|
{
|
||||||
|
const uchar *end;
|
||||||
|
size_t length;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
#ifndef VARCHAR_WITH_DIFF_ENDSPACE_ARE_DIFFERENT_FOR_UNIQUE
|
||||||
|
diff_if_only_endspace_difference= 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
end= a + (length= min(a_length, b_length));
|
||||||
|
while (a < end)
|
||||||
|
{
|
||||||
|
if (*a++ != *b++)
|
||||||
|
return ((int) a[-1] - (int) b[-1]);
|
||||||
|
}
|
||||||
|
res= 0;
|
||||||
|
if (a_length != b_length)
|
||||||
|
{
|
||||||
|
int swap= 1;
|
||||||
|
/*
|
||||||
|
Check the next not space character of the longer key. If it's < ' ',
|
||||||
|
then it's smaller than the other key.
|
||||||
|
*/
|
||||||
|
if (diff_if_only_endspace_difference)
|
||||||
|
res= 1; /* Assume 'a' is bigger */
|
||||||
|
if (a_length < b_length)
|
||||||
|
{
|
||||||
|
/* put shorter key in s */
|
||||||
|
a_length= b_length;
|
||||||
|
a= b;
|
||||||
|
swap= -1; /* swap sign of result */
|
||||||
|
res= -res;
|
||||||
|
}
|
||||||
|
for (end= a + a_length-length; a < end ; a++)
|
||||||
|
{
|
||||||
|
if (*a != ' ')
|
||||||
|
return (*a < ' ') ? -swap : swap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* This function is used for all conversion functions */
|
||||||
|
|
||||||
|
static size_t my_case_str_bin(CHARSET_INFO *cs __attribute__((unused)),
|
||||||
|
char *str __attribute__((unused)))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static size_t my_case_bin(CHARSET_INFO *cs __attribute__((unused)),
|
||||||
|
char *src __attribute__((unused)),
|
||||||
|
size_t srclen,
|
||||||
|
char *dst __attribute__((unused)),
|
||||||
|
size_t dstlen __attribute__((unused)))
|
||||||
|
{
|
||||||
|
return srclen;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int my_strcasecmp_bin(CHARSET_INFO * cs __attribute__((unused)),
|
||||||
|
const char *s, const char *t)
|
||||||
|
{
|
||||||
|
return strcmp(s,t);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint my_mbcharlen_8bit(CHARSET_INFO *cs __attribute__((unused)),
|
||||||
|
uint c __attribute__((unused)))
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int my_mb_wc_bin(CHARSET_INFO *cs __attribute__((unused)),
|
||||||
|
my_wc_t *wc,
|
||||||
|
const uchar *str,
|
||||||
|
const uchar *end __attribute__((unused)))
|
||||||
|
{
|
||||||
|
if (str >= end)
|
||||||
|
return MY_CS_TOOSMALL;
|
||||||
|
|
||||||
|
*wc=str[0];
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int my_wc_mb_bin(CHARSET_INFO *cs __attribute__((unused)),
|
||||||
|
my_wc_t wc,
|
||||||
|
uchar *s,
|
||||||
|
uchar *e __attribute__((unused)))
|
||||||
|
{
|
||||||
|
if (s >= e)
|
||||||
|
return MY_CS_TOOSMALL;
|
||||||
|
|
||||||
|
if (wc < 256)
|
||||||
|
{
|
||||||
|
s[0]= (char) wc;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return MY_CS_ILUNI;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void my_hash_sort_8bit_bin(CHARSET_INFO *cs __attribute__((unused)),
|
||||||
|
const uchar *key, size_t len,
|
||||||
|
ulong *nr1, ulong *nr2)
|
||||||
|
{
|
||||||
|
const uchar *pos = key;
|
||||||
|
|
||||||
|
key+= len;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Remove trailing spaces. We have to do this to be able to compare
|
||||||
|
'A ' and 'A' as identical
|
||||||
|
*/
|
||||||
|
while (key > pos && key[-1] == ' ')
|
||||||
|
key--;
|
||||||
|
|
||||||
|
for (; pos < (uchar*) key ; pos++)
|
||||||
|
{
|
||||||
|
nr1[0]^=(ulong) ((((uint) nr1[0] & 63)+nr2[0]) *
|
||||||
|
((uint)*pos)) + (nr1[0] << 8);
|
||||||
|
nr2[0]+=3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void my_hash_sort_bin(CHARSET_INFO *cs __attribute__((unused)),
|
||||||
|
const uchar *key, size_t len,ulong *nr1, ulong *nr2)
|
||||||
|
{
|
||||||
|
const uchar *pos = key;
|
||||||
|
|
||||||
|
key+= len;
|
||||||
|
|
||||||
|
for (; pos < (uchar*) key ; pos++)
|
||||||
|
{
|
||||||
|
nr1[0]^=(ulong) ((((uint) nr1[0] & 63)+nr2[0]) *
|
||||||
|
((uint)*pos)) + (nr1[0] << 8);
|
||||||
|
nr2[0]+=3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
The following defines is here to keep the following code identical to
|
||||||
|
the one in ctype-simple.c
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define likeconv(s,A) (A)
|
||||||
|
#define INC_PTR(cs,A,B) (A)++
|
||||||
|
|
||||||
|
|
||||||
|
int my_wildcmp_bin(CHARSET_INFO *cs,
|
||||||
|
const char *str,const char *str_end,
|
||||||
|
const char *wildstr,const char *wildend,
|
||||||
|
int escape, int w_one, int w_many)
|
||||||
|
{
|
||||||
|
int result= -1; /* Not found, using wildcards */
|
||||||
|
|
||||||
|
while (wildstr != wildend)
|
||||||
|
{
|
||||||
|
while (*wildstr != w_many && *wildstr != w_one)
|
||||||
|
{
|
||||||
|
if (*wildstr == escape && wildstr+1 != wildend)
|
||||||
|
wildstr++;
|
||||||
|
if (str == str_end || likeconv(cs,*wildstr++) != likeconv(cs,*str++))
|
||||||
|
return(1); /* No match */
|
||||||
|
if (wildstr == wildend)
|
||||||
|
return(str != str_end); /* Match if both are at end */
|
||||||
|
result=1; /* Found an anchor char */
|
||||||
|
}
|
||||||
|
if (*wildstr == w_one)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (str == str_end) /* Skip one char if possible */
|
||||||
|
return(result);
|
||||||
|
INC_PTR(cs,str,str_end);
|
||||||
|
} while (++wildstr < wildend && *wildstr == w_one);
|
||||||
|
if (wildstr == wildend)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (*wildstr == w_many)
|
||||||
|
{ /* Found w_many */
|
||||||
|
uchar cmp;
|
||||||
|
wildstr++;
|
||||||
|
/* Remove any '%' and '_' from the wild search string */
|
||||||
|
for (; wildstr != wildend ; wildstr++)
|
||||||
|
{
|
||||||
|
if (*wildstr == w_many)
|
||||||
|
continue;
|
||||||
|
if (*wildstr == w_one)
|
||||||
|
{
|
||||||
|
if (str == str_end)
|
||||||
|
return(-1);
|
||||||
|
INC_PTR(cs,str,str_end);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break; /* Not a wild character */
|
||||||
|
}
|
||||||
|
if (wildstr == wildend)
|
||||||
|
return(0); /* match if w_many is last */
|
||||||
|
if (str == str_end)
|
||||||
|
return(-1);
|
||||||
|
|
||||||
|
if ((cmp= *wildstr) == escape && wildstr+1 != wildend)
|
||||||
|
cmp= *++wildstr;
|
||||||
|
|
||||||
|
INC_PTR(cs,wildstr,wildend); /* This is compared through cmp */
|
||||||
|
cmp=likeconv(cs,cmp);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
while (str != str_end && (uchar) likeconv(cs,*str) != cmp)
|
||||||
|
str++;
|
||||||
|
if (str++ == str_end)
|
||||||
|
return(-1);
|
||||||
|
{
|
||||||
|
int tmp=my_wildcmp_bin(cs,str,str_end,wildstr,wildend,escape,w_one,
|
||||||
|
w_many);
|
||||||
|
if (tmp <= 0)
|
||||||
|
return(tmp);
|
||||||
|
}
|
||||||
|
} while (str != str_end && wildstr[0] != w_many);
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(str != str_end ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static size_t my_strnxfrm_bin(CHARSET_INFO *cs __attribute__((unused)),
|
||||||
|
uchar *dest, size_t dstlen,
|
||||||
|
const uchar *src, size_t srclen)
|
||||||
|
{
|
||||||
|
if (dest != src)
|
||||||
|
memcpy(dest, src, min(dstlen,srclen));
|
||||||
|
if (dstlen > srclen)
|
||||||
|
bfill(dest + srclen, dstlen - srclen, 0);
|
||||||
|
return dstlen;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
size_t my_strnxfrm_8bit_bin(CHARSET_INFO *cs __attribute__((unused)),
|
||||||
|
uchar *dest, size_t dstlen,
|
||||||
|
const uchar *src, size_t srclen)
|
||||||
|
{
|
||||||
|
if (dest != src)
|
||||||
|
memcpy(dest, src, min(dstlen,srclen));
|
||||||
|
if (dstlen > srclen)
|
||||||
|
bfill(dest + srclen, dstlen - srclen, ' ');
|
||||||
|
return dstlen;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
uint my_instr_bin(CHARSET_INFO *cs __attribute__((unused)),
|
||||||
|
const char *b, size_t b_length,
|
||||||
|
const char *s, size_t s_length,
|
||||||
|
my_match_t *match, uint nmatch)
|
||||||
|
{
|
||||||
|
register const uchar *str, *search, *end, *search_end;
|
||||||
|
|
||||||
|
if (s_length <= b_length)
|
||||||
|
{
|
||||||
|
if (!s_length)
|
||||||
|
{
|
||||||
|
if (nmatch)
|
||||||
|
{
|
||||||
|
match->beg= 0;
|
||||||
|
match->end= 0;
|
||||||
|
match->mb_len= 0;
|
||||||
|
}
|
||||||
|
return 1; /* Empty string is always found */
|
||||||
|
}
|
||||||
|
|
||||||
|
str= (const uchar*) b;
|
||||||
|
search= (const uchar*) s;
|
||||||
|
end= (const uchar*) b+b_length-s_length+1;
|
||||||
|
search_end= (const uchar*) s + s_length;
|
||||||
|
|
||||||
|
skip:
|
||||||
|
while (str != end)
|
||||||
|
{
|
||||||
|
if ( (*str++) == (*search))
|
||||||
|
{
|
||||||
|
register const uchar *i,*j;
|
||||||
|
|
||||||
|
i= str;
|
||||||
|
j= search+1;
|
||||||
|
|
||||||
|
while (j != search_end)
|
||||||
|
if ((*i++) != (*j++))
|
||||||
|
goto skip;
|
||||||
|
|
||||||
|
if (nmatch > 0)
|
||||||
|
{
|
||||||
|
match[0].beg= 0;
|
||||||
|
match[0].end= (size_t) (str- (const uchar*)b-1);
|
||||||
|
match[0].mb_len= match[0].end;
|
||||||
|
|
||||||
|
if (nmatch > 1)
|
||||||
|
{
|
||||||
|
match[1].beg= match[0].end;
|
||||||
|
match[1].end= match[0].end+s_length;
|
||||||
|
match[1].mb_len= match[1].end-match[1].beg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MY_COLLATION_HANDLER my_collation_8bit_bin_handler =
|
||||||
|
{
|
||||||
|
my_coll_init_8bit_bin,
|
||||||
|
my_strnncoll_8bit_bin,
|
||||||
|
my_strnncollsp_8bit_bin,
|
||||||
|
my_strnxfrm_8bit_bin,
|
||||||
|
my_strnxfrmlen_simple,
|
||||||
|
my_like_range_simple,
|
||||||
|
my_wildcmp_bin,
|
||||||
|
my_strcasecmp_bin,
|
||||||
|
my_instr_bin,
|
||||||
|
my_hash_sort_8bit_bin,
|
||||||
|
my_propagate_simple
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static MY_COLLATION_HANDLER my_collation_binary_handler =
|
||||||
|
{
|
||||||
|
NULL, /* init */
|
||||||
|
my_strnncoll_binary,
|
||||||
|
my_strnncollsp_binary,
|
||||||
|
my_strnxfrm_bin,
|
||||||
|
my_strnxfrmlen_simple,
|
||||||
|
my_like_range_simple,
|
||||||
|
my_wildcmp_bin,
|
||||||
|
my_strcasecmp_bin,
|
||||||
|
my_instr_bin,
|
||||||
|
my_hash_sort_bin,
|
||||||
|
my_propagate_simple
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static MY_CHARSET_HANDLER my_charset_handler=
|
||||||
|
{
|
||||||
|
NULL, /* init */
|
||||||
|
NULL, /* ismbchar */
|
||||||
|
my_mbcharlen_8bit, /* mbcharlen */
|
||||||
|
my_numchars_8bit,
|
||||||
|
my_charpos_8bit,
|
||||||
|
my_well_formed_len_8bit,
|
||||||
|
my_lengthsp_binary,
|
||||||
|
my_numcells_8bit,
|
||||||
|
my_mb_wc_bin,
|
||||||
|
my_wc_mb_bin,
|
||||||
|
my_mb_ctype_8bit,
|
||||||
|
my_case_str_bin,
|
||||||
|
my_case_str_bin,
|
||||||
|
my_case_bin,
|
||||||
|
my_case_bin,
|
||||||
|
my_snprintf_8bit,
|
||||||
|
my_long10_to_str_8bit,
|
||||||
|
my_longlong10_to_str_8bit,
|
||||||
|
my_fill_8bit,
|
||||||
|
my_strntol_8bit,
|
||||||
|
my_strntoul_8bit,
|
||||||
|
my_strntoll_8bit,
|
||||||
|
my_strntoull_8bit,
|
||||||
|
my_strntod_8bit,
|
||||||
|
my_strtoll10_8bit,
|
||||||
|
my_strntoull10rnd_8bit,
|
||||||
|
my_scan_8bit
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
CHARSET_INFO my_charset_bin =
|
||||||
|
{
|
||||||
|
63,0,0, /* number */
|
||||||
|
MY_CS_COMPILED|MY_CS_BINSORT|MY_CS_PRIMARY,/* state */
|
||||||
|
"binary", /* cs name */
|
||||||
|
"binary", /* name */
|
||||||
|
"", /* comment */
|
||||||
|
NULL, /* tailoring */
|
||||||
|
ctype_bin, /* ctype */
|
||||||
|
bin_char_array, /* to_lower */
|
||||||
|
bin_char_array, /* to_upper */
|
||||||
|
NULL, /* sort_order */
|
||||||
|
NULL, /* contractions */
|
||||||
|
NULL, /* sort_order_big*/
|
||||||
|
NULL, /* tab_to_uni */
|
||||||
|
NULL, /* tab_from_uni */
|
||||||
|
my_unicase_default, /* caseinfo */
|
||||||
|
NULL, /* state_map */
|
||||||
|
NULL, /* ident_map */
|
||||||
|
1, /* strxfrm_multiply */
|
||||||
|
1, /* caseup_multiply */
|
||||||
|
1, /* casedn_multiply */
|
||||||
|
1, /* mbminlen */
|
||||||
|
1, /* mbmaxlen */
|
||||||
|
0, /* min_sort_char */
|
||||||
|
255, /* max_sort_char */
|
||||||
|
0, /* pad char */
|
||||||
|
0, /* escape_with_backslash_is_dangerous */
|
||||||
|
&my_charset_handler,
|
||||||
|
&my_collation_binary_handler
|
||||||
|
};
|
5575
MySQL/ctype-cp932.c
Normal file
5575
MySQL/ctype-cp932.c
Normal file
File diff suppressed because it is too large
Load Diff
639
MySQL/ctype-czech.c
Normal file
639
MySQL/ctype-czech.c
Normal file
@ -0,0 +1,639 @@
|
|||||||
|
/* Copyright (C) 2000 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
/* File strings/ctype-czech.c for MySQL.
|
||||||
|
|
||||||
|
This file implements the Czech sorting for the MySQL database
|
||||||
|
server (www.mysql.com). Due to some complicated rules the
|
||||||
|
Czech language has for sorting strings, a more complex
|
||||||
|
solution was needed than the one-to-one conversion table. To
|
||||||
|
note a few, here is an example of a Czech sorting sequence:
|
||||||
|
|
||||||
|
co < hlaska < hláska < hlava < chlapec < krtek
|
||||||
|
|
||||||
|
It because some of the rules are: double char 'ch' is sorted
|
||||||
|
between 'h' and 'i'. Accented character 'á' (a with acute) is
|
||||||
|
sorted after 'a' and before 'b', but only if the word is
|
||||||
|
otherwise the same. However, because 's' is sorted before 'v'
|
||||||
|
in hlava, the accentness of 'á' is overridden. There are many
|
||||||
|
more rules.
|
||||||
|
|
||||||
|
This file defines functions my_strxfrm and my_strcoll for
|
||||||
|
C-like zero terminated strings and my_strnxfrm and my_strnncoll
|
||||||
|
for strings where the length comes as an parameter. Also
|
||||||
|
defined here you will find function my_like_range that returns
|
||||||
|
index range strings for LIKE expression and the
|
||||||
|
MY_STRXFRM_MULTIPLY set to value 4 -- this is the ratio the
|
||||||
|
strings grows during my_strxfrm. The algorithm has four
|
||||||
|
passes, that's why we need four times more space for expanded
|
||||||
|
string.
|
||||||
|
|
||||||
|
This file also contains the ISO-Latin-2 definitions of
|
||||||
|
characters.
|
||||||
|
|
||||||
|
Author: (c) 1997--1998 Jan Pazdziora, adelton@fi.muni.cz
|
||||||
|
Jan Pazdziora has a shared copyright for this code
|
||||||
|
|
||||||
|
The original of this file can also be found at
|
||||||
|
http://www.fi.muni.cz/~adelton/l10n/
|
||||||
|
|
||||||
|
Bug reports and suggestions are always welcome.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This comment is parsed by configure to create ctype.c,
|
||||||
|
* so don't change it unless you know what you are doing.
|
||||||
|
*
|
||||||
|
* .configure. strxfrm_multiply_czech=4
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define SKIP_TRAILING_SPACES 1
|
||||||
|
|
||||||
|
#define REAL_MYSQL
|
||||||
|
|
||||||
|
#ifdef REAL_MYSQL
|
||||||
|
|
||||||
|
#include <my_global.h>
|
||||||
|
#include "m_string.h"
|
||||||
|
#include "m_ctype.h"
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#define uchar unsigned char
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_CHARSET_latin2
|
||||||
|
|
||||||
|
/*
|
||||||
|
These are four tables for four passes of the algorithm. Please see
|
||||||
|
below for what are the "special values"
|
||||||
|
*/
|
||||||
|
|
||||||
|
static uchar *CZ_SORT_TABLE[] = {
|
||||||
|
(uchar*) "\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\043\044\045\046\047\050\051\052\053\054\000\000\000\000\000\000\000\003\004\377\007\010\011\012\013\015\016\017\020\022\023\024\025\026\027\031\033\034\035\036\037\040\041\000\000\000\000\000\000\003\004\377\007\010\011\012\013\015\016\017\020\022\023\024\025\026\027\031\033\034\035\036\037\040\041\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\000\021\000\020\032\000\000\032\032\033\042\000\042\042\000\003\000\021\000\020\032\000\000\032\032\033\042\000\042\042\027\003\003\003\003\020\006\006\006\010\010\010\010\015\015\007\007\023\023\024\024\024\024\000\030\034\034\034\034\040\033\000\027\003\003\003\003\020\006\006\006\010\010\010\010\015\015\007\007\023\023\024\024\024\024\000\030\034\034\034\034\040\033\000",
|
||||||
|
(uchar*) "\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\106\107\110\111\112\113\114\115\116\117\000\000\000\000\000\000\000\003\011\377\016\021\026\027\030\032\035\036\037\043\044\047\054\055\056\061\065\070\075\076\077\100\102\000\000\000\000\000\000\003\011\377\016\021\026\027\030\032\035\036\037\043\044\047\054\055\056\061\065\070\075\076\077\100\102\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\010\000\042\000\041\063\000\000\062\064\066\104\000\103\105\000\010\000\042\000\041\063\000\000\062\064\066\104\000\103\105\057\004\005\007\006\040\014\015\013\022\025\024\023\033\034\017\020\046\045\050\051\053\052\000\060\072\071\074\073\101\067\000\057\004\005\007\006\040\014\015\013\022\025\024\023\033\034\017\020\046\045\050\051\053\052\000\060\072\071\074\073\101\067\000",
|
||||||
|
(uchar*) "\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\212\213\214\215\216\217\220\221\222\223\000\000\000\000\000\000\000\004\020\377\032\040\052\054\056\063\071\073\075\105\107\115\127\131\133\141\151\157\171\173\175\177\203\000\000\000\000\000\000\003\017\377\031\037\051\053\055\062\070\072\074\104\106\114\126\130\132\140\150\156\170\172\174\176\202\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\103\000\101\145\000\000\143\147\153\207\000\205\211\000\015\000\102\000\100\144\000\000\142\146\152\206\000\204\210\135\006\010\014\012\077\026\030\024\042\050\046\044\065\067\034\036\113\111\117\121\125\123\000\137\163\161\167\165\201\155\000\134\005\007\013\011\076\025\027\023\041\047\045\043\064\066\033\035\112\110\116\120\124\122\000\136\162\160\166\164\200\154\000",
|
||||||
|
(uchar*) "\264\265\266\267\270\271\272\273\274\002\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\002\230\232\253\324\252\251\234\240\241\261\260\225\262\224\235\212\213\214\215\216\217\220\221\222\223\231\226\244\257\245\227\250\004\020\377\032\040\052\054\056\063\071\073\075\105\107\115\127\131\133\141\151\157\171\173\175\177\203\242\237\243\254\255\233\003\017\377\031\037\051\053\055\062\070\072\074\104\106\114\126\130\132\140\150\156\170\172\174\176\202\246\236\247\256\325\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\326\016\327\103\330\101\145\331\332\143\147\153\207\333\205\211\334\015\335\102\336\100\144\337\340\142\146\152\206\341\204\210\135\006\010\014\012\077\026\030\024\042\050\046\044\065\067\034\036\113\111\117\121\125\123\263\137\163\161\167\165\201\155\342\134\005\007\013\011\076\025\027\023\041\047\045\043\064\066\033\035\112\110\116\120\124\122\343\136\162\160\166\164\200\154\344",
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
These define the valuse for the double chars that need to be
|
||||||
|
sorted as they were single characters -- in Czech these are
|
||||||
|
'ch', 'Ch' and 'CH'.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct wordvalue
|
||||||
|
{
|
||||||
|
const char * word;
|
||||||
|
uchar *outvalue;
|
||||||
|
};
|
||||||
|
static struct wordvalue doubles[] = {
|
||||||
|
{ "ch", (uchar*) "\014\031\057\057" },
|
||||||
|
{ "Ch", (uchar*) "\014\031\060\060" },
|
||||||
|
{ "CH", (uchar*) "\014\031\061\061" },
|
||||||
|
{ "c", (uchar*) "\005\012\021\021" },
|
||||||
|
{ "C", (uchar*) "\005\012\022\022" },
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Unformal description of the algorithm:
|
||||||
|
|
||||||
|
We walk the string left to right.
|
||||||
|
|
||||||
|
The end of the string is either passed as parameter, or is
|
||||||
|
*p == 0. This is hidden in the IS_END macro.
|
||||||
|
|
||||||
|
In the first two passes, we compare word by word. So we make
|
||||||
|
first and second pass on the first word, first and second pass
|
||||||
|
on the second word, etc. If we come to the end of the string
|
||||||
|
during the first pass, we need to jump to the last word of the
|
||||||
|
second pass.
|
||||||
|
|
||||||
|
End of pass is marked with value 1 on the output.
|
||||||
|
|
||||||
|
For each character, we read it's value from the table.
|
||||||
|
|
||||||
|
If the value is ignore (0), we go straight to the next character.
|
||||||
|
|
||||||
|
If the value is space/end of word (2) and we are in the first
|
||||||
|
or second pass, we skip all characters having value 0 -- 2 and
|
||||||
|
switch the passwd.
|
||||||
|
|
||||||
|
If it's the compose character (255), we check if the double
|
||||||
|
exists behind it, find its value.
|
||||||
|
|
||||||
|
We append 0 to the end.
|
||||||
|
---
|
||||||
|
Neformální popis algoritmu:
|
||||||
|
|
||||||
|
Procházíme øetìzec zleva doprava.
|
||||||
|
|
||||||
|
Konec øetìzce je pøedán buï jako parametr, nebo je to *p == 0.
|
||||||
|
Toto je o¹etøeno makrem IS_END.
|
||||||
|
|
||||||
|
Pokud jsme do¹li na konec øetìzce pøi prùchodu 0, nejdeme na
|
||||||
|
zaèátek, ale na ulo¾enou pozici, proto¾e první a druhý prùchod
|
||||||
|
bì¾í souèasnì.
|
||||||
|
|
||||||
|
Konec vstupu (prùchodu) oznaèíme na výstupu hodnotou 1.
|
||||||
|
|
||||||
|
Pro ka¾dý znak øetìzce naèteme hodnotu z tøídící tabulky.
|
||||||
|
|
||||||
|
Jde-li o hodnotu ignorovat (0), skoèíme ihned na dal¹í znak..
|
||||||
|
|
||||||
|
Jde-li o hodnotu konec slova (2) a je to prùchod 0 nebo 1,
|
||||||
|
pøeskoèíme v¹echny dal¹í 0 -- 2 a prohodíme prùchody.
|
||||||
|
|
||||||
|
Jde-li o kompozitní znak (255), otestujeme, zda následuje
|
||||||
|
správný do dvojice, dohledáme správnou hodnotu.
|
||||||
|
|
||||||
|
Na konci pøipojíme znak 0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define ADD_TO_RESULT(dest, len, totlen, value) \
|
||||||
|
if ((totlen) < (len)) { dest[totlen] = value; } (totlen++);
|
||||||
|
#define IS_END(p, src, len) (((char *)p - (char *)src) >= (len))
|
||||||
|
|
||||||
|
#define NEXT_CMP_VALUE(src, p, store, pass, value, len) \
|
||||||
|
while (1) \
|
||||||
|
{ \
|
||||||
|
if (IS_END(p, src, len)) \
|
||||||
|
{ \
|
||||||
|
/* when we are at the end of string */ \
|
||||||
|
/* return either 0 for end of string */ \
|
||||||
|
/* or 1 for end of pass */ \
|
||||||
|
value= 0; \
|
||||||
|
if (pass != 3) \
|
||||||
|
{ \
|
||||||
|
p= (pass++ == 0) ? store : src; \
|
||||||
|
value = 1; \
|
||||||
|
} \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
/* not at end of string */ \
|
||||||
|
value = CZ_SORT_TABLE[pass][*p]; \
|
||||||
|
if (value == 0) \
|
||||||
|
{ p++; continue; } /* ignore value */ \
|
||||||
|
if (value == 2) /* space */ \
|
||||||
|
{ \
|
||||||
|
const uchar *tmp; \
|
||||||
|
const uchar *runner = ++p; \
|
||||||
|
while (!(IS_END(runner, src, len)) && (CZ_SORT_TABLE[pass][*runner] == 2)) \
|
||||||
|
runner++; /* skip all spaces */ \
|
||||||
|
if (IS_END(runner, src, len) && SKIP_TRAILING_SPACES) \
|
||||||
|
p = runner; \
|
||||||
|
if ((pass <= 2) && !(IS_END(runner, src, len))) \
|
||||||
|
p = runner; \
|
||||||
|
if (IS_END(p, src, len)) \
|
||||||
|
continue; \
|
||||||
|
/* we switch passes */ \
|
||||||
|
if (pass > 1) \
|
||||||
|
break; \
|
||||||
|
tmp = p; \
|
||||||
|
pass= 1-pass; \
|
||||||
|
p = store; store = tmp; \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
if (value == 255) \
|
||||||
|
{ \
|
||||||
|
int i; \
|
||||||
|
for (i = 0; i < (int) sizeof(doubles); i++) \
|
||||||
|
{ \
|
||||||
|
const char * pattern = doubles[i].word; \
|
||||||
|
const char * q = (const char *) p; \
|
||||||
|
int j = 0; \
|
||||||
|
while (pattern[j]) \
|
||||||
|
{ \
|
||||||
|
if (IS_END(q, src, len) || (*q != pattern[j])) \
|
||||||
|
break; \
|
||||||
|
j++; q++; \
|
||||||
|
} \
|
||||||
|
if (!(pattern[j])) \
|
||||||
|
{ \
|
||||||
|
value = (int)(doubles[i].outvalue[pass]); \
|
||||||
|
p= (const uchar *) q - 1; \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
p++; \
|
||||||
|
break; \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function strnncoll, actually strcoll, with Czech sorting, which expect
|
||||||
|
the length of the strings being specified
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int my_strnncoll_czech(CHARSET_INFO *cs __attribute__((unused)),
|
||||||
|
const uchar *s1, size_t len1,
|
||||||
|
const uchar *s2, size_t len2,
|
||||||
|
my_bool s2_is_prefix)
|
||||||
|
{
|
||||||
|
int v1, v2;
|
||||||
|
const uchar *p1, * p2, * store1, * store2;
|
||||||
|
int pass1 = 0, pass2 = 0;
|
||||||
|
|
||||||
|
if (s2_is_prefix && len1 > len2)
|
||||||
|
len1=len2;
|
||||||
|
|
||||||
|
p1 = s1; p2 = s2;
|
||||||
|
store1 = s1; store2 = s2;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
int diff;
|
||||||
|
NEXT_CMP_VALUE(s1, p1, store1, pass1, v1, (int)len1);
|
||||||
|
NEXT_CMP_VALUE(s2, p2, store2, pass2, v2, (int)len2);
|
||||||
|
if ((diff = v1 - v2))
|
||||||
|
return diff;
|
||||||
|
}
|
||||||
|
while (v1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
TODO: Fix this one to compare strings as they are done in ctype-simple1
|
||||||
|
*/
|
||||||
|
|
||||||
|
static
|
||||||
|
int my_strnncollsp_czech(CHARSET_INFO * cs,
|
||||||
|
const uchar *s, size_t slen,
|
||||||
|
const uchar *t, size_t tlen,
|
||||||
|
my_bool diff_if_only_endspace_difference
|
||||||
|
__attribute__((unused)))
|
||||||
|
{
|
||||||
|
for ( ; slen && s[slen-1] == ' ' ; slen--);
|
||||||
|
for ( ; tlen && t[tlen-1] == ' ' ; tlen--);
|
||||||
|
return my_strnncoll_czech(cs,s,slen,t,tlen,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function strnxfrm, actually strxfrm, with Czech sorting, which expect
|
||||||
|
the length of the strings being specified
|
||||||
|
*/
|
||||||
|
|
||||||
|
static size_t my_strnxfrm_czech(CHARSET_INFO *cs __attribute__((unused)),
|
||||||
|
uchar *dest, size_t len,
|
||||||
|
const uchar *src, size_t srclen)
|
||||||
|
{
|
||||||
|
int value;
|
||||||
|
const uchar *p, * store;
|
||||||
|
int pass = 0;
|
||||||
|
size_t totlen = 0;
|
||||||
|
p = src; store = src;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
NEXT_CMP_VALUE(src, p, store, pass, value, (int)srclen);
|
||||||
|
ADD_TO_RESULT(dest, len, totlen, value);
|
||||||
|
}
|
||||||
|
while (value);
|
||||||
|
if (len > totlen)
|
||||||
|
bfill(dest + totlen, len - totlen, ' ');
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef IS_END
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Neformální popis algoritmu:
|
||||||
|
|
||||||
|
procházíme øetìzec zleva doprava
|
||||||
|
konec øetìzce poznáme podle *p == 0
|
||||||
|
pokud jsme do¹li na konec øetìzce pøi prùchodu 0, nejdeme na
|
||||||
|
zaèátek, ale na ulo¾enou pozici, proto¾e první a druhý
|
||||||
|
prùchod bì¾í souèasnì
|
||||||
|
konec vstupu (prùchodu) oznaèíme na výstupu hodnotou 1
|
||||||
|
|
||||||
|
naèteme hodnotu z tøídící tabulky
|
||||||
|
jde-li o hodnotu ignorovat (0), skoèíme na dal¹í prùchod
|
||||||
|
jde-li o hodnotu konec slova (2) a je to prùchod 0 nebo 1,
|
||||||
|
pøeskoèíme v¹echny dal¹í 0 -- 2 a prohodíme
|
||||||
|
prùchody
|
||||||
|
jde-li o kompozitní znak (255), otestujeme, zda následuje
|
||||||
|
správný do dvojice, dohledáme správnou hodnotu
|
||||||
|
|
||||||
|
na konci pøipojíme znak 0
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Calculate min_str and max_str that ranges a LIKE string.
|
||||||
|
** Arguments:
|
||||||
|
** ptr Pointer to LIKE string.
|
||||||
|
** ptr_length Length of LIKE string.
|
||||||
|
** escape Escape character in LIKE. (Normally '\').
|
||||||
|
** All escape characters should be removed from min_str and max_str
|
||||||
|
** res_length Length of min_str and max_str.
|
||||||
|
** min_str Smallest case sensitive string that ranges LIKE.
|
||||||
|
** Should be space padded to res_length.
|
||||||
|
** max_str Largest case sensitive string that ranges LIKE.
|
||||||
|
** Normally padded with the biggest character sort value.
|
||||||
|
**
|
||||||
|
** The function should return 0 if ok and 1 if the LIKE string can't be
|
||||||
|
** optimized !
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef REAL_MYSQL
|
||||||
|
|
||||||
|
#define min_sort_char ' '
|
||||||
|
#define max_sort_char '9'
|
||||||
|
|
||||||
|
#define EXAMPLE
|
||||||
|
|
||||||
|
static my_bool my_like_range_czech(CHARSET_INFO *cs __attribute__((unused)),
|
||||||
|
const char *ptr,size_t ptr_length,
|
||||||
|
pbool escape, pbool w_one, pbool w_many,
|
||||||
|
size_t res_length, char *min_str,
|
||||||
|
char *max_str,
|
||||||
|
size_t *min_length,size_t *max_length)
|
||||||
|
{
|
||||||
|
#ifdef EXAMPLE
|
||||||
|
uchar value;
|
||||||
|
const char *end=ptr+ptr_length;
|
||||||
|
char *min_org=min_str;
|
||||||
|
char *min_end=min_str+res_length;
|
||||||
|
|
||||||
|
for (; ptr != end && min_str != min_end ; ptr++)
|
||||||
|
{
|
||||||
|
if (*ptr == w_one) /* '_' in SQL */
|
||||||
|
{ break; }
|
||||||
|
if (*ptr == w_many) /* '%' in SQL */
|
||||||
|
{ break; }
|
||||||
|
|
||||||
|
if (*ptr == escape && ptr+1 != end)
|
||||||
|
{ ptr++; } /* Skip escape */
|
||||||
|
|
||||||
|
value = CZ_SORT_TABLE[0][(int) (uchar) *ptr];
|
||||||
|
|
||||||
|
if (value == 0) /* Ignore in the first pass */
|
||||||
|
{ continue; }
|
||||||
|
if (value <= 2) /* End of pass or end of string */
|
||||||
|
{ break; }
|
||||||
|
if (value == 255) /* Double char too compicated */
|
||||||
|
{ break; }
|
||||||
|
|
||||||
|
*min_str++= *max_str++ = *ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cs->state & MY_CS_BINSORT)
|
||||||
|
*min_length= (size_t) (min_str - min_org);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* 'a\0\0... is the smallest possible string */
|
||||||
|
*min_length= res_length;
|
||||||
|
}
|
||||||
|
/* a\ff\ff... is the biggest possible string */
|
||||||
|
*max_length= res_length;
|
||||||
|
|
||||||
|
while (min_str != min_end)
|
||||||
|
{
|
||||||
|
*min_str++ = min_sort_char; /* Because of key compression */
|
||||||
|
*max_str++ = max_sort_char;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
return 1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef REAL_MYSQL
|
||||||
|
/* This is a latin2 file */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* File generated by cset
|
||||||
|
* (C) Abandoned 1997 Zarko Mocnik <zarko.mocnik@dem.si>
|
||||||
|
*
|
||||||
|
* definition table reworked by Jaromir Dolecek <dolecek@ics.muni.cz>
|
||||||
|
*/
|
||||||
|
#include <my_global.h>
|
||||||
|
#include "m_string.h"
|
||||||
|
|
||||||
|
static uchar NEAR ctype_czech[257] = {
|
||||||
|
0,
|
||||||
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 32, 32,
|
||||||
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
||||||
|
72, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||||
|
132,132,132,132,132,132,132,132,132,132, 16, 16, 16, 16, 16, 16,
|
||||||
|
16,129,129,129,129,129,129, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16, 16, 16, 16, 16,
|
||||||
|
16,130,130,130,130,130,130, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 16, 16, 16, 16, 32,
|
||||||
|
32, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 32, 32, 32,
|
||||||
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 72,
|
||||||
|
1, 16, 1, 16, 1, 1, 16, 0, 0, 1, 1, 1, 1, 16, 1, 1,
|
||||||
|
16, 2, 16, 2, 16, 2, 2, 16, 16, 2, 2, 2, 2, 16, 2, 2,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
16, 1, 1, 1, 1, 1, 1, 16, 1, 1, 1, 1, 1, 1, 1, 16,
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 16, 2, 2, 2, 2, 2, 2, 2, 16,
|
||||||
|
};
|
||||||
|
|
||||||
|
static uchar NEAR to_lower_czech[] = {
|
||||||
|
0, 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, 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, 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,
|
||||||
|
177,161,179,163,181,182,166,167,168,185,186,187,188,173,190,191,
|
||||||
|
176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
|
||||||
|
224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
|
||||||
|
208,241,242,243,244,245,246,215,248,249,250,251,252,253,254,223,
|
||||||
|
224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
|
||||||
|
240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,
|
||||||
|
};
|
||||||
|
|
||||||
|
static uchar NEAR to_upper_czech[] = {
|
||||||
|
0, 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, 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,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,171,172,173,174,175,
|
||||||
|
176,160,178,162,180,164,165,183,184,169,170,171,172,189,174,175,
|
||||||
|
192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
|
||||||
|
208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
|
||||||
|
192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
|
||||||
|
240,209,210,211,212,213,214,247,216,217,218,219,220,221,222,255,
|
||||||
|
};
|
||||||
|
|
||||||
|
static uchar NEAR sort_order_czech[] = {
|
||||||
|
0, 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, 71, 72, 76, 78, 83, 84, 85, 86, 90, 91, 92, 96, 97,100,
|
||||||
|
105,106,107,110,114,117,122,123,124,125,127,131,132,133,134,135,
|
||||||
|
136, 65, 71, 72, 76, 78, 83, 84, 85, 86, 90, 91, 92, 96, 97,100,
|
||||||
|
105,106,107,110,114,117,122,123,124,125,127,137,138,139,140, 0,
|
||||||
|
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,255,
|
||||||
|
66,255, 93,255, 94,111,255,255,255,112,113,115,128,255,129,130,
|
||||||
|
255, 66,255, 93,255, 94,111,255,255,112,113,115,128,255,129,130,
|
||||||
|
108, 67, 68, 69, 70, 95, 73, 75, 74, 79, 81, 82, 80, 89, 87, 77,
|
||||||
|
255, 98, 99,101,102,103,104,255,109,119,118,120,121,126,116,255,
|
||||||
|
108, 67, 68, 69, 70, 95, 73, 75, 74, 79, 81, 82, 80, 89, 88, 77,
|
||||||
|
255, 98, 99,101,102,103,104,255,109,119,118,120,121,126,116,255,
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint16 tab_8859_2_uni[256]={
|
||||||
|
0,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,
|
||||||
|
0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F,
|
||||||
|
0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,
|
||||||
|
0x0018,0x0019,0x001A,0x001B,0x001C,0x001D,0x001E,0x001F,
|
||||||
|
0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,
|
||||||
|
0x0028,0x0029,0x002A,0x002B,0x002C,0x002D,0x002E,0x002F,
|
||||||
|
0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,
|
||||||
|
0x0038,0x0039,0x003A,0x003B,0x003C,0x003D,0x003E,0x003F,
|
||||||
|
0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,
|
||||||
|
0x0048,0x0049,0x004A,0x004B,0x004C,0x004D,0x004E,0x004F,
|
||||||
|
0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,
|
||||||
|
0x0058,0x0059,0x005A,0x005B,0x005C,0x005D,0x005E,0x005F,
|
||||||
|
0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,
|
||||||
|
0x0068,0x0069,0x006A,0x006B,0x006C,0x006D,0x006E,0x006F,
|
||||||
|
0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,
|
||||||
|
0x0078,0x0079,0x007A,0x007B,0x007C,0x007D,0x007E, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0x00A0,0x0104,0x02D8,0x0141,0x00A4,0x013D,0x015A,0x00A7,
|
||||||
|
0x00A8,0x0160,0x015E,0x0164,0x0179,0x00AD,0x017D,0x017B,
|
||||||
|
0x00B0,0x0105,0x02DB,0x0142,0x00B4,0x013E,0x015B,0x02C7,
|
||||||
|
0x00B8,0x0161,0x015F,0x0165,0x017A,0x02DD,0x017E,0x017C,
|
||||||
|
0x0154,0x00C1,0x00C2,0x0102,0x00C4,0x0139,0x0106,0x00C7,
|
||||||
|
0x010C,0x00C9,0x0118,0x00CB,0x011A,0x00CD,0x00CE,0x010E,
|
||||||
|
0x0110,0x0143,0x0147,0x00D3,0x00D4,0x0150,0x00D6,0x00D7,
|
||||||
|
0x0158,0x016E,0x00DA,0x0170,0x00DC,0x00DD,0x0162,0x00DF,
|
||||||
|
0x0155,0x00E1,0x00E2,0x0103,0x00E4,0x013A,0x0107,0x00E7,
|
||||||
|
0x010D,0x00E9,0x0119,0x00EB,0x011B,0x00ED,0x00EE,0x010F,
|
||||||
|
0x0111,0x0144,0x0148,0x00F3,0x00F4,0x0151,0x00F6,0x00F7,
|
||||||
|
0x0159,0x016F,0x00FA,0x0171,0x00FC,0x00FD,0x0163,0x02D9
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* 0000-00FD , 254 chars */
|
||||||
|
static uchar tab_uni_8859_2_plane00[]={
|
||||||
|
0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
|
||||||
|
0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
|
||||||
|
0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
|
||||||
|
0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
|
||||||
|
0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,
|
||||||
|
0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F,
|
||||||
|
0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
|
||||||
|
0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0xA0,0x00,0x00,0x00,0xA4,0x00,0x00,0xA7,0xA8,0x00,0x00,0x00,0x00,0xAD,0x00,0x00,
|
||||||
|
0xB0,0x00,0x00,0x00,0xB4,0x00,0x00,0x00,0xB8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0xC1,0xC2,0x00,0xC4,0x00,0x00,0xC7,0x00,0xC9,0x00,0xCB,0x00,0xCD,0xCE,0x00,
|
||||||
|
0x00,0x00,0x00,0xD3,0xD4,0x00,0xD6,0xD7,0x00,0x00,0xDA,0x00,0xDC,0xDD,0x00,0xDF,
|
||||||
|
0x00,0xE1,0xE2,0x00,0xE4,0x00,0x00,0xE7,0x00,0xE9,0x00,0xEB,0x00,0xED,0xEE,0x00,
|
||||||
|
0x00,0x00,0x00,0xF3,0xF4,0x00,0xF6,0xF7,0x00,0x00,0xFA,0x00,0xFC,0xFD};
|
||||||
|
|
||||||
|
/* 0102-017E , 125 chars */
|
||||||
|
static uchar tab_uni_8859_2_plane01[]={
|
||||||
|
0xC3,0xE3,0xA1,0xB1,0xC6,0xE6,0x00,0x00,0x00,0x00,0xC8,0xE8,0xCF,0xEF,0xD0,0xF0,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0xCA,0xEA,0xCC,0xEC,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC5,0xE5,0x00,0x00,0xA5,0xB5,0x00,0x00,0xA3,
|
||||||
|
0xB3,0xD1,0xF1,0x00,0x00,0xD2,0xF2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xD5,0xF5,
|
||||||
|
0x00,0x00,0xC0,0xE0,0x00,0x00,0xD8,0xF8,0xA6,0xB6,0x00,0x00,0xAA,0xBA,0xA9,0xB9,
|
||||||
|
0xDE,0xFE,0xAB,0xBB,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xD9,0xF9,0xDB,0xFB,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xAC,0xBC,0xAF,0xBF,0xAE,0xBE};
|
||||||
|
|
||||||
|
/* 02C7-02DD , 23 chars */
|
||||||
|
static uchar tab_uni_8859_2_plane02[]={
|
||||||
|
0xB7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0xA2,0xFF,0x00,0xB2,0x00,0xBD};
|
||||||
|
|
||||||
|
static MY_UNI_IDX idx_uni_8859_2[]={
|
||||||
|
{0x0000,0x00FD,tab_uni_8859_2_plane00},
|
||||||
|
{0x0102,0x017E,tab_uni_8859_2_plane01},
|
||||||
|
{0x02C7,0x02DD,tab_uni_8859_2_plane02},
|
||||||
|
{0,0,NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static MY_COLLATION_HANDLER my_collation_latin2_czech_ci_handler =
|
||||||
|
{
|
||||||
|
NULL, /* init */
|
||||||
|
my_strnncoll_czech,
|
||||||
|
my_strnncollsp_czech,
|
||||||
|
my_strnxfrm_czech,
|
||||||
|
my_strnxfrmlen_simple,
|
||||||
|
my_like_range_czech,
|
||||||
|
my_wildcmp_bin,
|
||||||
|
my_strcasecmp_8bit,
|
||||||
|
my_instr_simple,
|
||||||
|
my_hash_sort_simple,
|
||||||
|
my_propagate_simple
|
||||||
|
};
|
||||||
|
|
||||||
|
CHARSET_INFO my_charset_latin2_czech_ci =
|
||||||
|
{
|
||||||
|
2,0,0, /* number */
|
||||||
|
MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_CSSORT, /* state */
|
||||||
|
"latin2", /* cs name */
|
||||||
|
"latin2_czech_cs", /* name */
|
||||||
|
"", /* comment */
|
||||||
|
NULL, /* tailoring */
|
||||||
|
ctype_czech,
|
||||||
|
to_lower_czech,
|
||||||
|
to_upper_czech,
|
||||||
|
sort_order_czech,
|
||||||
|
NULL, /* contractions */
|
||||||
|
NULL, /* sort_order_big*/
|
||||||
|
tab_8859_2_uni, /* tab_to_uni */
|
||||||
|
idx_uni_8859_2, /* tab_from_uni */
|
||||||
|
my_unicase_default, /* caseinfo */
|
||||||
|
NULL, /* state_map */
|
||||||
|
NULL, /* ident_map */
|
||||||
|
4, /* strxfrm_multiply */
|
||||||
|
1, /* caseup_multiply */
|
||||||
|
1, /* casedn_multiply */
|
||||||
|
1, /* mbminlen */
|
||||||
|
1, /* mbmaxlen */
|
||||||
|
0, /* min_sort_char */
|
||||||
|
0, /* max_sort_char */
|
||||||
|
' ', /* pad char */
|
||||||
|
0, /* escape_with_backslash_is_dangerous */
|
||||||
|
&my_charset_8bit_handler,
|
||||||
|
&my_collation_latin2_czech_ci_handler
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
8805
MySQL/ctype-euc_kr.c
Normal file
8805
MySQL/ctype-euc_kr.c
Normal file
File diff suppressed because it is too large
Load Diff
8754
MySQL/ctype-eucjpms.c
Normal file
8754
MySQL/ctype-eucjpms.c
Normal file
File diff suppressed because it is too large
Load Diff
8715
MySQL/ctype-extra.c
Normal file
8715
MySQL/ctype-extra.c
Normal file
File diff suppressed because it is too large
Load Diff
5832
MySQL/ctype-gb2312.c
Normal file
5832
MySQL/ctype-gb2312.c
Normal file
File diff suppressed because it is too large
Load Diff
10091
MySQL/ctype-gbk.c
Normal file
10091
MySQL/ctype-gbk.c
Normal file
File diff suppressed because it is too large
Load Diff
783
MySQL/ctype-latin1.c
Normal file
783
MySQL/ctype-latin1.c
Normal file
@ -0,0 +1,783 @@
|
|||||||
|
/* Copyright (C) 2000 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
#include <my_global.h>
|
||||||
|
#include "m_string.h"
|
||||||
|
#include "m_ctype.h"
|
||||||
|
|
||||||
|
static uchar ctype_latin1[] = {
|
||||||
|
0,
|
||||||
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 32, 32,
|
||||||
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
||||||
|
72, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||||
|
132,132,132,132,132,132,132,132,132,132, 16, 16, 16, 16, 16, 16,
|
||||||
|
16,129,129,129,129,129,129, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16, 16, 16, 16, 16,
|
||||||
|
16,130,130,130,130,130,130, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 16, 16, 16, 16, 32,
|
||||||
|
16, 0, 16, 2, 16, 16, 16, 16, 16, 16, 1, 16, 1, 0, 1, 0,
|
||||||
|
0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2, 16, 2, 0, 2, 1,
|
||||||
|
72, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||||
|
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 16, 1, 1, 1, 1, 1, 1, 1, 2,
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 16, 2, 2, 2, 2, 2, 2, 2, 2
|
||||||
|
};
|
||||||
|
|
||||||
|
static uchar to_lower_latin1[] = {
|
||||||
|
0, 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, 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, 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,171,172,173,174,175,
|
||||||
|
176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
|
||||||
|
224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
|
||||||
|
240,241,242,243,244,245,246,215,248,249,250,251,252,253,254,223,
|
||||||
|
224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
|
||||||
|
240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255
|
||||||
|
};
|
||||||
|
|
||||||
|
static uchar to_upper_latin1[] = {
|
||||||
|
0, 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, 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,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,171,172,173,174,175,
|
||||||
|
176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
|
||||||
|
192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
|
||||||
|
208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
|
||||||
|
192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
|
||||||
|
208,209,210,211,212,213,214,247,216,217,218,219,220,221,222,255
|
||||||
|
};
|
||||||
|
|
||||||
|
static uchar sort_order_latin1[] = {
|
||||||
|
0, 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, 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,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,171,172,173,174,175,
|
||||||
|
176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
|
||||||
|
65, 65, 65, 65, 92, 91, 92, 67, 69, 69, 69, 69, 73, 73, 73, 73,
|
||||||
|
68, 78, 79, 79, 79, 79, 93,215,216, 85, 85, 85, 89, 89,222,223,
|
||||||
|
65, 65, 65, 65, 92, 91, 92, 67, 69, 69, 69, 69, 73, 73, 73, 73,
|
||||||
|
68, 78, 79, 79, 79, 79, 93,247,216, 85, 85, 85, 89, 89,222,255
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
WL#1494 notes:
|
||||||
|
|
||||||
|
We'll use cp1252 instead of iso-8859-1.
|
||||||
|
cp1252 contains printable characters in the range 0x80-0x9F.
|
||||||
|
In ISO 8859-1, these code points have no associated printable
|
||||||
|
characters. Therefore, by converting from CP1252 to ISO 8859-1,
|
||||||
|
one would lose the euro (for instance). Since most people are
|
||||||
|
unaware of the difference, and since we don't really want a
|
||||||
|
"Windows ANSI" to differ from a "Unix ANSI", we will:
|
||||||
|
|
||||||
|
- continue to pretend the latin1 character set is ISO 8859-1
|
||||||
|
- actually allow the storage of euro etc. so it's actually cp1252
|
||||||
|
|
||||||
|
Also we'll map these five undefined cp1252 character:
|
||||||
|
0x81, 0x8D, 0x8F, 0x90, 0x9D
|
||||||
|
into corresponding control characters:
|
||||||
|
U+0081, U+008D, U+008F, U+0090, U+009D.
|
||||||
|
like ISO-8859-1 does. Otherwise, loading "mysqldump"
|
||||||
|
output doesn't reproduce these undefined characters.
|
||||||
|
*/
|
||||||
|
|
||||||
|
unsigned short cs_to_uni[256]={
|
||||||
|
0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,
|
||||||
|
0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F,
|
||||||
|
0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,
|
||||||
|
0x0018,0x0019,0x001A,0x001B,0x001C,0x001D,0x001E,0x001F,
|
||||||
|
0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,
|
||||||
|
0x0028,0x0029,0x002A,0x002B,0x002C,0x002D,0x002E,0x002F,
|
||||||
|
0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,
|
||||||
|
0x0038,0x0039,0x003A,0x003B,0x003C,0x003D,0x003E,0x003F,
|
||||||
|
0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,
|
||||||
|
0x0048,0x0049,0x004A,0x004B,0x004C,0x004D,0x004E,0x004F,
|
||||||
|
0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,
|
||||||
|
0x0058,0x0059,0x005A,0x005B,0x005C,0x005D,0x005E,0x005F,
|
||||||
|
0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,
|
||||||
|
0x0068,0x0069,0x006A,0x006B,0x006C,0x006D,0x006E,0x006F,
|
||||||
|
0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,
|
||||||
|
0x0078,0x0079,0x007A,0x007B,0x007C,0x007D,0x007E,0x007F,
|
||||||
|
0x20AC,0x0081,0x201A,0x0192,0x201E,0x2026,0x2020,0x2021,
|
||||||
|
0x02C6,0x2030,0x0160,0x2039,0x0152,0x008D,0x017D,0x008F,
|
||||||
|
0x0090,0x2018,0x2019,0x201C,0x201D,0x2022,0x2013,0x2014,
|
||||||
|
0x02DC,0x2122,0x0161,0x203A,0x0153,0x009D,0x017E,0x0178,
|
||||||
|
0x00A0,0x00A1,0x00A2,0x00A3,0x00A4,0x00A5,0x00A6,0x00A7,
|
||||||
|
0x00A8,0x00A9,0x00AA,0x00AB,0x00AC,0x00AD,0x00AE,0x00AF,
|
||||||
|
0x00B0,0x00B1,0x00B2,0x00B3,0x00B4,0x00B5,0x00B6,0x00B7,
|
||||||
|
0x00B8,0x00B9,0x00BA,0x00BB,0x00BC,0x00BD,0x00BE,0x00BF,
|
||||||
|
0x00C0,0x00C1,0x00C2,0x00C3,0x00C4,0x00C5,0x00C6,0x00C7,
|
||||||
|
0x00C8,0x00C9,0x00CA,0x00CB,0x00CC,0x00CD,0x00CE,0x00CF,
|
||||||
|
0x00D0,0x00D1,0x00D2,0x00D3,0x00D4,0x00D5,0x00D6,0x00D7,
|
||||||
|
0x00D8,0x00D9,0x00DA,0x00DB,0x00DC,0x00DD,0x00DE,0x00DF,
|
||||||
|
0x00E0,0x00E1,0x00E2,0x00E3,0x00E4,0x00E5,0x00E6,0x00E7,
|
||||||
|
0x00E8,0x00E9,0x00EA,0x00EB,0x00EC,0x00ED,0x00EE,0x00EF,
|
||||||
|
0x00F0,0x00F1,0x00F2,0x00F3,0x00F4,0x00F5,0x00F6,0x00F7,
|
||||||
|
0x00F8,0x00F9,0x00FA,0x00FB,0x00FC,0x00FD,0x00FE,0x00FF
|
||||||
|
};
|
||||||
|
uchar pl00[256]={
|
||||||
|
0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
|
||||||
|
0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
|
||||||
|
0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
|
||||||
|
0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
|
||||||
|
0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,
|
||||||
|
0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
|
||||||
|
0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
|
||||||
|
0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
|
||||||
|
0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,
|
||||||
|
0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,
|
||||||
|
0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,
|
||||||
|
0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F,
|
||||||
|
0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,
|
||||||
|
0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
|
||||||
|
0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,
|
||||||
|
0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,
|
||||||
|
0x00,0x81,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x8D,0x00,0x8F,
|
||||||
|
0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x9D,0x00,0x00,
|
||||||
|
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,
|
||||||
|
0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,
|
||||||
|
0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,
|
||||||
|
0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF,
|
||||||
|
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,
|
||||||
|
0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,
|
||||||
|
0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,
|
||||||
|
0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,
|
||||||
|
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,
|
||||||
|
0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,
|
||||||
|
0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,
|
||||||
|
0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF
|
||||||
|
};
|
||||||
|
uchar pl01[256]={
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x8C,0x9C,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x8A,0x9A,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x9F,0x00,0x00,0x00,0x00,0x8E,0x9E,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x83,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||||
|
};
|
||||||
|
uchar pl02[256]={
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x98,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||||
|
};
|
||||||
|
uchar pl20[256]={
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x96,0x97,0x00,0x00,0x00,
|
||||||
|
0x91,0x92,0x82,0x00,0x93,0x94,0x84,0x00,
|
||||||
|
0x86,0x87,0x95,0x00,0x00,0x00,0x85,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x89,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x8B,0x9B,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||||
|
};
|
||||||
|
uchar pl21[256]={
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x99,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||||
|
};
|
||||||
|
uchar *uni_to_cs[256]={
|
||||||
|
pl00,pl01,pl02,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
pl20,pl21,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
static
|
||||||
|
int my_mb_wc_latin1(CHARSET_INFO *cs __attribute__((unused)),
|
||||||
|
my_wc_t *wc,
|
||||||
|
const uchar *str,
|
||||||
|
const uchar *end __attribute__((unused)))
|
||||||
|
{
|
||||||
|
if (str >= end)
|
||||||
|
return MY_CS_TOOSMALL;
|
||||||
|
|
||||||
|
*wc=cs_to_uni[*str];
|
||||||
|
return (!wc[0] && str[0]) ? -1 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int my_wc_mb_latin1(CHARSET_INFO *cs __attribute__((unused)),
|
||||||
|
my_wc_t wc,
|
||||||
|
uchar *str,
|
||||||
|
uchar *end __attribute__((unused)))
|
||||||
|
{
|
||||||
|
uchar *pl;
|
||||||
|
|
||||||
|
if (str >= end)
|
||||||
|
return MY_CS_TOOSMALL;
|
||||||
|
|
||||||
|
pl= uni_to_cs[(wc>>8) & 0xFF];
|
||||||
|
str[0]= pl ? pl[wc & 0xFF] : '\0';
|
||||||
|
return (!str[0] && wc) ? MY_CS_ILUNI : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static MY_CHARSET_HANDLER my_charset_handler=
|
||||||
|
{
|
||||||
|
NULL, /* init */
|
||||||
|
NULL,
|
||||||
|
my_mbcharlen_8bit,
|
||||||
|
my_numchars_8bit,
|
||||||
|
my_charpos_8bit,
|
||||||
|
my_well_formed_len_8bit,
|
||||||
|
my_lengthsp_8bit,
|
||||||
|
my_numcells_8bit,
|
||||||
|
my_mb_wc_latin1,
|
||||||
|
my_wc_mb_latin1,
|
||||||
|
my_mb_ctype_8bit,
|
||||||
|
my_caseup_str_8bit,
|
||||||
|
my_casedn_str_8bit,
|
||||||
|
my_caseup_8bit,
|
||||||
|
my_casedn_8bit,
|
||||||
|
my_snprintf_8bit,
|
||||||
|
my_long10_to_str_8bit,
|
||||||
|
my_longlong10_to_str_8bit,
|
||||||
|
my_fill_8bit,
|
||||||
|
my_strntol_8bit,
|
||||||
|
my_strntoul_8bit,
|
||||||
|
my_strntoll_8bit,
|
||||||
|
my_strntoull_8bit,
|
||||||
|
my_strntod_8bit,
|
||||||
|
my_strtoll10_8bit,
|
||||||
|
my_strntoull10rnd_8bit,
|
||||||
|
my_scan_8bit
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
CHARSET_INFO my_charset_latin1=
|
||||||
|
{
|
||||||
|
8,0,0, /* number */
|
||||||
|
MY_CS_COMPILED | MY_CS_PRIMARY, /* state */
|
||||||
|
"latin1", /* cs name */
|
||||||
|
"latin1_swedish_ci", /* name */
|
||||||
|
"", /* comment */
|
||||||
|
NULL, /* tailoring */
|
||||||
|
ctype_latin1,
|
||||||
|
to_lower_latin1,
|
||||||
|
to_upper_latin1,
|
||||||
|
sort_order_latin1,
|
||||||
|
NULL, /* contractions */
|
||||||
|
NULL, /* sort_order_big*/
|
||||||
|
cs_to_uni, /* tab_to_uni */
|
||||||
|
NULL, /* tab_from_uni */
|
||||||
|
my_unicase_default, /* caseinfo */
|
||||||
|
NULL, /* state_map */
|
||||||
|
NULL, /* ident_map */
|
||||||
|
1, /* strxfrm_multiply */
|
||||||
|
1, /* caseup_multiply */
|
||||||
|
1, /* casedn_multiply */
|
||||||
|
1, /* mbminlen */
|
||||||
|
1, /* mbmaxlen */
|
||||||
|
0, /* min_sort_char */
|
||||||
|
255, /* max_sort_char */
|
||||||
|
' ', /* pad char */
|
||||||
|
0, /* escape_with_backslash_is_dangerous */
|
||||||
|
&my_charset_handler,
|
||||||
|
&my_collation_8bit_simple_ci_handler
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is the latin1 character set with German sorting
|
||||||
|
*
|
||||||
|
* The modern sort order is used, where:
|
||||||
|
*
|
||||||
|
* 'ä' -> "ae"
|
||||||
|
* 'ö' -> "oe"
|
||||||
|
* 'ü' -> "ue"
|
||||||
|
* 'ß' -> "ss"
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is a simple latin1 mapping table, which maps all accented
|
||||||
|
* characters to their non-accented equivalents. Note: in this
|
||||||
|
* table, 'ä' is mapped to 'A', 'ÿ' is mapped to 'Y', etc. - all
|
||||||
|
* accented characters except the following are treated the same way.
|
||||||
|
* Ü, ü, Ö, ö, Ä, ä
|
||||||
|
*/
|
||||||
|
|
||||||
|
static uchar sort_order_latin1_de[] = {
|
||||||
|
0, 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, 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,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,171,172,173,174,175,
|
||||||
|
176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
|
||||||
|
65, 65, 65, 65,196, 65, 92, 67, 69, 69, 69, 69, 73, 73, 73, 73,
|
||||||
|
68, 78, 79, 79, 79, 79,214,215,216, 85, 85, 85,220, 89,222,223,
|
||||||
|
65, 65, 65, 65,196, 65, 92, 67, 69, 69, 69, 69, 73, 73, 73, 73,
|
||||||
|
68, 78, 79, 79, 79, 79,214,247,216, 85, 85, 85,220, 89,222, 89
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
same as sort_order_latin_de, but maps ALL accented chars to unaccented ones
|
||||||
|
*/
|
||||||
|
|
||||||
|
uchar combo1map[]={
|
||||||
|
0, 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, 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,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,171,172,173,174,175,
|
||||||
|
176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
|
||||||
|
65, 65, 65, 65, 65, 65, 92, 67, 69, 69, 69, 69, 73, 73, 73, 73,
|
||||||
|
68, 78, 79, 79, 79, 79, 79,215,216, 85, 85, 85, 85, 89,222, 83,
|
||||||
|
65, 65, 65, 65, 65, 65, 92, 67, 69, 69, 69, 69, 73, 73, 73, 73,
|
||||||
|
68, 78, 79, 79, 79, 79, 79,247,216, 85, 85, 85, 85, 89,222, 89
|
||||||
|
};
|
||||||
|
|
||||||
|
uchar combo2map[]={
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,69, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0,69, 0, 0, 0, 0, 0,69, 0, 0,83, 0, 0, 0, 0,69, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,69, 0, 0, 0, 0, 0,69, 0, 0, 0, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Some notes about the following comparison rules:
|
||||||
|
By definition, my_strnncoll_latin_de must works exactly as if had called
|
||||||
|
my_strnxfrm_latin_de() on both strings and compared the result strings.
|
||||||
|
|
||||||
|
This means that:
|
||||||
|
Ä must also matches ÁE and Aè, because my_strxn_frm_latin_de() will convert
|
||||||
|
both to AE.
|
||||||
|
|
||||||
|
The other option would be to not do any accent removal in
|
||||||
|
sort_order_latin_de[] at all
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
static int my_strnncoll_latin1_de(CHARSET_INFO *cs __attribute__((unused)),
|
||||||
|
const uchar *a, size_t a_length,
|
||||||
|
const uchar *b, size_t b_length,
|
||||||
|
my_bool b_is_prefix)
|
||||||
|
{
|
||||||
|
const uchar *a_end= a + a_length;
|
||||||
|
const uchar *b_end= b + b_length;
|
||||||
|
uchar a_char, a_extend= 0, b_char, b_extend= 0;
|
||||||
|
|
||||||
|
while ((a < a_end || a_extend) && (b < b_end || b_extend))
|
||||||
|
{
|
||||||
|
if (a_extend)
|
||||||
|
{
|
||||||
|
a_char=a_extend; a_extend=0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
a_extend=combo2map[*a];
|
||||||
|
a_char=combo1map[*a++];
|
||||||
|
}
|
||||||
|
if (b_extend)
|
||||||
|
{
|
||||||
|
b_char=b_extend; b_extend=0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
b_extend=combo2map[*b];
|
||||||
|
b_char=combo1map[*b++];
|
||||||
|
}
|
||||||
|
if (a_char != b_char)
|
||||||
|
return (int) a_char - (int) b_char;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
A simple test of string lengths won't work -- we test to see
|
||||||
|
which string ran out first
|
||||||
|
*/
|
||||||
|
return ((a < a_end || a_extend) ? (b_is_prefix ? 0 : 1) :
|
||||||
|
(b < b_end || b_extend) ? -1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int my_strnncollsp_latin1_de(CHARSET_INFO *cs __attribute__((unused)),
|
||||||
|
const uchar *a, size_t a_length,
|
||||||
|
const uchar *b, size_t b_length,
|
||||||
|
my_bool diff_if_only_endspace_difference)
|
||||||
|
{
|
||||||
|
const uchar *a_end= a + a_length, *b_end= b + b_length;
|
||||||
|
uchar a_char, a_extend= 0, b_char, b_extend= 0;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
#ifndef VARCHAR_WITH_DIFF_ENDSPACE_ARE_DIFFERENT_FOR_UNIQUE
|
||||||
|
diff_if_only_endspace_difference= 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
while ((a < a_end || a_extend) && (b < b_end || b_extend))
|
||||||
|
{
|
||||||
|
if (a_extend)
|
||||||
|
{
|
||||||
|
a_char=a_extend;
|
||||||
|
a_extend= 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
a_extend= combo2map[*a];
|
||||||
|
a_char= combo1map[*a++];
|
||||||
|
}
|
||||||
|
if (b_extend)
|
||||||
|
{
|
||||||
|
b_char= b_extend;
|
||||||
|
b_extend= 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
b_extend= combo2map[*b];
|
||||||
|
b_char= combo1map[*b++];
|
||||||
|
}
|
||||||
|
if (a_char != b_char)
|
||||||
|
return (int) a_char - (int) b_char;
|
||||||
|
}
|
||||||
|
/* Check if double character last */
|
||||||
|
if (a_extend)
|
||||||
|
return 1;
|
||||||
|
if (b_extend)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
res= 0;
|
||||||
|
if (a != a_end || b != b_end)
|
||||||
|
{
|
||||||
|
int swap= 1;
|
||||||
|
if (diff_if_only_endspace_difference)
|
||||||
|
res= 1; /* Assume 'a' is bigger */
|
||||||
|
/*
|
||||||
|
Check the next not space character of the longer key. If it's < ' ',
|
||||||
|
then it's smaller than the other key.
|
||||||
|
*/
|
||||||
|
if (a == a_end)
|
||||||
|
{
|
||||||
|
/* put shorter key in a */
|
||||||
|
a_end= b_end;
|
||||||
|
a= b;
|
||||||
|
swap= -1; /* swap sign of result */
|
||||||
|
res= -res;
|
||||||
|
}
|
||||||
|
for ( ; a < a_end ; a++)
|
||||||
|
{
|
||||||
|
if (*a != ' ')
|
||||||
|
return (*a < ' ') ? -swap : swap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static size_t my_strnxfrm_latin1_de(CHARSET_INFO *cs __attribute__((unused)),
|
||||||
|
uchar *dest, size_t len,
|
||||||
|
const uchar *src, size_t srclen)
|
||||||
|
{
|
||||||
|
const uchar *de = dest + len;
|
||||||
|
const uchar *se = src + srclen;
|
||||||
|
for ( ; src < se && dest < de ; src++)
|
||||||
|
{
|
||||||
|
uchar chr=combo1map[*src];
|
||||||
|
*dest++=chr;
|
||||||
|
if ((chr=combo2map[*src]) && dest < de)
|
||||||
|
*dest++=chr;
|
||||||
|
}
|
||||||
|
if (dest < de)
|
||||||
|
bfill(dest, de - dest, ' ');
|
||||||
|
return (int) len;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void my_hash_sort_latin1_de(CHARSET_INFO *cs __attribute__((unused)),
|
||||||
|
const uchar *key, size_t len,
|
||||||
|
ulong *nr1, ulong *nr2)
|
||||||
|
{
|
||||||
|
const uchar *end= key+len;
|
||||||
|
/*
|
||||||
|
Remove end space. We have to do this to be able to compare
|
||||||
|
'AE' and 'Ä' as identical
|
||||||
|
*/
|
||||||
|
while (end > key && end[-1] == ' ')
|
||||||
|
end--;
|
||||||
|
|
||||||
|
for (; key < end ; key++)
|
||||||
|
{
|
||||||
|
uint X= (uint) combo1map[(uint) *key];
|
||||||
|
nr1[0]^=(ulong) ((((uint) nr1[0] & 63)+nr2[0]) * X) + (nr1[0] << 8);
|
||||||
|
nr2[0]+=3;
|
||||||
|
if ((X= combo2map[*key]))
|
||||||
|
{
|
||||||
|
nr1[0]^=(ulong) ((((uint) nr1[0] & 63)+nr2[0]) * X) + (nr1[0] << 8);
|
||||||
|
nr2[0]+=3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static MY_COLLATION_HANDLER my_collation_german2_ci_handler=
|
||||||
|
{
|
||||||
|
NULL, /* init */
|
||||||
|
my_strnncoll_latin1_de,
|
||||||
|
my_strnncollsp_latin1_de,
|
||||||
|
my_strnxfrm_latin1_de,
|
||||||
|
my_strnxfrmlen_simple,
|
||||||
|
my_like_range_simple,
|
||||||
|
my_wildcmp_8bit,
|
||||||
|
my_strcasecmp_8bit,
|
||||||
|
my_instr_simple,
|
||||||
|
my_hash_sort_latin1_de,
|
||||||
|
my_propagate_complex
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
CHARSET_INFO my_charset_latin1_german2_ci=
|
||||||
|
{
|
||||||
|
31,0,0, /* number */
|
||||||
|
MY_CS_COMPILED|MY_CS_STRNXFRM, /* state */
|
||||||
|
"latin1", /* cs name */
|
||||||
|
"latin1_german2_ci", /* name */
|
||||||
|
"", /* comment */
|
||||||
|
NULL, /* tailoring */
|
||||||
|
ctype_latin1,
|
||||||
|
to_lower_latin1,
|
||||||
|
to_upper_latin1,
|
||||||
|
sort_order_latin1_de,
|
||||||
|
NULL, /* contractions */
|
||||||
|
NULL, /* sort_order_big*/
|
||||||
|
cs_to_uni, /* tab_to_uni */
|
||||||
|
NULL, /* tab_from_uni */
|
||||||
|
my_unicase_default, /* caseinfo */
|
||||||
|
NULL, /* state_map */
|
||||||
|
NULL, /* ident_map */
|
||||||
|
2, /* strxfrm_multiply */
|
||||||
|
1, /* caseup_multiply */
|
||||||
|
1, /* casedn_multiply */
|
||||||
|
1, /* mbminlen */
|
||||||
|
1, /* mbmaxlen */
|
||||||
|
0, /* min_sort_char */
|
||||||
|
247, /* max_sort_char */
|
||||||
|
' ', /* pad char */
|
||||||
|
0, /* escape_with_backslash_is_dangerous */
|
||||||
|
&my_charset_handler,
|
||||||
|
&my_collation_german2_ci_handler
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
CHARSET_INFO my_charset_latin1_bin=
|
||||||
|
{
|
||||||
|
47,0,0, /* number */
|
||||||
|
MY_CS_COMPILED|MY_CS_BINSORT, /* state */
|
||||||
|
"latin1", /* cs name */
|
||||||
|
"latin1_bin", /* name */
|
||||||
|
"", /* comment */
|
||||||
|
NULL, /* tailoring */
|
||||||
|
ctype_latin1,
|
||||||
|
to_lower_latin1,
|
||||||
|
to_upper_latin1,
|
||||||
|
NULL, /* sort_order */
|
||||||
|
NULL, /* contractions */
|
||||||
|
NULL, /* sort_order_big*/
|
||||||
|
cs_to_uni, /* tab_to_uni */
|
||||||
|
NULL, /* tab_from_uni */
|
||||||
|
my_unicase_default, /* caseinfo */
|
||||||
|
NULL, /* state_map */
|
||||||
|
NULL, /* ident_map */
|
||||||
|
1, /* strxfrm_multiply */
|
||||||
|
1, /* caseup_multiply */
|
||||||
|
1, /* casedn_multiply */
|
||||||
|
1, /* mbminlen */
|
||||||
|
1, /* mbmaxlen */
|
||||||
|
0, /* min_sort_char */
|
||||||
|
255, /* max_sort_char */
|
||||||
|
' ', /* pad char */
|
||||||
|
0, /* escape_with_backslash_is_dangerous */
|
||||||
|
&my_charset_handler,
|
||||||
|
&my_collation_8bit_bin_handler
|
||||||
|
};
|
||||||
|
|
1058
MySQL/ctype-mb.c
Normal file
1058
MySQL/ctype-mb.c
Normal file
File diff suppressed because it is too large
Load Diff
1827
MySQL/ctype-simple.c
Normal file
1827
MySQL/ctype-simple.c
Normal file
File diff suppressed because it is too large
Load Diff
4736
MySQL/ctype-sjis.c
Normal file
4736
MySQL/ctype-sjis.c
Normal file
File diff suppressed because it is too large
Load Diff
965
MySQL/ctype-tis620.c
Normal file
965
MySQL/ctype-tis620.c
Normal file
@ -0,0 +1,965 @@
|
|||||||
|
/* Copyright (C) 2000-2003 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 by Sathit Jittanupat
|
||||||
|
<jsat66@hotmail.com,jsat66@yahoo.com>
|
||||||
|
* solving bug crash with long text field string
|
||||||
|
* sorting with different number of space or sign char. within string
|
||||||
|
|
||||||
|
Copyright (C) 2001 by Korakot Chaovavanich <korakot@iname.com> and
|
||||||
|
Apisilp Trunganont <apisilp@pantip.inet.co.th>
|
||||||
|
Copyright (C) 1998, 1999 by Pruet Boonma <pruet@eng.cmu.ac.th>
|
||||||
|
Copyright (C) 1998 by Theppitak Karoonboonyanan <thep@links.nectec.or.th>
|
||||||
|
Copyright (C) 1989, 1991 by Samphan Raruenrom <samphan@thai.com>
|
||||||
|
|
||||||
|
Permission to use, copy, modify, distribute and sell this software
|
||||||
|
and its documentation for any purpose is hereby granted without fee,
|
||||||
|
provided that the above copyright notice appear in all copies.
|
||||||
|
Samphan Raruenrom , Theppitak Karoonboonyanan , Pruet Boonma ,
|
||||||
|
Korakot Chaovavanich and Apisilp Trunganont makes no representations
|
||||||
|
about the suitability of this software for any purpose. It is provided
|
||||||
|
"as is" without express or implied warranty.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
This file is basicly tis620 character sets with some extra functions
|
||||||
|
for tis-620 handling
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This comment is parsed by configure to create ctype.c,
|
||||||
|
* so don't change it unless you know what you are doing.
|
||||||
|
*
|
||||||
|
* .configure. strxfrm_multiply_tis620=4
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <my_global.h>
|
||||||
|
#include <my_sys.h>
|
||||||
|
#include "m_string.h"
|
||||||
|
#include "m_ctype.h"
|
||||||
|
#include "t_ctype.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_CHARSET_tis620
|
||||||
|
|
||||||
|
#define BUFFER_MULTIPLY 4
|
||||||
|
#define M L_MIDDLE
|
||||||
|
#define U L_UPPER
|
||||||
|
#define L L_LOWER
|
||||||
|
#define UU L_UPRUPR
|
||||||
|
#define X L_MIDDLE
|
||||||
|
|
||||||
|
|
||||||
|
static int t_ctype[][TOT_LEVELS] = {
|
||||||
|
/*0x00*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x01*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x02*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x03*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x04*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x05*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x06*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x07*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x08*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x09*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x0A*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x0B*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x0C*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x0D*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x0E*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x0F*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x10*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x11*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x12*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x13*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x14*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x15*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x16*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x17*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x18*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x19*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x1A*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x1B*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x1C*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x1D*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x1E*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x1F*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x20*/ { IGNORE, IGNORE, L3_SPACE, IGNORE, M},
|
||||||
|
/*0x21*/ { IGNORE, IGNORE, L3_EXCLAMATION, IGNORE, M },
|
||||||
|
/*0x22*/ { IGNORE, IGNORE, L3_QUOTATION, IGNORE, M },
|
||||||
|
/*0x23*/ { IGNORE, IGNORE, L3_NUMBER, IGNORE, M },
|
||||||
|
/*0x24*/ { IGNORE, IGNORE, L3_DOLLAR, IGNORE, M },
|
||||||
|
/*0x25*/ { IGNORE, IGNORE, L3_PERCENT, IGNORE, M },
|
||||||
|
/*0x26*/ { IGNORE, IGNORE, L3_AMPERSAND, IGNORE, M },
|
||||||
|
/*0x27*/ { IGNORE, IGNORE, L3_APOSTROPHE, IGNORE, M },
|
||||||
|
/*0x28*/ { IGNORE, IGNORE, L3_L_PARANTHESIS, IGNORE, M },
|
||||||
|
/*0x29*/ { IGNORE, IGNORE, L3_R_PARENTHESIS, IGNORE, M },
|
||||||
|
/*0x2A*/ { IGNORE, IGNORE, L3_ASTERISK, IGNORE, M },
|
||||||
|
/*0x2B*/ { IGNORE, IGNORE, L3_PLUS, IGNORE, M },
|
||||||
|
/*0x2C*/ { IGNORE, IGNORE, L3_COMMA, IGNORE, M },
|
||||||
|
/*0x2D*/ { IGNORE, IGNORE, L3_HYPHEN, IGNORE, M },
|
||||||
|
/*0x2E*/ { IGNORE, IGNORE, L3_FULL_STOP, IGNORE, M },
|
||||||
|
/*0x2F*/ { IGNORE, IGNORE, L3_SOLIDUS, IGNORE, M },
|
||||||
|
/*0x30*/ { L1_08, L2_BLANK, L3_BLANK, L4_BLANK, M },
|
||||||
|
/*0x31*/ { L1_18, L2_BLANK, L3_BLANK, L4_BLANK, M },
|
||||||
|
/*0x32*/ { L1_28, L2_BLANK, L3_BLANK, L4_BLANK, M },
|
||||||
|
/*0x33*/ { L1_38, L2_BLANK, L3_BLANK, L4_BLANK, M },
|
||||||
|
/*0x34*/ { L1_48, L2_BLANK, L3_BLANK, L4_BLANK, M },
|
||||||
|
/*0x35*/ { L1_58, L2_BLANK, L3_BLANK, L4_BLANK, M },
|
||||||
|
/*0x36*/ { L1_68, L2_BLANK, L3_BLANK, L4_BLANK, M },
|
||||||
|
/*0x37*/ { L1_78, L2_BLANK, L3_BLANK, L4_BLANK, M },
|
||||||
|
/*0x38*/ { L1_88, L2_BLANK, L3_BLANK, L4_BLANK, M },
|
||||||
|
/*0x39*/ { L1_98, L2_BLANK, L3_BLANK, L4_BLANK, M },
|
||||||
|
/*0x3A*/ { IGNORE, IGNORE, L3_COLON, IGNORE, M },
|
||||||
|
/*0x3B*/ { IGNORE, IGNORE, L3_SEMICOLON, IGNORE, M },
|
||||||
|
/*0x3C*/ { IGNORE, IGNORE, L3_LESS_THAN, IGNORE, M },
|
||||||
|
/*0x3D*/ { IGNORE, IGNORE, L3_EQUAL, IGNORE, M },
|
||||||
|
/*0x3E*/ { IGNORE, IGNORE, L3_GREATER_THAN, IGNORE, M },
|
||||||
|
/*0x3F*/ { IGNORE, IGNORE, L3_QUESTION, IGNORE, M },
|
||||||
|
/*0x40*/ { IGNORE, IGNORE, L3_AT, IGNORE, M },
|
||||||
|
/*0x41*/ { L1_A8, L2_BLANK, L3_BLANK, L4_CAP, M },
|
||||||
|
/*0x42*/ { L1_B8, L2_BLANK, L3_BLANK, L4_CAP, M },
|
||||||
|
/*0x43*/ { L1_C8, L2_BLANK, L3_BLANK, L4_CAP, M },
|
||||||
|
/*0x44*/ { L1_D8, L2_BLANK, L3_BLANK, L4_CAP, M },
|
||||||
|
/*0x45*/ { L1_E8, L2_BLANK, L3_BLANK, L4_CAP, M },
|
||||||
|
/*0x46*/ { L1_F8, L2_BLANK, L3_BLANK, L4_CAP, M },
|
||||||
|
/*0x47*/ { L1_G8, L2_BLANK, L3_BLANK, L4_CAP, M },
|
||||||
|
/*0x48*/ { L1_H8, L2_BLANK, L3_BLANK, L4_CAP, M },
|
||||||
|
/*0x49*/ { L1_I8, L2_BLANK, L3_BLANK, L4_CAP, M },
|
||||||
|
/*0x4A*/ { L1_J8, L2_BLANK, L3_BLANK, L4_CAP, M },
|
||||||
|
/*0x4B*/ { L1_K8, L2_BLANK, L3_BLANK, L4_CAP, M },
|
||||||
|
/*0x4C*/ { L1_L8, L2_BLANK, L3_BLANK, L4_CAP, M },
|
||||||
|
/*0x4D*/ { L1_M8, L2_BLANK, L3_BLANK, L4_CAP, M },
|
||||||
|
/*0x4E*/ { L1_N8, L2_BLANK, L3_BLANK, L4_CAP, M },
|
||||||
|
/*0x4F*/ { L1_O8, L2_BLANK, L3_BLANK, L4_CAP, M },
|
||||||
|
/*0x50*/ { L1_P8, L2_BLANK, L3_BLANK, L4_CAP, M },
|
||||||
|
/*0x51*/ { L1_Q8, L2_BLANK, L3_BLANK, L4_CAP, M },
|
||||||
|
/*0x52*/ { L1_R8, L2_BLANK, L3_BLANK, L4_CAP, M },
|
||||||
|
/*0x53*/ { L1_S8, L2_BLANK, L3_BLANK, L4_CAP, M },
|
||||||
|
/*0x54*/ { L1_T8, L2_BLANK, L3_BLANK, L4_CAP, M },
|
||||||
|
/*0x55*/ { L1_U8, L2_BLANK, L3_BLANK, L4_CAP, M },
|
||||||
|
/*0x56*/ { L1_V8, L2_BLANK, L3_BLANK, L4_CAP, M },
|
||||||
|
/*0x57*/ { L1_W8, L2_BLANK, L3_BLANK, L4_CAP, M },
|
||||||
|
/*0x58*/ { L1_X8, L2_BLANK, L3_BLANK, L4_CAP, M },
|
||||||
|
/*0x59*/ { L1_Y8, L2_BLANK, L3_BLANK, L4_CAP, M },
|
||||||
|
/*0x5A*/ { L1_Z8, L2_BLANK, L3_BLANK, L4_CAP, M },
|
||||||
|
/*0x5B*/ { IGNORE, IGNORE, L3_L_BRACKET, IGNORE, M },
|
||||||
|
/*0x5C*/ { IGNORE, IGNORE, L3_BK_SOLIDUS, IGNORE, M },
|
||||||
|
/*0x5D*/ { IGNORE, IGNORE, L3_R_BRACKET, IGNORE, M },
|
||||||
|
/*0x5E*/ { IGNORE, IGNORE, L3_CIRCUMFLEX, IGNORE, M },
|
||||||
|
/*0x5F*/ { IGNORE, IGNORE, L3_LOW_LINE, IGNORE, M },
|
||||||
|
/*0x60*/ { IGNORE, IGNORE, L3_GRAVE, IGNORE, M },
|
||||||
|
/*0x61*/ { L1_A8, L2_BLANK, L3_BLANK, L4_MIN, M },
|
||||||
|
/*0x62*/ { L1_B8, L2_BLANK, L3_BLANK, L4_MIN, M },
|
||||||
|
/*0x63*/ { L1_C8, L2_BLANK, L3_BLANK, L4_MIN, M },
|
||||||
|
/*0x64*/ { L1_D8, L2_BLANK, L3_BLANK, L4_MIN, M },
|
||||||
|
/*0x65*/ { L1_E8, L2_BLANK, L3_BLANK, L4_MIN, M },
|
||||||
|
/*0x66*/ { L1_F8, L2_BLANK, L3_BLANK, L4_MIN, M },
|
||||||
|
/*0x67*/ { L1_G8, L2_BLANK, L3_BLANK, L4_MIN, M },
|
||||||
|
/*0x68*/ { L1_H8, L2_BLANK, L3_BLANK, L4_MIN, M },
|
||||||
|
/*0x69*/ { L1_I8, L2_BLANK, L3_BLANK, L4_MIN, M },
|
||||||
|
/*0x6A*/ { L1_J8, L2_BLANK, L3_BLANK, L4_MIN, M },
|
||||||
|
/*0x6B*/ { L1_K8, L2_BLANK, L3_BLANK, L4_MIN, M },
|
||||||
|
/*0x6C*/ { L1_L8, L2_BLANK, L3_BLANK, L4_MIN, M },
|
||||||
|
/*0x6D*/ { L1_M8, L2_BLANK, L3_BLANK, L4_MIN, M },
|
||||||
|
/*0x6E*/ { L1_N8, L2_BLANK, L3_BLANK, L4_MIN, M },
|
||||||
|
/*0x6F*/ { L1_O8, L2_BLANK, L3_BLANK, L4_MIN, M },
|
||||||
|
/*0x70*/ { L1_P8, L2_BLANK, L3_BLANK, L4_MIN, M },
|
||||||
|
/*0x71*/ { L1_Q8, L2_BLANK, L3_BLANK, L4_MIN, M },
|
||||||
|
/*0x72*/ { L1_R8, L2_BLANK, L3_BLANK, L4_MIN, M },
|
||||||
|
/*0x73*/ { L1_S8, L2_BLANK, L3_BLANK, L4_MIN, M },
|
||||||
|
/*0x74*/ { L1_T8, L2_BLANK, L3_BLANK, L4_MIN, M },
|
||||||
|
/*0x75*/ { L1_U8, L2_BLANK, L3_BLANK, L4_MIN, M },
|
||||||
|
/*0x76*/ { L1_V8, L2_BLANK, L3_BLANK, L4_MIN, M },
|
||||||
|
/*0x77*/ { L1_W8, L2_BLANK, L3_BLANK, L4_MIN, M },
|
||||||
|
/*0x78*/ { L1_X8, L2_BLANK, L3_BLANK, L4_MIN, M },
|
||||||
|
/*0x79*/ { L1_Y8, L2_BLANK, L3_BLANK, L4_MIN, M },
|
||||||
|
/*0x7A*/ { L1_Z8, L2_BLANK, L3_BLANK, L4_MIN, M },
|
||||||
|
/*0x7B*/ { IGNORE, IGNORE, L3_L_BRACE, IGNORE, M },
|
||||||
|
/*0x7C*/ { IGNORE, IGNORE, L3_V_LINE, IGNORE, M },
|
||||||
|
/*0x7D*/ { IGNORE, IGNORE, L3_R_BRACE, IGNORE, M },
|
||||||
|
/*0x7E*/ { IGNORE, IGNORE, L3_TILDE, IGNORE, M },
|
||||||
|
/*0x7F*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x80*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x81*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x82*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x83*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x84*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x85*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x86*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x87*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x88*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x89*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x8A*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x8B*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x8C*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x8D*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x8E*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x8F*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x90*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x91*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x92*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x93*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x94*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x95*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x96*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x97*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x98*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x99*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x9A*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x9B*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x9C*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x9D*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x9E*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0x9F*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0xA0*/ { IGNORE, IGNORE, L3_NB_SACE, IGNORE, X },
|
||||||
|
/*0xA1*/ { L1_KO_KAI, L2_BLANK, L3_BLANK, L4_BLANK, M | _consnt},
|
||||||
|
/*0xA2*/ { L1_KHO_KHAI, L2_BLANK, L3_BLANK, L4_BLANK, M | _consnt},
|
||||||
|
/*0xA3*/ { L1_KHO_KHUAT, L2_BLANK, L3_BLANK, L4_BLANK, M | _consnt},
|
||||||
|
/*0xA4*/ { L1_KHO_KHWAI, L2_BLANK, L3_BLANK, L4_BLANK, M | _consnt},
|
||||||
|
/*0xA5*/ { L1_KHO_KHON, L2_BLANK, L3_BLANK, L4_BLANK, M | _consnt},
|
||||||
|
/*0xA6*/ { L1_KHO_RAKHANG, L2_BLANK, L3_BLANK, L4_BLANK, M | _consnt},
|
||||||
|
/*0xA7*/ { L1_NGO_NGU, L2_BLANK, L3_BLANK, L4_BLANK, M | _consnt},
|
||||||
|
/*0xA8*/ { L1_CHO_CHAN, L2_BLANK, L3_BLANK, L4_BLANK, M | _consnt},
|
||||||
|
/*0xA9*/ { L1_CHO_CHING, L2_BLANK, L3_BLANK, L4_BLANK, M | _consnt},
|
||||||
|
/*0xAA*/ { L1_CHO_CHANG, L2_BLANK, L3_BLANK, L4_BLANK, M | _consnt},
|
||||||
|
/*0xAB*/ { L1_SO_SO, L2_BLANK, L3_BLANK, L4_BLANK, M | _consnt},
|
||||||
|
/*0xAC*/ { L1_CHO_CHOE, L2_BLANK, L3_BLANK, L4_BLANK, M | _consnt},
|
||||||
|
/*0xAD*/ { L1_YO_YING, L2_BLANK, L3_BLANK, L4_BLANK, M | _consnt},
|
||||||
|
/*0xAE*/ { L1_DO_CHADA, L2_BLANK, L3_BLANK, L4_BLANK, M | _consnt},
|
||||||
|
/*0xAF*/ { L1_TO_PATAK, L2_BLANK, L3_BLANK, L4_BLANK, M | _consnt},
|
||||||
|
/*0xB0*/ { L1_THO_THAN, L2_BLANK,L3_BLANK, L4_BLANK, M | _consnt},
|
||||||
|
/*0xB1*/ { L1_THO_NANGMONTHO, L2_BLANK, L3_BLANK, L4_BLANK, M | _consnt},
|
||||||
|
/*0xB2*/ { L1_THO_PHUTHAO, L2_BLANK, L3_BLANK, L4_BLANK, M | _consnt},
|
||||||
|
/*0xB3*/ { L1_NO_NEN, L2_BLANK, L3_BLANK, L4_BLANK, M | _consnt},
|
||||||
|
/*0xB4*/ { L1_DO_DEK, L2_BLANK, L3_BLANK, L4_BLANK, M | _consnt},
|
||||||
|
/*0xB5*/ { L1_TO_TAO, L2_BLANK, L3_BLANK, L4_BLANK, M | _consnt},
|
||||||
|
/*0xB6*/ { L1_THO_THUNG, L2_BLANK, L3_BLANK, L4_BLANK, M | _consnt},
|
||||||
|
/*0xB7*/ { L1_THO_THAHAN, L2_BLANK, L3_BLANK, L4_BLANK, M | _consnt},
|
||||||
|
/*0xB8*/ { L1_THO_THONG, L2_BLANK, L3_BLANK, L4_BLANK, M | _consnt},
|
||||||
|
/*0xB9*/ { L1_NO_NU, L2_BLANK, L3_BLANK, L4_BLANK, M | _consnt},
|
||||||
|
/*0xBA*/ { L1_BO_BAIMAI, L2_BLANK, L3_BLANK, L4_BLANK, M | _consnt},
|
||||||
|
/*0xBB*/ { L1_PO_PLA, L2_BLANK, L3_BLANK, L4_BLANK, M | _consnt},
|
||||||
|
/*0xBC*/ { L1_PHO_PHUNG, L2_BLANK, L3_BLANK, L4_BLANK, M | _consnt},
|
||||||
|
/*0xBD*/ { L1_FO_FA, L2_BLANK, L3_BLANK, L4_BLANK, M | _consnt},
|
||||||
|
/*0xBE*/ { L1_PHO_PHAN, L2_BLANK, L3_BLANK, L4_BLANK, M | _consnt},
|
||||||
|
/*0xBF*/ { L1_FO_FAN, L2_BLANK, L3_BLANK, L4_BLANK, M | _consnt},
|
||||||
|
/*0xC0*/ { L1_PHO_SAMPHAO, L2_BLANK, L3_BLANK, L4_BLANK, M | _consnt},
|
||||||
|
/*0xC1*/ { L1_MO_MA, L2_BLANK, L3_BLANK, L4_BLANK, M | _consnt},
|
||||||
|
/*0xC2*/ { L1_YO_YAK, L2_BLANK, L3_BLANK, L4_BLANK, M | _consnt},
|
||||||
|
/*0xC3*/ { L1_RO_RUA, L2_BLANK, L3_BLANK, L4_BLANK, M | _consnt},
|
||||||
|
/*0xC4*/ { L1_RU, L2_BLANK, L3_BLANK, L4_BLANK, M | _consnt},
|
||||||
|
/*0xC5*/ { L1_LO_LING, L2_BLANK, L3_BLANK, L4_BLANK, M | _consnt},
|
||||||
|
/*0xC6*/ { L1_LU, L2_BLANK, L3_BLANK, L4_BLANK, M | _consnt},
|
||||||
|
/*0xC7*/ { L1_WO_WAEN, L2_BLANK, L3_BLANK, L4_BLANK, M | _consnt},
|
||||||
|
/*0xC8*/ { L1_SO_SALA, L2_BLANK, L3_BLANK, L4_BLANK, M | _consnt},
|
||||||
|
/*0xC9*/ { L1_SO_RUSI, L2_BLANK, L3_BLANK, L4_BLANK, M | _consnt},
|
||||||
|
/*0xCA*/ { L1_SO_SUA, L2_BLANK, L3_BLANK, L4_BLANK, M | _consnt},
|
||||||
|
/*0xCB*/ { L1_HO_HIP, L2_BLANK, L3_BLANK, L4_BLANK, M | _consnt},
|
||||||
|
/*0xCC*/ { L1_LO_CHULA, L2_BLANK, L3_BLANK, L4_BLANK, M | _consnt},
|
||||||
|
/*0xCD*/ { L1_O_ANG, L2_BLANK, L3_BLANK, L4_BLANK, M | _consnt},
|
||||||
|
/*0xCE*/ { L1_HO_NOKHUK, L2_BLANK, L3_BLANK, L4_BLANK, M | _consnt},
|
||||||
|
/*0xCF*/ { IGNORE, IGNORE, L3_PAIYAN_NOI, IGNORE, M},
|
||||||
|
/*0xD0*/ { L1_SARA_A, L2_BLANK, L3_BLANK, L4_BLANK, M | _fllwvowel},
|
||||||
|
/*0xD1*/ { L1_MAI_HAN_AKAT, L2_BLANK, L3_BLANK, L4_BLANK, U | _uprvowel},
|
||||||
|
/*0xD2*/ { L1_SARA_AA, L2_BLANK, L3_BLANK, L4_BLANK, M | _fllwvowel},
|
||||||
|
/*0xD3*/ { L1_SARA_AM, L2_BLANK, L3_BLANK, L4_BLANK, M | _fllwvowel},
|
||||||
|
/*0xD4*/ { L1_SARA_I, L2_BLANK, L3_BLANK, L4_BLANK, U | _uprvowel},
|
||||||
|
/*0xD5*/ { L1_SARA_II, L2_BLANK, L3_BLANK, L4_BLANK, U | _uprvowel},
|
||||||
|
/*0xD6*/ { L1_SARA_UE, L2_BLANK, L3_BLANK, L4_BLANK, U | _uprvowel},
|
||||||
|
/*0xD7*/ { L1_SARA_UEE, L2_BLANK, L3_BLANK, L4_BLANK, U | _uprvowel},
|
||||||
|
/*0xD8*/ { L1_SARA_U, L2_BLANK, L3_BLANK, L4_BLANK, L | _lwrvowel},
|
||||||
|
/*0xD9*/ { L1_SARA_UU, L2_BLANK, L3_BLANK, L4_BLANK, L | _lwrvowel},
|
||||||
|
/*0xDA*/ { IGNORE, L2_PINTHU, L3_BLANK, L4_BLANK, L },
|
||||||
|
/*0xDB*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0xDC*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0xDD*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0xDE*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0xDF*/ { IGNORE, IGNORE, L3_BAHT, IGNORE, M},
|
||||||
|
/*0xE0*/ { L1_SARA_E, L2_BLANK, L3_BLANK, L4_BLANK, M | _ldvowel },
|
||||||
|
/*0xE1*/ { L1_SARA_AE, L2_BLANK, L3_BLANK, L4_BLANK, M | _ldvowel },
|
||||||
|
/*0xE2*/ { L1_SARA_O, L2_BLANK, L3_BLANK, L4_BLANK, M | _ldvowel },
|
||||||
|
/*0xE3*/ { L1_SARA_AI_MAIMUAN, L2_BLANK, L3_BLANK, L4_BLANK, M | _ldvowel },
|
||||||
|
/*0xE4*/ { L1_SARA_AI_MAIMALAI, L2_BLANK, L3_BLANK, L4_BLANK, M | _ldvowel },
|
||||||
|
/*0xE5*/ { L1_SARA_AA, L2_BLANK, L3_BLANK, L4_EXT, M | _fllwvowel },
|
||||||
|
/*0xE6*/ { IGNORE, IGNORE, L3_MAI_YAMOK, IGNORE, M | _stone },
|
||||||
|
/*0xE7*/ { IGNORE, L2_TYKHU, L3_BLANK, L4_BLANK, U | _diacrt1 | _stone },
|
||||||
|
/*0xE8*/ { IGNORE, L2_TONE1, L3_BLANK, L4_BLANK, UU | _tone | _combine | _stone },
|
||||||
|
/*0xE9*/ { IGNORE, L2_TONE2, L3_BLANK, L4_BLANK, UU | _tone | _combine | _stone },
|
||||||
|
/*0xEA*/ { IGNORE, L2_TONE3, L3_BLANK, L4_BLANK, UU | _tone | _combine | _stone },
|
||||||
|
/*0xEB*/ { IGNORE, L2_TONE4, L3_BLANK, L4_BLANK, UU | _tone | _combine | _stone },
|
||||||
|
/*0xEC*/ { IGNORE, L2_GARAN, L3_BLANK, L4_BLANK, UU | _diacrt2 | _combine | _stone },
|
||||||
|
/*0xED*/ { L1_NKHIT, L2_BLANK, L3_BLANK, L4_BLANK, U | _diacrt1 },
|
||||||
|
/*0xEE*/ { IGNORE, L2_YAMAK, L3_BLANK, L4_BLANK, U | _diacrt1 },
|
||||||
|
/*0xEF*/ { IGNORE, IGNORE, L3_FONGMAN, IGNORE, M },
|
||||||
|
/*0xF0*/ { L1_08, L2_THAII, L3_BLANK, L4_BLANK, M | _tdig },
|
||||||
|
/*0xF1*/ { L1_18, L2_THAII, L3_BLANK, L4_BLANK, M | _tdig },
|
||||||
|
/*0xF2*/ { L1_28, L2_THAII, L3_BLANK, L4_BLANK, M | _tdig },
|
||||||
|
/*0xF3*/ { L1_38, L2_THAII, L3_BLANK, L4_BLANK, M | _tdig },
|
||||||
|
/*0xF4*/ { L1_48, L2_THAII, L3_BLANK, L4_BLANK, M | _tdig },
|
||||||
|
/*0xF5*/ { L1_58, L2_THAII, L3_BLANK, L4_BLANK, M | _tdig },
|
||||||
|
/*0xF6*/ { L1_68, L2_THAII, L3_BLANK, L4_BLANK, M | _tdig },
|
||||||
|
/*0xF7*/ { L1_78, L2_THAII, L3_BLANK, L4_BLANK, M | _tdig },
|
||||||
|
/*0xF8*/ { L1_88, L2_THAII, L3_BLANK, L4_BLANK, M | _tdig },
|
||||||
|
/*0xF9*/ { L1_98, L2_THAII, L3_BLANK, L4_BLANK, M | _tdig },
|
||||||
|
/*0xFA*/ { IGNORE, IGNORE, L3_ANGKHANKHU, IGNORE, X },
|
||||||
|
/*0xFB*/ { IGNORE, IGNORE, L3_KHOMUT, IGNORE, X },
|
||||||
|
/*0xFC*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0xFD*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/*0xFE*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
/* Utilize 0xFF for max_sort_chr in my_like_range_tis620 */
|
||||||
|
/*0xFF*/ { 255 /*IGNORE*/, IGNORE, IGNORE, IGNORE, X },
|
||||||
|
};
|
||||||
|
|
||||||
|
static uchar NEAR ctype_tis620[257] =
|
||||||
|
{
|
||||||
|
0, /* For standard library */
|
||||||
|
32,32,32,32,32,32,32,32,32,40,40,40,40,40,32,32,
|
||||||
|
32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,
|
||||||
|
72,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
|
||||||
|
132,132,132,132,132,132,132,132,132,132,16,16,16,16,16,16,
|
||||||
|
16,129,129,129,129,129,129,1,1,1,1,1,1,1,1,1,
|
||||||
|
1,1,1,1,1,1,1,1,1,1,1,16,16,16,16,16,
|
||||||
|
16,130,130,130,130,130,130,2,2,2,2,2,2,2,2,2,
|
||||||
|
2,2,2,2,2,2,2,2,2,2,2,16,16,16,16,32,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
};
|
||||||
|
|
||||||
|
static uchar NEAR to_lower_tis620[]=
|
||||||
|
{
|
||||||
|
'\000','\001','\002','\003','\004','\005','\006','\007',
|
||||||
|
'\010','\011','\012','\013','\014','\015','\016','\017',
|
||||||
|
'\020','\021','\022','\023','\024','\025','\026','\027',
|
||||||
|
'\030','\031','\032','\033','\034','\035','\036','\037',
|
||||||
|
' ', '!', '"', '#', '$', '%', '&', '\'',
|
||||||
|
'(', ')', '*', '+', ',', '-', '.', '/',
|
||||||
|
'0', '1', '2', '3', '4', '5', '6', '7',
|
||||||
|
'8', '9', ':', ';', '<', '=', '>', '?',
|
||||||
|
'@', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
|
||||||
|
'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
|
||||||
|
'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
|
||||||
|
'x', 'y', 'z', '[', '\\', ']', '^', '_',
|
||||||
|
'`', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
|
||||||
|
'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
|
||||||
|
'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
|
||||||
|
'x', 'y', 'z', '{', '|', '}', '~', '\177',
|
||||||
|
(uchar) '\200',(uchar) '\201',(uchar) '\202',(uchar) '\203',(uchar) '\204',(uchar) '\205',(uchar) '\206',(uchar) '\207',
|
||||||
|
(uchar) '\210',(uchar) '\211',(uchar) '\212',(uchar) '\213',(uchar) '\214',(uchar) '\215',(uchar) '\216',(uchar) '\217',
|
||||||
|
(uchar) '\220',(uchar) '\221',(uchar) '\222',(uchar) '\223',(uchar) '\224',(uchar) '\225',(uchar) '\226',(uchar) '\227',
|
||||||
|
(uchar) '\230',(uchar) '\231',(uchar) '\232',(uchar) '\233',(uchar) '\234',(uchar) '\235',(uchar) '\236',(uchar) '\237',
|
||||||
|
(uchar) '\240',(uchar) '\241',(uchar) '\242',(uchar) '\243',(uchar) '\244',(uchar) '\245',(uchar) '\246',(uchar) '\247',
|
||||||
|
(uchar) '\250',(uchar) '\251',(uchar) '\252',(uchar) '\253',(uchar) '\254',(uchar) '\255',(uchar) '\256',(uchar) '\257',
|
||||||
|
(uchar) '\260',(uchar) '\261',(uchar) '\262',(uchar) '\263',(uchar) '\264',(uchar) '\265',(uchar) '\266',(uchar) '\267',
|
||||||
|
(uchar) '\270',(uchar) '\271',(uchar) '\272',(uchar) '\273',(uchar) '\274',(uchar) '\275',(uchar) '\276',(uchar) '\277',
|
||||||
|
(uchar) '\300',(uchar) '\301',(uchar) '\302',(uchar) '\303',(uchar) '\304',(uchar) '\305',(uchar) '\306',(uchar) '\307',
|
||||||
|
(uchar) '\310',(uchar) '\311',(uchar) '\312',(uchar) '\313',(uchar) '\314',(uchar) '\315',(uchar) '\316',(uchar) '\317',
|
||||||
|
(uchar) '\320',(uchar) '\321',(uchar) '\322',(uchar) '\323',(uchar) '\324',(uchar) '\325',(uchar) '\326',(uchar) '\327',
|
||||||
|
(uchar) '\330',(uchar) '\331',(uchar) '\332',(uchar) '\333',(uchar) '\334',(uchar) '\335',(uchar) '\336',(uchar) '\337',
|
||||||
|
(uchar) '\340',(uchar) '\341',(uchar) '\342',(uchar) '\343',(uchar) '\344',(uchar) '\345',(uchar) '\346',(uchar) '\347',
|
||||||
|
(uchar) '\350',(uchar) '\351',(uchar) '\352',(uchar) '\353',(uchar) '\354',(uchar) '\355',(uchar) '\356',(uchar) '\357',
|
||||||
|
(uchar) '\360',(uchar) '\361',(uchar) '\362',(uchar) '\363',(uchar) '\364',(uchar) '\365',(uchar) '\366',(uchar) '\367',
|
||||||
|
(uchar) '\370',(uchar) '\371',(uchar) '\372',(uchar) '\373',(uchar) '\374',(uchar) '\375',(uchar) '\376',(uchar) '\377',
|
||||||
|
};
|
||||||
|
|
||||||
|
static uchar NEAR to_upper_tis620[]=
|
||||||
|
{
|
||||||
|
'\000','\001','\002','\003','\004','\005','\006','\007',
|
||||||
|
'\010','\011','\012','\013','\014','\015','\016','\017',
|
||||||
|
'\020','\021','\022','\023','\024','\025','\026','\027',
|
||||||
|
'\030','\031','\032','\033','\034','\035','\036','\037',
|
||||||
|
' ', '!', '"', '#', '$', '%', '&', '\'',
|
||||||
|
'(', ')', '*', '+', ',', '-', '.', '/',
|
||||||
|
'0', '1', '2', '3', '4', '5', '6', '7',
|
||||||
|
'8', '9', ':', ';', '<', '=', '>', '?',
|
||||||
|
'@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
|
||||||
|
'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
|
||||||
|
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
|
||||||
|
'X', 'Y', 'Z', '[', '\\', ']', '^', '_',
|
||||||
|
'`', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
|
||||||
|
'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
|
||||||
|
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
|
||||||
|
'X', 'Y', 'Z', '{', '|', '}', '~', '\177',
|
||||||
|
(uchar) '\200',(uchar) '\201',(uchar) '\202',(uchar) '\203',(uchar) '\204',(uchar) '\205',(uchar) '\206',(uchar) '\207',
|
||||||
|
(uchar) '\210',(uchar) '\211',(uchar) '\212',(uchar) '\213',(uchar) '\214',(uchar) '\215',(uchar) '\216',(uchar) '\217',
|
||||||
|
(uchar) '\220',(uchar) '\221',(uchar) '\222',(uchar) '\223',(uchar) '\224',(uchar) '\225',(uchar) '\226',(uchar) '\227',
|
||||||
|
(uchar) '\230',(uchar) '\231',(uchar) '\232',(uchar) '\233',(uchar) '\234',(uchar) '\235',(uchar) '\236',(uchar) '\237',
|
||||||
|
(uchar) '\240',(uchar) '\241',(uchar) '\242',(uchar) '\243',(uchar) '\244',(uchar) '\245',(uchar) '\246',(uchar) '\247',
|
||||||
|
(uchar) '\250',(uchar) '\251',(uchar) '\252',(uchar) '\253',(uchar) '\254',(uchar) '\255',(uchar) '\256',(uchar) '\257',
|
||||||
|
(uchar) '\260',(uchar) '\261',(uchar) '\262',(uchar) '\263',(uchar) '\264',(uchar) '\265',(uchar) '\266',(uchar) '\267',
|
||||||
|
(uchar) '\270',(uchar) '\271',(uchar) '\272',(uchar) '\273',(uchar) '\274',(uchar) '\275',(uchar) '\276',(uchar) '\277',
|
||||||
|
(uchar) '\300',(uchar) '\301',(uchar) '\302',(uchar) '\303',(uchar) '\304',(uchar) '\305',(uchar) '\306',(uchar) '\307',
|
||||||
|
(uchar) '\310',(uchar) '\311',(uchar) '\312',(uchar) '\313',(uchar) '\314',(uchar) '\315',(uchar) '\316',(uchar) '\317',
|
||||||
|
(uchar) '\320',(uchar) '\321',(uchar) '\322',(uchar) '\323',(uchar) '\324',(uchar) '\325',(uchar) '\326',(uchar) '\327',
|
||||||
|
(uchar) '\330',(uchar) '\331',(uchar) '\332',(uchar) '\333',(uchar) '\334',(uchar) '\335',(uchar) '\336',(uchar) '\337',
|
||||||
|
(uchar) '\340',(uchar) '\341',(uchar) '\342',(uchar) '\343',(uchar) '\344',(uchar) '\345',(uchar) '\346',(uchar) '\347',
|
||||||
|
(uchar) '\350',(uchar) '\351',(uchar) '\352',(uchar) '\353',(uchar) '\354',(uchar) '\355',(uchar) '\356',(uchar) '\357',
|
||||||
|
(uchar) '\360',(uchar) '\361',(uchar) '\362',(uchar) '\363',(uchar) '\364',(uchar) '\365',(uchar) '\366',(uchar) '\367',
|
||||||
|
(uchar) '\370',(uchar) '\371',(uchar) '\372',(uchar) '\373',(uchar) '\374',(uchar) '\375',(uchar) '\376',(uchar) '\377',
|
||||||
|
};
|
||||||
|
|
||||||
|
static uchar NEAR sort_order_tis620[]=
|
||||||
|
{
|
||||||
|
'\000','\001','\002','\003','\004','\005','\006','\007',
|
||||||
|
'\010','\011','\012','\013','\014','\015','\016','\017',
|
||||||
|
'\020','\021','\022','\023','\024','\025','\026','\027',
|
||||||
|
'\030','\031','\032','\033','\034','\035','\036','\037',
|
||||||
|
' ', '!', '"', '#', '$', '%', '&', '\'',
|
||||||
|
'(', ')', '*', '+', ',', '-', '.', '/',
|
||||||
|
'0', '1', '2', '3', '4', '5', '6', '7',
|
||||||
|
'8', '9', ':', ';', '<', '=', '>', '?',
|
||||||
|
'@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
|
||||||
|
'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
|
||||||
|
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
|
||||||
|
'X', 'Y', 'Z', '\\', ']', '[', '^', '_',
|
||||||
|
'E', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
|
||||||
|
'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
|
||||||
|
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
|
||||||
|
'X', 'Y', 'Z', '{', '|', '}', 'Y', '\177',
|
||||||
|
(uchar) '\200',(uchar) '\201',(uchar) '\202',(uchar) '\203',(uchar) '\204',(uchar) '\205',(uchar) '\206',(uchar) '\207',
|
||||||
|
(uchar) '\210',(uchar) '\211',(uchar) '\212',(uchar) '\213',(uchar) '\214',(uchar) '\215',(uchar) '\216',(uchar) '\217',
|
||||||
|
(uchar) '\220',(uchar) '\221',(uchar) '\222',(uchar) '\223',(uchar) '\224',(uchar) '\225',(uchar) '\226',(uchar) '\227',
|
||||||
|
(uchar) '\230',(uchar) '\231',(uchar) '\232',(uchar) '\233',(uchar) '\234',(uchar) '\235',(uchar) '\236',(uchar) '\237',
|
||||||
|
(uchar) '\240',(uchar) '\241',(uchar) '\242',(uchar) '\243',(uchar) '\244',(uchar) '\245',(uchar) '\246',(uchar) '\247',
|
||||||
|
(uchar) '\250',(uchar) '\251',(uchar) '\252',(uchar) '\253',(uchar) '\254',(uchar) '\255',(uchar) '\256',(uchar) '\257',
|
||||||
|
(uchar) '\260',(uchar) '\261',(uchar) '\262',(uchar) '\263',(uchar) '\264',(uchar) '\265',(uchar) '\266',(uchar) '\267',
|
||||||
|
(uchar) '\270',(uchar) '\271',(uchar) '\272',(uchar) '\273',(uchar) '\274',(uchar) '\275',(uchar) '\276',(uchar) '\277',
|
||||||
|
(uchar) '\300',(uchar) '\301',(uchar) '\302',(uchar) '\303',(uchar) '\304',(uchar) '\305',(uchar) '\306',(uchar) '\307',
|
||||||
|
(uchar) '\310',(uchar) '\311',(uchar) '\312',(uchar) '\313',(uchar) '\314',(uchar) '\315',(uchar) '\316',(uchar) '\317',
|
||||||
|
(uchar) '\320',(uchar) '\321',(uchar) '\322',(uchar) '\323',(uchar) '\324',(uchar) '\325',(uchar) '\326',(uchar) '\327',
|
||||||
|
(uchar) '\330',(uchar) '\331',(uchar) '\332',(uchar) '\333',(uchar) '\334',(uchar) '\335',(uchar) '\336',(uchar) '\337',
|
||||||
|
(uchar) '\340',(uchar) '\341',(uchar) '\342',(uchar) '\343',(uchar) '\344',(uchar) '\345',(uchar) '\346',(uchar) '\347',
|
||||||
|
(uchar) '\350',(uchar) '\351',(uchar) '\352',(uchar) '\353',(uchar) '\354',(uchar) '\355',(uchar) '\356',(uchar) '\357',
|
||||||
|
(uchar) '\360',(uchar) '\361',(uchar) '\362',(uchar) '\363',(uchar) '\364',(uchar) '\365',(uchar) '\366',(uchar) '\367',
|
||||||
|
(uchar) '\370',(uchar) '\371',(uchar) '\372',(uchar) '\373',(uchar) '\374',(uchar) '\375',(uchar) '\376',(uchar) '\377',
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Convert thai string to "Standard C String Function" sortable string
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
thai2sortable()
|
||||||
|
tstr String to convert. Does not have to end with \0
|
||||||
|
len Length of tstr
|
||||||
|
*/
|
||||||
|
|
||||||
|
static size_t thai2sortable(uchar *tstr, size_t len)
|
||||||
|
{
|
||||||
|
uchar *p;
|
||||||
|
int tlen;
|
||||||
|
uchar l2bias;
|
||||||
|
|
||||||
|
tlen= len;
|
||||||
|
l2bias= 256 - 8;
|
||||||
|
for (p= tstr; tlen > 0; p++, tlen--)
|
||||||
|
{
|
||||||
|
uchar c= *p;
|
||||||
|
|
||||||
|
if (isthai(c))
|
||||||
|
{
|
||||||
|
int *t_ctype0= t_ctype[c];
|
||||||
|
|
||||||
|
if (isconsnt(c))
|
||||||
|
l2bias -= 8;
|
||||||
|
if (isldvowel(c) && tlen != 1 && isconsnt(p[1]))
|
||||||
|
{
|
||||||
|
/* simply swap between leading-vowel and consonant */
|
||||||
|
*p= p[1];
|
||||||
|
p[1]= c;
|
||||||
|
tlen--;
|
||||||
|
p++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if found level 2 char (L2_GARAN,L2_TONE*,L2_TYKHU) move to last */
|
||||||
|
if (t_ctype0[1] >= L2_GARAN)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
l2bias use to control position weight of l2char
|
||||||
|
example (*=l2char) XX*X must come before X*XX
|
||||||
|
*/
|
||||||
|
memmove((char*) p, (char*) (p+1), tlen-1);
|
||||||
|
tstr[len-1]= l2bias + t_ctype0[1]- L2_GARAN +1;
|
||||||
|
p--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
l2bias-= 8;
|
||||||
|
*p= to_lower_tis620[c];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
strncoll() replacement, compare 2 string, both are converted to sortable
|
||||||
|
string
|
||||||
|
|
||||||
|
NOTE:
|
||||||
|
We can't cut strings at end \0 as this would break comparision with
|
||||||
|
LIKE characters, where the min range is stored as end \0
|
||||||
|
|
||||||
|
Arg: 2 Strings and it compare length
|
||||||
|
Ret: strcmp result
|
||||||
|
*/
|
||||||
|
|
||||||
|
static
|
||||||
|
int my_strnncoll_tis620(CHARSET_INFO *cs __attribute__((unused)),
|
||||||
|
const uchar *s1, size_t len1,
|
||||||
|
const uchar *s2, size_t len2,
|
||||||
|
my_bool s2_is_prefix)
|
||||||
|
{
|
||||||
|
uchar buf[80] ;
|
||||||
|
uchar *tc1, *tc2;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (s2_is_prefix && len1 > len2)
|
||||||
|
len1= len2;
|
||||||
|
|
||||||
|
tc1= buf;
|
||||||
|
if ((len1 + len2 +2) > (int) sizeof(buf))
|
||||||
|
tc1= (uchar*) my_str_malloc(len1+len2+2);
|
||||||
|
tc2= tc1 + len1+1;
|
||||||
|
memcpy((char*) tc1, (char*) s1, len1);
|
||||||
|
tc1[len1]= 0; /* if length(s1)> len1, need to put 'end of string' */
|
||||||
|
memcpy((char *)tc2, (char *)s2, len2);
|
||||||
|
tc2[len2]= 0; /* put end of string */
|
||||||
|
thai2sortable(tc1, len1);
|
||||||
|
thai2sortable(tc2, len2);
|
||||||
|
i= strcmp((char*)tc1, (char*)tc2);
|
||||||
|
if (tc1 != buf)
|
||||||
|
my_str_free(tc1);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
int my_strnncollsp_tis620(CHARSET_INFO * cs __attribute__((unused)),
|
||||||
|
const uchar *a0, size_t a_length,
|
||||||
|
const uchar *b0, size_t b_length,
|
||||||
|
my_bool diff_if_only_endspace_difference)
|
||||||
|
{
|
||||||
|
uchar buf[80], *end, *a, *b, *alloced= NULL;
|
||||||
|
size_t length;
|
||||||
|
int res= 0;
|
||||||
|
|
||||||
|
#ifndef VARCHAR_WITH_DIFF_ENDSPACE_ARE_DIFFERENT_FOR_UNIQUE
|
||||||
|
diff_if_only_endspace_difference= 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
a= buf;
|
||||||
|
if ((a_length + b_length +2) > (int) sizeof(buf))
|
||||||
|
alloced= a= (uchar*) my_str_malloc(a_length+b_length+2);
|
||||||
|
|
||||||
|
b= a + a_length+1;
|
||||||
|
memcpy((char*) a, (char*) a0, a_length);
|
||||||
|
a[a_length]= 0; /* if length(a0)> len1, need to put 'end of string' */
|
||||||
|
memcpy((char *)b, (char *)b0, b_length);
|
||||||
|
b[b_length]= 0; /* put end of string */
|
||||||
|
a_length= thai2sortable(a, a_length);
|
||||||
|
b_length= thai2sortable(b, b_length);
|
||||||
|
|
||||||
|
end= a + (length= min(a_length, b_length));
|
||||||
|
while (a < end)
|
||||||
|
{
|
||||||
|
if (*a++ != *b++)
|
||||||
|
{
|
||||||
|
res= ((int) a[-1] - (int) b[-1]);
|
||||||
|
goto ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (a_length != b_length)
|
||||||
|
{
|
||||||
|
int swap= 1;
|
||||||
|
if (diff_if_only_endspace_difference)
|
||||||
|
res= 1; /* Assume 'a' is bigger */
|
||||||
|
/*
|
||||||
|
Check the next not space character of the longer key. If it's < ' ',
|
||||||
|
then it's smaller than the other key.
|
||||||
|
*/
|
||||||
|
if (a_length < b_length)
|
||||||
|
{
|
||||||
|
/* put shorter key in s */
|
||||||
|
a_length= b_length;
|
||||||
|
a= b;
|
||||||
|
swap= -1; /* swap sign of result */
|
||||||
|
res= -res;
|
||||||
|
}
|
||||||
|
for (end= a + a_length-length; a < end ; a++)
|
||||||
|
{
|
||||||
|
if (*a != ' ')
|
||||||
|
{
|
||||||
|
res= (*a < ' ') ? -swap : swap;
|
||||||
|
goto ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret:
|
||||||
|
|
||||||
|
if (alloced)
|
||||||
|
my_str_free(alloced);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
strnxfrm replacment, convert Thai string to sortable string
|
||||||
|
|
||||||
|
Arg: Destination buffer, source string, dest length and source length
|
||||||
|
Ret: Conveted string size
|
||||||
|
*/
|
||||||
|
|
||||||
|
static
|
||||||
|
size_t my_strnxfrm_tis620(CHARSET_INFO *cs __attribute__((unused)),
|
||||||
|
uchar *dest, size_t len,
|
||||||
|
const uchar *src, size_t srclen)
|
||||||
|
{
|
||||||
|
size_t dstlen= len;
|
||||||
|
len= (size_t) (strmake((char*) dest, (char*) src, min(len, srclen)) -
|
||||||
|
(char*) dest);
|
||||||
|
len= thai2sortable(dest, len);
|
||||||
|
if (dstlen > len)
|
||||||
|
bfill(dest + len, dstlen - len, ' ');
|
||||||
|
return dstlen;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static unsigned short cs_to_uni[256]={
|
||||||
|
0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,
|
||||||
|
0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F,
|
||||||
|
0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,
|
||||||
|
0x0018,0x0019,0x001A,0x001B,0x001C,0x001D,0x001E,0x001F,
|
||||||
|
0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,
|
||||||
|
0x0028,0x0029,0x002A,0x002B,0x002C,0x002D,0x002E,0x002F,
|
||||||
|
0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,
|
||||||
|
0x0038,0x0039,0x003A,0x003B,0x003C,0x003D,0x003E,0x003F,
|
||||||
|
0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,
|
||||||
|
0x0048,0x0049,0x004A,0x004B,0x004C,0x004D,0x004E,0x004F,
|
||||||
|
0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,
|
||||||
|
0x0058,0x0059,0x005A,0x005B,0x005C,0x005D,0x005E,0x005F,
|
||||||
|
0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,
|
||||||
|
0x0068,0x0069,0x006A,0x006B,0x006C,0x006D,0x006E,0x006F,
|
||||||
|
0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,
|
||||||
|
0x0078,0x0079,0x007A,0x007B,0x007C,0x007D,0x007E,0x007F,
|
||||||
|
0x0080,0x0081,0x0082,0x0083,0x0084,0x0085,0x0086,0x0087,
|
||||||
|
0x0088,0x0089,0x008A,0x008B,0x008C,0x008D,0x008E,0x008F,
|
||||||
|
0x0090,0x0091,0x0092,0x0093,0x0094,0x0095,0x0096,0x0097,
|
||||||
|
0x0098,0x0099,0x009A,0x009B,0x009C,0x009D,0x009E,0x009F,
|
||||||
|
0xFFFD,0x0E01,0x0E02,0x0E03,0x0E04,0x0E05,0x0E06,0x0E07,
|
||||||
|
0x0E08,0x0E09,0x0E0A,0x0E0B,0x0E0C,0x0E0D,0x0E0E,0x0E0F,
|
||||||
|
0x0E10,0x0E11,0x0E12,0x0E13,0x0E14,0x0E15,0x0E16,0x0E17,
|
||||||
|
0x0E18,0x0E19,0x0E1A,0x0E1B,0x0E1C,0x0E1D,0x0E1E,0x0E1F,
|
||||||
|
0x0E20,0x0E21,0x0E22,0x0E23,0x0E24,0x0E25,0x0E26,0x0E27,
|
||||||
|
0x0E28,0x0E29,0x0E2A,0x0E2B,0x0E2C,0x0E2D,0x0E2E,0x0E2F,
|
||||||
|
0x0E30,0x0E31,0x0E32,0x0E33,0x0E34,0x0E35,0x0E36,0x0E37,
|
||||||
|
0x0E38,0x0E39,0x0E3A,0xFFFD,0xFFFD,0xFFFD,0xFFFD,0x0E3F,
|
||||||
|
0x0E40,0x0E41,0x0E42,0x0E43,0x0E44,0x0E45,0x0E46,0x0E47,
|
||||||
|
0x0E48,0x0E49,0x0E4A,0x0E4B,0x0E4C,0x0E4D,0x0E4E,0x0E4F,
|
||||||
|
0x0E50,0x0E51,0x0E52,0x0E53,0x0E54,0x0E55,0x0E56,0x0E57,
|
||||||
|
0x0E58,0x0E59,0x0E5A,0x0E5B,0xFFFD,0xFFFD,0xFFFD,0xFFFD
|
||||||
|
};
|
||||||
|
static uchar pl00[256]={
|
||||||
|
0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,
|
||||||
|
0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F,
|
||||||
|
0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,
|
||||||
|
0x0018,0x0019,0x001A,0x001B,0x001C,0x001D,0x001E,0x001F,
|
||||||
|
0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,
|
||||||
|
0x0028,0x0029,0x002A,0x002B,0x002C,0x002D,0x002E,0x002F,
|
||||||
|
0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,
|
||||||
|
0x0038,0x0039,0x003A,0x003B,0x003C,0x003D,0x003E,0x003F,
|
||||||
|
0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,
|
||||||
|
0x0048,0x0049,0x004A,0x004B,0x004C,0x004D,0x004E,0x004F,
|
||||||
|
0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,
|
||||||
|
0x0058,0x0059,0x005A,0x005B,0x005C,0x005D,0x005E,0x005F,
|
||||||
|
0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,
|
||||||
|
0x0068,0x0069,0x006A,0x006B,0x006C,0x006D,0x006E,0x006F,
|
||||||
|
0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,
|
||||||
|
0x0078,0x0079,0x007A,0x007B,0x007C,0x007D,0x007E,0x007F,
|
||||||
|
0x0080,0x0081,0x0082,0x0083,0x0084,0x0085,0x0086,0x0087,
|
||||||
|
0x0088,0x0089,0x008A,0x008B,0x008C,0x008D,0x008E,0x008F,
|
||||||
|
0x0090,0x0091,0x0092,0x0093,0x0094,0x0095,0x0096,0x0097,
|
||||||
|
0x0098,0x0099,0x009A,0x009B,0x009C,0x009D,0x009E,0x009F,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
|
||||||
|
};
|
||||||
|
static uchar pl0E[256]={
|
||||||
|
0x0000,0x00A1,0x00A2,0x00A3,0x00A4,0x00A5,0x00A6,0x00A7,
|
||||||
|
0x00A8,0x00A9,0x00AA,0x00AB,0x00AC,0x00AD,0x00AE,0x00AF,
|
||||||
|
0x00B0,0x00B1,0x00B2,0x00B3,0x00B4,0x00B5,0x00B6,0x00B7,
|
||||||
|
0x00B8,0x00B9,0x00BA,0x00BB,0x00BC,0x00BD,0x00BE,0x00BF,
|
||||||
|
0x00C0,0x00C1,0x00C2,0x00C3,0x00C4,0x00C5,0x00C6,0x00C7,
|
||||||
|
0x00C8,0x00C9,0x00CA,0x00CB,0x00CC,0x00CD,0x00CE,0x00CF,
|
||||||
|
0x00D0,0x00D1,0x00D2,0x00D3,0x00D4,0x00D5,0x00D6,0x00D7,
|
||||||
|
0x00D8,0x00D9,0x00DA,0x0000,0x0000,0x0000,0x0000,0x00DF,
|
||||||
|
0x00E0,0x00E1,0x00E2,0x00E3,0x00E4,0x00E5,0x00E6,0x00E7,
|
||||||
|
0x00E8,0x00E9,0x00EA,0x00EB,0x00EC,0x00ED,0x00EE,0x00EF,
|
||||||
|
0x00F0,0x00F1,0x00F2,0x00F3,0x00F4,0x00F5,0x00F6,0x00F7,
|
||||||
|
0x00F8,0x00F9,0x00FA,0x00FB,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
|
||||||
|
};
|
||||||
|
static uchar plFF[256]={
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
|
||||||
|
0x0000,0x0000,0x0000,0x0000,0x0000,0x00FF,0x0000,0x0000
|
||||||
|
};
|
||||||
|
static uchar *uni_to_cs[256]={
|
||||||
|
pl00,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,pl0E,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,plFF
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
int my_mb_wc_tis620(CHARSET_INFO *cs __attribute__((unused)),
|
||||||
|
my_wc_t *wc,
|
||||||
|
const uchar *str,
|
||||||
|
const uchar *end __attribute__((unused)))
|
||||||
|
{
|
||||||
|
if (str >= end)
|
||||||
|
return MY_CS_TOOSMALL;
|
||||||
|
|
||||||
|
*wc=cs_to_uni[*str];
|
||||||
|
return (!wc[0] && str[0]) ? -1 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int my_wc_mb_tis620(CHARSET_INFO *cs __attribute__((unused)),
|
||||||
|
my_wc_t wc,
|
||||||
|
uchar *str,
|
||||||
|
uchar *end __attribute__((unused)))
|
||||||
|
{
|
||||||
|
uchar *pl;
|
||||||
|
|
||||||
|
if (str >= end)
|
||||||
|
return MY_CS_TOOSMALL;
|
||||||
|
|
||||||
|
pl= uni_to_cs[(wc>>8) & 0xFF];
|
||||||
|
str[0]= pl ? pl[wc & 0xFF] : '\0';
|
||||||
|
return (!str[0] && wc) ? MY_CS_ILUNI : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static MY_COLLATION_HANDLER my_collation_ci_handler =
|
||||||
|
{
|
||||||
|
NULL, /* init */
|
||||||
|
my_strnncoll_tis620,
|
||||||
|
my_strnncollsp_tis620,
|
||||||
|
my_strnxfrm_tis620,
|
||||||
|
my_strnxfrmlen_simple,
|
||||||
|
my_like_range_simple,
|
||||||
|
my_wildcmp_8bit, /* wildcmp */
|
||||||
|
my_strcasecmp_8bit,
|
||||||
|
my_instr_simple, /* QQ: To be fixed */
|
||||||
|
my_hash_sort_simple,
|
||||||
|
my_propagate_simple
|
||||||
|
};
|
||||||
|
|
||||||
|
static MY_CHARSET_HANDLER my_charset_handler=
|
||||||
|
{
|
||||||
|
NULL, /* init */
|
||||||
|
NULL, /* ismbchar */
|
||||||
|
my_mbcharlen_8bit, /* mbcharlen */
|
||||||
|
my_numchars_8bit,
|
||||||
|
my_charpos_8bit,
|
||||||
|
my_well_formed_len_8bit,
|
||||||
|
my_lengthsp_8bit,
|
||||||
|
my_numcells_8bit,
|
||||||
|
my_mb_wc_tis620, /* mb_wc */
|
||||||
|
my_wc_mb_tis620, /* wc_mb */
|
||||||
|
my_mb_ctype_8bit,
|
||||||
|
my_caseup_str_8bit,
|
||||||
|
my_casedn_str_8bit,
|
||||||
|
my_caseup_8bit,
|
||||||
|
my_casedn_8bit,
|
||||||
|
my_snprintf_8bit,
|
||||||
|
my_long10_to_str_8bit,
|
||||||
|
my_longlong10_to_str_8bit,
|
||||||
|
my_fill_8bit,
|
||||||
|
my_strntol_8bit,
|
||||||
|
my_strntoul_8bit,
|
||||||
|
my_strntoll_8bit,
|
||||||
|
my_strntoull_8bit,
|
||||||
|
my_strntod_8bit,
|
||||||
|
my_strtoll10_8bit,
|
||||||
|
my_strntoull10rnd_8bit,
|
||||||
|
my_scan_8bit
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
CHARSET_INFO my_charset_tis620_thai_ci=
|
||||||
|
{
|
||||||
|
18,0,0, /* number */
|
||||||
|
MY_CS_COMPILED|MY_CS_PRIMARY|MY_CS_STRNXFRM, /* state */
|
||||||
|
"tis620", /* cs name */
|
||||||
|
"tis620_thai_ci", /* name */
|
||||||
|
"", /* comment */
|
||||||
|
NULL, /* tailoring */
|
||||||
|
ctype_tis620,
|
||||||
|
to_lower_tis620,
|
||||||
|
to_upper_tis620,
|
||||||
|
sort_order_tis620,
|
||||||
|
NULL, /* contractions */
|
||||||
|
NULL, /* sort_order_big*/
|
||||||
|
NULL, /* tab_to_uni */
|
||||||
|
NULL, /* tab_from_uni */
|
||||||
|
my_unicase_default, /* caseinfo */
|
||||||
|
NULL, /* state_map */
|
||||||
|
NULL, /* ident_map */
|
||||||
|
4, /* strxfrm_multiply */
|
||||||
|
1, /* caseup_multiply */
|
||||||
|
1, /* casedn_multiply */
|
||||||
|
1, /* mbminlen */
|
||||||
|
1, /* mbmaxlen */
|
||||||
|
0, /* min_sort_char */
|
||||||
|
255, /* max_sort_char */
|
||||||
|
' ', /* pad char */
|
||||||
|
0, /* escape_with_backslash_is_dangerous */
|
||||||
|
&my_charset_handler,
|
||||||
|
&my_collation_ci_handler
|
||||||
|
};
|
||||||
|
|
||||||
|
CHARSET_INFO my_charset_tis620_bin=
|
||||||
|
{
|
||||||
|
89,0,0, /* number */
|
||||||
|
MY_CS_COMPILED|MY_CS_BINSORT, /* state */
|
||||||
|
"tis620", /* cs name */
|
||||||
|
"tis620_bin", /* name */
|
||||||
|
"", /* comment */
|
||||||
|
NULL, /* tailoring */
|
||||||
|
ctype_tis620,
|
||||||
|
to_lower_tis620,
|
||||||
|
to_upper_tis620,
|
||||||
|
NULL, /* sort_order */
|
||||||
|
NULL, /* contractions */
|
||||||
|
NULL, /* sort_order_big*/
|
||||||
|
NULL, /* tab_to_uni */
|
||||||
|
NULL, /* tab_from_uni */
|
||||||
|
my_unicase_default, /* caseinfo */
|
||||||
|
NULL, /* state_map */
|
||||||
|
NULL, /* ident_map */
|
||||||
|
1, /* strxfrm_multiply */
|
||||||
|
1, /* caseup_multiply */
|
||||||
|
1, /* casedn_multiply */
|
||||||
|
1, /* mbminlen */
|
||||||
|
1, /* mbmaxlen */
|
||||||
|
0, /* min_sort_char */
|
||||||
|
255, /* max_sort_char */
|
||||||
|
' ', /* pad char */
|
||||||
|
0, /* escape_with_backslash_is_dangerous */
|
||||||
|
&my_charset_handler,
|
||||||
|
&my_collation_8bit_bin_handler
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
9363
MySQL/ctype-uca.c
Normal file
9363
MySQL/ctype-uca.c
Normal file
File diff suppressed because it is too large
Load Diff
1777
MySQL/ctype-ucs2.c
Normal file
1777
MySQL/ctype-ucs2.c
Normal file
File diff suppressed because it is too large
Load Diff
8611
MySQL/ctype-ujis.c
Normal file
8611
MySQL/ctype-ujis.c
Normal file
File diff suppressed because it is too large
Load Diff
4286
MySQL/ctype-utf8.c
Normal file
4286
MySQL/ctype-utf8.c
Normal file
File diff suppressed because it is too large
Load Diff
715
MySQL/ctype-win1250ch.c
Normal file
715
MySQL/ctype-win1250ch.c
Normal file
@ -0,0 +1,715 @@
|
|||||||
|
/* Copyright (C) 2003 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Shared, independent copyright: (C) 2001 Jan Pazdziora.
|
||||||
|
|
||||||
|
Development of this software was supported by Neocortex, s.r.o.
|
||||||
|
MySQL AB expresses its gratitude to Jan for for giving us this software.
|
||||||
|
|
||||||
|
Bug reports and suggestions are always welcome.
|
||||||
|
|
||||||
|
This file implements the collating sequence for Windows-1250
|
||||||
|
character set. It merely extends the binary sorting of US-ASCII
|
||||||
|
by adding characters with diacritical marks into proper places.
|
||||||
|
In addition, it sorts 'ch' between 'h' and 'i', and the sorting
|
||||||
|
is case sensitive, with uppercase being sorted first, in the
|
||||||
|
second pass.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This comment is parsed by configure to create ctype.c,
|
||||||
|
* so don't change it unless you know what you are doing.
|
||||||
|
*
|
||||||
|
* .configure. strxfrm_multiply_win1250ch=2
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define REAL_MYSQL
|
||||||
|
#ifdef REAL_MYSQL
|
||||||
|
|
||||||
|
#include "my_global.h"
|
||||||
|
#include "m_string.h"
|
||||||
|
#include "m_ctype.h"
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#define uchar unsigned char
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_CHARSET_cp1250
|
||||||
|
|
||||||
|
|
||||||
|
static uint16 tab_cp1250_uni[256]={
|
||||||
|
0,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,
|
||||||
|
0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F,
|
||||||
|
0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,
|
||||||
|
0x0018,0x0019,0x001A,0x001B,0x001C,0x001D,0x001E,0x001F,
|
||||||
|
0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,
|
||||||
|
0x0028,0x0029,0x002A,0x002B,0x002C,0x002D,0x002E,0x002F,
|
||||||
|
0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,
|
||||||
|
0x0038,0x0039,0x003A,0x003B,0x003C,0x003D,0x003E,0x003F,
|
||||||
|
0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,
|
||||||
|
0x0048,0x0049,0x004A,0x004B,0x004C,0x004D,0x004E,0x004F,
|
||||||
|
0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,
|
||||||
|
0x0058,0x0059,0x005A,0x005B,0x005C,0x005D,0x005E,0x005F,
|
||||||
|
0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,
|
||||||
|
0x0068,0x0069,0x006A,0x006B,0x006C,0x006D,0x006E,0x006F,
|
||||||
|
0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,
|
||||||
|
0x0078,0x0079,0x007A,0x007B,0x007C,0x007D,0x007E,0x007F,
|
||||||
|
0x20AC, 0,0x201A, 0,0x201E,0x2026,0x2020,0x2021,
|
||||||
|
0,0x2030,0x0160,0x2039,0x015A,0x0164,0x017D,0x0179,
|
||||||
|
0,0x2018,0x2019,0x201C,0x201D,0x2022,0x2013,0x2014,
|
||||||
|
0,0x2122,0x0161,0x203A,0x015B,0x0165,0x017E,0x017A,
|
||||||
|
0x00A0,0x02C7,0x02D8,0x0141,0x00A4,0x0104,0x00A6,0x00A7,
|
||||||
|
0x00A8,0x00A9,0x015E,0x00AB,0x00AC,0x00AD,0x00AE,0x017B,
|
||||||
|
0x00B0,0x00B1,0x02DB,0x0142,0x00B4,0x00B5,0x00B6,0x00B7,
|
||||||
|
0x00B8,0x0105,0x015F,0x00BB,0x013D,0x02DD,0x013E,0x017C,
|
||||||
|
0x0154,0x00C1,0x00C2,0x0102,0x00C4,0x0139,0x0106,0x00C7,
|
||||||
|
0x010C,0x00C9,0x0118,0x00CB,0x011A,0x00CD,0x00CE,0x010E,
|
||||||
|
0x0110,0x0143,0x0147,0x00D3,0x00D4,0x0150,0x00D6,0x00D7,
|
||||||
|
0x0158,0x016E,0x00DA,0x0170,0x00DC,0x00DD,0x0162,0x00DF,
|
||||||
|
0x0155,0x00E1,0x00E2,0x0103,0x00E4,0x013A,0x0107,0x00E7,
|
||||||
|
0x010D,0x00E9,0x0119,0x00EB,0x011B,0x00ED,0x00EE,0x010F,
|
||||||
|
0x0111,0x0144,0x0148,0x00F3,0x00F4,0x0151,0x00F6,0x00F7,
|
||||||
|
0x0159,0x016F,0x00FA,0x0171,0x00FC,0x00FD,0x0163,0x02D9
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* 0000-00FD , 254 chars */
|
||||||
|
static uchar tab_uni_cp1250_plane00[]={
|
||||||
|
0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
|
||||||
|
0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
|
||||||
|
0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
|
||||||
|
0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
|
||||||
|
0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,
|
||||||
|
0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F,
|
||||||
|
0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
|
||||||
|
0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0xA0,0x00,0x00,0x00,0xA4,0x00,0xA6,0xA7,0xA8,0xA9,0x00,0xAB,0xAC,0xAD,0xAE,0x00,
|
||||||
|
0xB0,0xB1,0x00,0x00,0xB4,0xB5,0xB6,0xB7,0xB8,0x00,0x00,0xBB,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0xC1,0xC2,0x00,0xC4,0x00,0x00,0xC7,0x00,0xC9,0x00,0xCB,0x00,0xCD,0xCE,0x00,
|
||||||
|
0x00,0x00,0x00,0xD3,0xD4,0x00,0xD6,0xD7,0x00,0x00,0xDA,0x00,0xDC,0xDD,0x00,0xDF,
|
||||||
|
0x00,0xE1,0xE2,0x00,0xE4,0x00,0x00,0xE7,0x00,0xE9,0x00,0xEB,0x00,0xED,0xEE,0x00,
|
||||||
|
0x00,0x00,0x00,0xF3,0xF4,0x00,0xF6,0xF7,0x00,0x00,0xFA,0x00,0xFC,0xFD};
|
||||||
|
|
||||||
|
/* 0102-017E , 125 chars */
|
||||||
|
static uchar tab_uni_cp1250_plane01[]={
|
||||||
|
0xC3,0xE3,0xA5,0xB9,0xC6,0xE6,0x00,0x00,0x00,0x00,0xC8,0xE8,0xCF,0xEF,0xD0,0xF0,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0xCA,0xEA,0xCC,0xEC,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC5,0xE5,0x00,0x00,0xBC,0xBE,0x00,0x00,0xA3,
|
||||||
|
0xB3,0xD1,0xF1,0x00,0x00,0xD2,0xF2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xD5,0xF5,
|
||||||
|
0x00,0x00,0xC0,0xE0,0x00,0x00,0xD8,0xF8,0x8C,0x9C,0x00,0x00,0xAA,0xBA,0x8A,0x9A,
|
||||||
|
0xDE,0xFE,0x8D,0x9D,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xD9,0xF9,0xDB,0xFB,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x8F,0x9F,0xAF,0xBF,0x8E,0x9E};
|
||||||
|
|
||||||
|
/* 2013-20AC , 154 chars */
|
||||||
|
static uchar tab_uni_cp1250_plane20[]={
|
||||||
|
0x96,0x97,0x00,0x00,0x00,0x91,0x92,0x82,0x00,0x93,0x94,0x84,0x00,0x86,0x87,0x95,
|
||||||
|
0x00,0x00,0x00,0x85,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x89,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x8B,0x9B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80};
|
||||||
|
|
||||||
|
/* 02C7-02DD , 23 chars */
|
||||||
|
static uchar tab_uni_cp1250_plane02[]={
|
||||||
|
0xA1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0xA2,0xFF,0x00,0xB2,0x00,0xBD};
|
||||||
|
|
||||||
|
/* 2122-2122 , 1 chars */
|
||||||
|
static uchar tab_uni_cp1250_plane21[]={
|
||||||
|
0x99};
|
||||||
|
|
||||||
|
|
||||||
|
static MY_UNI_IDX idx_uni_cp1250[]={
|
||||||
|
{0x0000,0x00FD,tab_uni_cp1250_plane00},
|
||||||
|
{0x0102,0x017E,tab_uni_cp1250_plane01},
|
||||||
|
{0x2013,0x20AC,tab_uni_cp1250_plane20},
|
||||||
|
{0x02C7,0x02DD,tab_uni_cp1250_plane02},
|
||||||
|
{0x2122,0x2122,tab_uni_cp1250_plane21},
|
||||||
|
{0,0,NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static uchar NEAR ctype_win1250ch[] = {
|
||||||
|
0x00,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x28, 0x28, 0x28, 0x28, 0x28, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x48, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
|
||||||
|
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
|
||||||
|
0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
|
||||||
|
0x84, 0x84, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
|
||||||
|
0x10, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x01,
|
||||||
|
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||||
|
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||||
|
0x01, 0x01, 0x01, 0x10, 0x10, 0x10, 0x10, 0x10,
|
||||||
|
0x10, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x02,
|
||||||
|
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
|
||||||
|
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
|
||||||
|
0x02, 0x02, 0x02, 0x10, 0x10, 0x10, 0x10, 0x20,
|
||||||
|
0x20, 0x20, 0x10, 0x20, 0x10, 0x10, 0x10, 0x10,
|
||||||
|
0x20, 0x10, 0x01, 0x10, 0x01, 0x01, 0x01, 0x01,
|
||||||
|
0x20, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
|
||||||
|
0x20, 0x10, 0x02, 0x10, 0x02, 0x02, 0x02, 0x02,
|
||||||
|
0x48, 0x10, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01,
|
||||||
|
0x10, 0x10, 0x01, 0x10, 0x10, 0x10, 0x10, 0x01,
|
||||||
|
0x10, 0x10, 0x10, 0x02, 0x10, 0x10, 0x10, 0x10,
|
||||||
|
0x10, 0x02, 0x02, 0x10, 0x01, 0x10, 0x02, 0x02,
|
||||||
|
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||||
|
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||||
|
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x10,
|
||||||
|
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
|
||||||
|
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
|
||||||
|
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
|
||||||
|
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x10,
|
||||||
|
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x10
|
||||||
|
};
|
||||||
|
|
||||||
|
static uchar NEAR to_lower_win1250ch[] = {
|
||||||
|
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||||
|
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||||
|
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
||||||
|
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
||||||
|
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
|
||||||
|
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
|
||||||
|
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
|
||||||
|
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
|
||||||
|
0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
|
||||||
|
0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
|
||||||
|
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
|
||||||
|
0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
|
||||||
|
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
|
||||||
|
0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
|
||||||
|
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
|
||||||
|
0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
|
||||||
|
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
|
||||||
|
0x88, 0x89, 0x9a, 0x8b, 0x9c, 0x9d, 0x9e, 0x9f,
|
||||||
|
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
|
||||||
|
0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
|
||||||
|
0xa0, 0xa1, 0xa2, 0xb3, 0xa4, 0xb9, 0xa6, 0xdf,
|
||||||
|
0xa8, 0xa9, 0xba, 0xab, 0xac, 0xad, 0xae, 0xbf,
|
||||||
|
0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
|
||||||
|
0xb8, 0xb9, 0xba, 0xbb, 0xbe, 0xbd, 0xbe, 0xbf,
|
||||||
|
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
|
||||||
|
0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
|
||||||
|
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xd7,
|
||||||
|
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xdf,
|
||||||
|
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
|
||||||
|
0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
|
||||||
|
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
|
||||||
|
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
|
||||||
|
};
|
||||||
|
|
||||||
|
static uchar NEAR to_upper_win1250ch[] = {
|
||||||
|
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||||
|
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||||
|
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
||||||
|
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
||||||
|
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
|
||||||
|
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
|
||||||
|
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
|
||||||
|
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
|
||||||
|
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
|
||||||
|
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
|
||||||
|
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
|
||||||
|
0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
|
||||||
|
0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
|
||||||
|
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
|
||||||
|
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
|
||||||
|
0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
|
||||||
|
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
|
||||||
|
0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
|
||||||
|
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
|
||||||
|
0x98, 0x99, 0x8a, 0x9b, 0x8c, 0x8d, 0x8e, 0x8f,
|
||||||
|
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
|
||||||
|
0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
|
||||||
|
0xb0, 0xb1, 0xb2, 0xa3, 0xb4, 0xb5, 0xb6, 0xb7,
|
||||||
|
0xb8, 0xa5, 0xaa, 0xbb, 0xbc, 0xbd, 0xbc, 0xaf,
|
||||||
|
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
|
||||||
|
0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
|
||||||
|
0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
|
||||||
|
0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xa7,
|
||||||
|
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
|
||||||
|
0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
|
||||||
|
0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xf7,
|
||||||
|
0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xff
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static uchar NEAR sort_order_win1250ch[] = {
|
||||||
|
0, 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, 171, 172, 173, 174, 175,
|
||||||
|
176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
|
||||||
|
192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
|
||||||
|
208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
|
||||||
|
224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
|
||||||
|
240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
|
||||||
|
};
|
||||||
|
|
||||||
|
static uchar NEAR _sort_order_win1250ch1[] = {
|
||||||
|
0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
|
||||||
|
0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
|
||||||
|
0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
|
||||||
|
0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
|
||||||
|
/* space ord 32 0x20 */
|
||||||
|
0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
|
||||||
|
0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91,
|
||||||
|
/* 0 ord 48 0x30 */
|
||||||
|
0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
|
||||||
|
0x9a, 0x9b,
|
||||||
|
/* colon ord 58 0x3a */
|
||||||
|
0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1,
|
||||||
|
0xa2,
|
||||||
|
/* A ord 65 0x41 */
|
||||||
|
0xa4, 0xa5,
|
||||||
|
/* C ord 67 0x43 */
|
||||||
|
0xff, 0xa8, 0xa9, 0xaa, 0xab,
|
||||||
|
0xac, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4,
|
||||||
|
0xb5, 0xb6,
|
||||||
|
/* R ord 82 0x52 */
|
||||||
|
0xb7,
|
||||||
|
/* S ord 83 0x53 */
|
||||||
|
0xb9, 0xbc, 0xbd, 0xbe, 0xbf,
|
||||||
|
0xc0, 0xc1, 0xc2,
|
||||||
|
/* [ ord 91 0x5b */
|
||||||
|
0xc4, 0xc5, 0xc6, 0xc7, 0xc8,
|
||||||
|
0xc9,
|
||||||
|
/* a ord 97 0x61 */
|
||||||
|
0xa4, 0xa5, 0xff, 0xa8, 0xa9, 0xaa, 0xab,
|
||||||
|
0xac, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4,
|
||||||
|
0xb5, 0xb6, 0xb7, 0xb9, 0xbc, 0xbd, 0xbe, 0xbf,
|
||||||
|
0xc0, 0xc1, 0xc2,
|
||||||
|
/* { ord 123 0x7b */
|
||||||
|
0xca, 0xcb, 0xcc, 0xcd, 0x81,
|
||||||
|
0x81, 0x81, 0xce, 0x81, 0xcf, 0xd0, 0xd1, 0xd2,
|
||||||
|
0x81, 0xd3,
|
||||||
|
/* Scaron ord 138 0x8a */
|
||||||
|
0xba, 0xd4, 0xb9, 0xbc, 0xc3, 0xc2,
|
||||||
|
0x81, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb,
|
||||||
|
0x81, 0xdc, 0xba, 0xdd, 0xb9, 0xbc, 0xc3, 0xc2,
|
||||||
|
/* nobreakspace ord 160 0xa0 */
|
||||||
|
0x82, 0xde, 0xdf, 0xb1, 0xe0, 0xa4, 0xe1, 0xe2,
|
||||||
|
0xe3, 0xe4, 0xb9, 0xe5, 0xe6, 0xe7, 0xe8, 0xc2,
|
||||||
|
0xe9, 0xea, 0xeb, 0xb1, 0xed, 0xee, 0x81, 0xef,
|
||||||
|
/* cedilla ord 183 0xb8 */
|
||||||
|
0xf0, 0xa4, 0xb9, 0xf1, 0xb1, 0xf2, 0xb1, 0xc2,
|
||||||
|
0xb7, 0xa4, 0xa4, 0xa4, 0xa4, 0xb1, 0xa6, 0xa6,
|
||||||
|
0xa7, 0xa9, 0xa9, 0xa9, 0xa9, 0xae, 0xae, 0xa8,
|
||||||
|
/* Eth ord 208 0xd0 */
|
||||||
|
0xa8, 0xb3, 0xb3, 0xb4, 0xb4, 0xb4, 0xb4, 0xf3,
|
||||||
|
0xb8, 0xbd, 0xbd, 0xbd, 0xbd, 0xc1, 0xbc, 0xbb,
|
||||||
|
/* racute ord 224 0xe0 */
|
||||||
|
0xb7, 0xa4, 0xa4, 0xa4, 0xa4, 0xb1, 0xa6, 0xa6,
|
||||||
|
0xa7, 0xa9, 0xa9, 0xa9, 0xa9, 0xae, 0xae, 0xa8,
|
||||||
|
/* eth ord 240 0xf0 */
|
||||||
|
0xa8, 0xb3, 0xb3, 0xb4, 0xb4, 0xb4, 0xb4, 0xf4,
|
||||||
|
0xb8, 0xbd, 0xbd, 0xbd, 0xbd, 0xc1, 0xbc, 0xf5
|
||||||
|
};
|
||||||
|
|
||||||
|
static uchar NEAR _sort_order_win1250ch2[] = {
|
||||||
|
0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
|
||||||
|
0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
|
||||||
|
0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
|
||||||
|
0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21,
|
||||||
|
/* space ord 32 0x20 */
|
||||||
|
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||||
|
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||||
|
/* 0 ord 48 0x30 */
|
||||||
|
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||||
|
0x01, 0x01,
|
||||||
|
/* colon ord 58 0x3a */
|
||||||
|
0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||||
|
0x01,
|
||||||
|
/* A ord 65 0x41 */
|
||||||
|
0x01, 0x01,
|
||||||
|
/* C ord 67 0x43 */
|
||||||
|
0xff, 0x01, 0x01, 0x01, 0x01,
|
||||||
|
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||||
|
0x01, 0x01,
|
||||||
|
/* R ord 82 0x52 */
|
||||||
|
0x01,
|
||||||
|
/* S ord 83 0x53 */
|
||||||
|
0x01, 0x01, 0x01, 0x01, 0x01,
|
||||||
|
0x01, 0x01, 0x01,
|
||||||
|
/* [ ord 91 0x5b */
|
||||||
|
0x01, 0x01, 0x01, 0x01, 0x01,
|
||||||
|
0x01,
|
||||||
|
/* a ord 97 0x61 */
|
||||||
|
0x02, 0x02, 0xff, 0x02, 0x02, 0x02, 0x02,
|
||||||
|
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
|
||||||
|
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
|
||||||
|
0x02, 0x02, 0x02,
|
||||||
|
/* { ord 123 0x7b */
|
||||||
|
0x01, 0x01, 0x01, 0x01, 0x22,
|
||||||
|
0x23, 0x24, 0x01, 0x25, 0x01, 0x01, 0x01, 0x01,
|
||||||
|
0x26, 0x01,
|
||||||
|
/* Scaron ord 138 0x8a */
|
||||||
|
0x01, 0x01, 0x03, 0x03, 0x01, 0x05,
|
||||||
|
0x27, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||||
|
0x28, 0x01, 0x02, 0x01, 0x04, 0x04, 0x02, 0x06,
|
||||||
|
/* nobreakspace ord 160 0xa0 */
|
||||||
|
0x02, 0x01, 0x01, 0x07, 0x01, 0x11, 0x01, 0x01,
|
||||||
|
0x01, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x03,
|
||||||
|
0x01, 0x01, 0x01, 0x08, 0x01, 0x01, 0x29, 0x01,
|
||||||
|
/* cedilla ord 184 0xb8 */
|
||||||
|
0x01, 0x12, 0x06, 0x01, 0x05, 0x01, 0x06, 0x04,
|
||||||
|
0x03, 0x03, 0x05, 0x07, 0x09, 0x03, 0x03, 0x05,
|
||||||
|
0x01, 0x03, 0x09, 0x07, 0x05, 0x03, 0x05, 0x03,
|
||||||
|
/* Eth ord 208 0xd0 */
|
||||||
|
0x05, 0x03, 0x05, 0x03, 0x05, 0x09, 0x07, 0x01,
|
||||||
|
0x01, 0x05, 0x03, 0x09, 0x07, 0x03, 0x05, 0x01,
|
||||||
|
/* racute ord 224 0xe0 */
|
||||||
|
0x04, 0x04, 0x06, 0x08, 0x0a, 0x04, 0x04, 0x06,
|
||||||
|
0x02, 0x04, 0x0a, 0x08, 0x06, 0x04, 0x06, 0x04,
|
||||||
|
/* eth ord 240 0xf0 */
|
||||||
|
0x06, 0x04, 0x06, 0x04, 0x06, 0x0a, 0x08, 0x01,
|
||||||
|
0x02, 0x06, 0x04, 0x0a, 0x08, 0x04, 0x06, 0x01
|
||||||
|
};
|
||||||
|
|
||||||
|
struct wordvalue {
|
||||||
|
const uchar *word;
|
||||||
|
uchar pass1;
|
||||||
|
uchar pass2;
|
||||||
|
};
|
||||||
|
static struct wordvalue doubles[] = {
|
||||||
|
{ (uchar*) "ch", 0xad, 0x03 },
|
||||||
|
{ (uchar*) "c", 0xa6, 0x02 },
|
||||||
|
{ (uchar*) "Ch", 0xad, 0x02 },
|
||||||
|
{ (uchar*) "CH", 0xad, 0x01 },
|
||||||
|
{ (uchar*) "C", 0xa6, 0x01 },
|
||||||
|
};
|
||||||
|
|
||||||
|
#define NEXT_CMP_VALUE(src, p, pass, value, len) \
|
||||||
|
while (1) { \
|
||||||
|
if (IS_END(p, src, len)) { \
|
||||||
|
if (pass == 0 && len > 0) { p= src; pass++; } \
|
||||||
|
else { value = 0; break; } \
|
||||||
|
} \
|
||||||
|
value = ((pass == 0) ? _sort_order_win1250ch1[*p] \
|
||||||
|
: _sort_order_win1250ch2[*p]); \
|
||||||
|
if (value == 0xff) { \
|
||||||
|
int i; \
|
||||||
|
for (i = 0; i < (int) sizeof(doubles); i++) { \
|
||||||
|
const uchar *patt = doubles[i].word; \
|
||||||
|
const uchar *q = (const uchar *) p; \
|
||||||
|
while (*patt \
|
||||||
|
&& !(IS_END(q, src, len)) \
|
||||||
|
&& (*patt == *q)) { \
|
||||||
|
patt++; q++; \
|
||||||
|
} \
|
||||||
|
if (!(*patt)) { \
|
||||||
|
value = (int)((pass == 0) \
|
||||||
|
? doubles[i].pass1 \
|
||||||
|
: doubles[i].pass2); \
|
||||||
|
p = (const uchar *) q - 1; \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
p++; \
|
||||||
|
break; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define IS_END(p, src, len) (((char *)p - (char *)src) >= (len))
|
||||||
|
|
||||||
|
static int my_strnncoll_win1250ch(CHARSET_INFO *cs __attribute__((unused)),
|
||||||
|
const uchar *s1, size_t len1,
|
||||||
|
const uchar *s2, size_t len2,
|
||||||
|
my_bool s2_is_prefix)
|
||||||
|
{
|
||||||
|
int v1, v2;
|
||||||
|
const uchar *p1, * p2;
|
||||||
|
int pass1 = 0, pass2 = 0;
|
||||||
|
int diff;
|
||||||
|
|
||||||
|
if (s2_is_prefix && len1 > len2)
|
||||||
|
len1=len2;
|
||||||
|
|
||||||
|
p1 = s1; p2 = s2;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
NEXT_CMP_VALUE(s1, p1, pass1, v1, (int)len1);
|
||||||
|
NEXT_CMP_VALUE(s2, p2, pass2, v2, (int)len2);
|
||||||
|
if ((diff = v1 - v2))
|
||||||
|
return diff;
|
||||||
|
} while (v1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
TODO: Has to be fixed as strnncollsp in ctype-simple
|
||||||
|
*/
|
||||||
|
|
||||||
|
static
|
||||||
|
int my_strnncollsp_win1250ch(CHARSET_INFO * cs,
|
||||||
|
const uchar *s, size_t slen,
|
||||||
|
const uchar *t, size_t tlen,
|
||||||
|
my_bool diff_if_only_endspace_difference
|
||||||
|
__attribute__((unused)))
|
||||||
|
{
|
||||||
|
for ( ; slen && s[slen-1] == ' ' ; slen--);
|
||||||
|
for ( ; tlen && t[tlen-1] == ' ' ; tlen--);
|
||||||
|
return my_strnncoll_win1250ch(cs,s,slen,t,tlen,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static size_t my_strnxfrm_win1250ch(CHARSET_INFO * cs __attribute__((unused)),
|
||||||
|
uchar *dest, size_t len,
|
||||||
|
const uchar *src, size_t srclen)
|
||||||
|
{
|
||||||
|
int value;
|
||||||
|
const uchar *p;
|
||||||
|
int pass = 0;
|
||||||
|
size_t totlen = 0;
|
||||||
|
p = src;
|
||||||
|
|
||||||
|
do {
|
||||||
|
NEXT_CMP_VALUE(src, p, pass, value, (int)srclen);
|
||||||
|
if (totlen <= len)
|
||||||
|
dest[totlen] = value;
|
||||||
|
totlen++;
|
||||||
|
} while (value) ;
|
||||||
|
if (len > totlen)
|
||||||
|
bfill(dest + totlen, len - totlen, ' ');
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef IS_END
|
||||||
|
|
||||||
|
#ifdef REAL_MYSQL
|
||||||
|
|
||||||
|
static uchar NEAR like_range_prefix_min_win1250ch[]=
|
||||||
|
{
|
||||||
|
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||||
|
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
||||||
|
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
||||||
|
0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
|
||||||
|
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
|
||||||
|
0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
|
||||||
|
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
|
||||||
|
0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
|
||||||
|
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
|
||||||
|
0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
|
||||||
|
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
|
||||||
|
0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
|
||||||
|
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
|
||||||
|
0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
|
||||||
|
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
|
||||||
|
0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
|
||||||
|
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
|
||||||
|
0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
|
||||||
|
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
|
||||||
|
0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
|
||||||
|
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
|
||||||
|
0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
|
||||||
|
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7,
|
||||||
|
0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
|
||||||
|
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
|
||||||
|
0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
|
||||||
|
0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,
|
||||||
|
0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
|
||||||
|
0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
|
||||||
|
0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
|
||||||
|
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
|
||||||
|
0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
The letter "C" is a special case:
|
||||||
|
"CH" is sorted between "H" and "I".
|
||||||
|
prefix_max for "C" is "I": prefix_max[0x43] == 0x49
|
||||||
|
prefix_max for "c" is "i": prefix_max[0x63] == 0x69
|
||||||
|
For all other characters: prefix_max[i] == i
|
||||||
|
*/
|
||||||
|
|
||||||
|
static uchar NEAR like_range_prefix_max_win1250ch[]=
|
||||||
|
{
|
||||||
|
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||||
|
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
||||||
|
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
||||||
|
0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
|
||||||
|
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
|
||||||
|
0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
|
||||||
|
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
|
||||||
|
0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
|
||||||
|
0x40, 0x41, 0x42, 0x49, 0x44, 0x45, 0x46, 0x47,
|
||||||
|
0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
|
||||||
|
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
|
||||||
|
0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
|
||||||
|
0x60, 0x61, 0x62, 0x69, 0x64, 0x65, 0x66, 0x67,
|
||||||
|
0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
|
||||||
|
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
|
||||||
|
0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
|
||||||
|
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
|
||||||
|
0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
|
||||||
|
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
|
||||||
|
0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
|
||||||
|
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
|
||||||
|
0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
|
||||||
|
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7,
|
||||||
|
0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
|
||||||
|
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
|
||||||
|
0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
|
||||||
|
0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,
|
||||||
|
0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
|
||||||
|
0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
|
||||||
|
0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
|
||||||
|
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
|
||||||
|
0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
|
||||||
|
};
|
||||||
|
|
||||||
|
#define min_sort_char '\x20'
|
||||||
|
#define max_sort_char '\xff'
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Calculate min_str and max_str that ranges a LIKE string.
|
||||||
|
** Arguments:
|
||||||
|
** ptr Pointer to LIKE string.
|
||||||
|
** ptr_length Length of LIKE string.
|
||||||
|
** escape Escape character in LIKE. (Normally '\').
|
||||||
|
** All escape characters should be removed from min_str and max_str
|
||||||
|
** res_length Length of min_str and max_str.
|
||||||
|
** min_str Smallest case sensitive string that ranges LIKE.
|
||||||
|
** Should be space padded to res_length.
|
||||||
|
** max_str Largest case sensitive string that ranges LIKE.
|
||||||
|
** Normally padded with the biggest character sort value.
|
||||||
|
**
|
||||||
|
** The function should return 0 if ok and 1 if the LIKE string can't be
|
||||||
|
** optimized !
|
||||||
|
*/
|
||||||
|
|
||||||
|
static my_bool
|
||||||
|
my_like_range_win1250ch(CHARSET_INFO *cs __attribute__((unused)),
|
||||||
|
const char *ptr, size_t ptr_length,
|
||||||
|
pbool escape, pbool w_one, pbool w_many,
|
||||||
|
size_t res_length,
|
||||||
|
char *min_str, char *max_str,
|
||||||
|
size_t *min_length, size_t *max_length)
|
||||||
|
{
|
||||||
|
|
||||||
|
int only_min_found= 1;
|
||||||
|
const char *end = ptr + ptr_length;
|
||||||
|
char *min_org = min_str;
|
||||||
|
char *min_end = min_str + res_length;
|
||||||
|
|
||||||
|
/* return 1; */
|
||||||
|
|
||||||
|
for (; ptr != end && min_str != min_end ; ptr++)
|
||||||
|
{
|
||||||
|
if (*ptr == escape && ptr+1 != end)
|
||||||
|
ptr++; /* Skip escape */
|
||||||
|
else if (*ptr == w_one || *ptr == w_many) /* '_' or '%' in SQL */
|
||||||
|
break;
|
||||||
|
*min_str= like_range_prefix_min_win1250ch[(uint) (uchar) (*ptr)];
|
||||||
|
if (*min_str != min_sort_char)
|
||||||
|
only_min_found= 0;
|
||||||
|
min_str++;
|
||||||
|
*max_str++= like_range_prefix_max_win1250ch[(uint) (uchar) (*ptr)];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cs->state & MY_CS_BINSORT)
|
||||||
|
*min_length= (size_t) (min_str - min_org);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* 'a\0\0... is the smallest possible string */
|
||||||
|
*min_length= res_length;
|
||||||
|
}
|
||||||
|
/* a\ff\ff... is the biggest possible string */
|
||||||
|
*max_length= res_length;
|
||||||
|
|
||||||
|
while (min_str != min_end)
|
||||||
|
{
|
||||||
|
*min_str++ = min_sort_char;
|
||||||
|
*max_str++ = max_sort_char;
|
||||||
|
}
|
||||||
|
return (only_min_found);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static MY_COLLATION_HANDLER my_collation_czech_ci_handler =
|
||||||
|
{
|
||||||
|
NULL, /* init */
|
||||||
|
my_strnncoll_win1250ch,
|
||||||
|
my_strnncollsp_win1250ch,
|
||||||
|
my_strnxfrm_win1250ch,
|
||||||
|
my_strnxfrmlen_simple,
|
||||||
|
my_like_range_win1250ch,
|
||||||
|
my_wildcmp_8bit,
|
||||||
|
my_strcasecmp_8bit,
|
||||||
|
my_instr_simple,
|
||||||
|
my_hash_sort_simple,
|
||||||
|
my_propagate_simple
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
CHARSET_INFO my_charset_cp1250_czech_ci =
|
||||||
|
{
|
||||||
|
34,0,0, /* number */
|
||||||
|
MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_CSSORT, /* state */
|
||||||
|
"cp1250", /* cs name */
|
||||||
|
"cp1250_czech_cs", /* name */
|
||||||
|
"", /* comment */
|
||||||
|
NULL, /* tailoring */
|
||||||
|
ctype_win1250ch,
|
||||||
|
to_lower_win1250ch,
|
||||||
|
to_upper_win1250ch,
|
||||||
|
sort_order_win1250ch,
|
||||||
|
NULL, /* contractions */
|
||||||
|
NULL, /* sort_order_big*/
|
||||||
|
tab_cp1250_uni, /* tab_to_uni */
|
||||||
|
idx_uni_cp1250, /* tab_from_uni */
|
||||||
|
my_unicase_default, /* caseinfo */
|
||||||
|
NULL, /* state_map */
|
||||||
|
NULL, /* ident_map */
|
||||||
|
2, /* strxfrm_multiply */
|
||||||
|
1, /* caseup_multiply */
|
||||||
|
1, /* casedn_multiply */
|
||||||
|
1, /* mbminlen */
|
||||||
|
1, /* mbmaxlen */
|
||||||
|
0, /* min_sort_char */
|
||||||
|
0, /* max_sort_char */
|
||||||
|
' ', /* pad char */
|
||||||
|
0, /* escape_with_backslash_is_dangerous */
|
||||||
|
&my_charset_8bit_handler,
|
||||||
|
&my_collation_czech_ci_handler
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* REAL_MYSQL */
|
||||||
|
|
||||||
|
#endif /* HAVE_CHARSET_cp1250 */
|
407
MySQL/ctype.c
Normal file
407
MySQL/ctype.c
Normal file
@ -0,0 +1,407 @@
|
|||||||
|
/* Copyright (C) 2000 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
#include <my_global.h>
|
||||||
|
#include <m_ctype.h>
|
||||||
|
#include <my_xml.h>
|
||||||
|
#ifndef SCO
|
||||||
|
#include <m_string.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
This files implements routines which parse XML based
|
||||||
|
character set and collation description files.
|
||||||
|
|
||||||
|
Unicode collations are encoded according to
|
||||||
|
|
||||||
|
Unicode Technical Standard #35
|
||||||
|
Locale Data Markup Language (LDML)
|
||||||
|
http://www.unicode.org/reports/tr35/
|
||||||
|
|
||||||
|
and converted into ICU string according to
|
||||||
|
|
||||||
|
Collation Customization
|
||||||
|
http://oss.software.ibm.com/icu/userguide/Collate_Customization.html
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
static char *mstr(char *str,const char *src,size_t l1,size_t l2)
|
||||||
|
{
|
||||||
|
l1= l1<l2 ? l1 : l2;
|
||||||
|
memcpy(str,src,l1);
|
||||||
|
str[l1]='\0';
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct my_cs_file_section_st
|
||||||
|
{
|
||||||
|
int state;
|
||||||
|
const char *str;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define _CS_MISC 1
|
||||||
|
#define _CS_ID 2
|
||||||
|
#define _CS_CSNAME 3
|
||||||
|
#define _CS_FAMILY 4
|
||||||
|
#define _CS_ORDER 5
|
||||||
|
#define _CS_COLNAME 6
|
||||||
|
#define _CS_FLAG 7
|
||||||
|
#define _CS_CHARSET 8
|
||||||
|
#define _CS_COLLATION 9
|
||||||
|
#define _CS_UPPERMAP 10
|
||||||
|
#define _CS_LOWERMAP 11
|
||||||
|
#define _CS_UNIMAP 12
|
||||||
|
#define _CS_COLLMAP 13
|
||||||
|
#define _CS_CTYPEMAP 14
|
||||||
|
#define _CS_PRIMARY_ID 15
|
||||||
|
#define _CS_BINARY_ID 16
|
||||||
|
#define _CS_CSDESCRIPT 17
|
||||||
|
#define _CS_RESET 18
|
||||||
|
#define _CS_DIFF1 19
|
||||||
|
#define _CS_DIFF2 20
|
||||||
|
#define _CS_DIFF3 21
|
||||||
|
|
||||||
|
|
||||||
|
static struct my_cs_file_section_st sec[] =
|
||||||
|
{
|
||||||
|
{_CS_MISC, "xml"},
|
||||||
|
{_CS_MISC, "xml/version"},
|
||||||
|
{_CS_MISC, "xml/encoding"},
|
||||||
|
{_CS_MISC, "charsets"},
|
||||||
|
{_CS_MISC, "charsets/max-id"},
|
||||||
|
{_CS_CHARSET, "charsets/charset"},
|
||||||
|
{_CS_PRIMARY_ID, "charsets/charset/primary-id"},
|
||||||
|
{_CS_BINARY_ID, "charsets/charset/binary-id"},
|
||||||
|
{_CS_CSNAME, "charsets/charset/name"},
|
||||||
|
{_CS_FAMILY, "charsets/charset/family"},
|
||||||
|
{_CS_CSDESCRIPT, "charsets/charset/description"},
|
||||||
|
{_CS_MISC, "charsets/charset/alias"},
|
||||||
|
{_CS_MISC, "charsets/charset/ctype"},
|
||||||
|
{_CS_CTYPEMAP, "charsets/charset/ctype/map"},
|
||||||
|
{_CS_MISC, "charsets/charset/upper"},
|
||||||
|
{_CS_UPPERMAP, "charsets/charset/upper/map"},
|
||||||
|
{_CS_MISC, "charsets/charset/lower"},
|
||||||
|
{_CS_LOWERMAP, "charsets/charset/lower/map"},
|
||||||
|
{_CS_MISC, "charsets/charset/unicode"},
|
||||||
|
{_CS_UNIMAP, "charsets/charset/unicode/map"},
|
||||||
|
{_CS_COLLATION, "charsets/charset/collation"},
|
||||||
|
{_CS_COLNAME, "charsets/charset/collation/name"},
|
||||||
|
{_CS_ID, "charsets/charset/collation/id"},
|
||||||
|
{_CS_ORDER, "charsets/charset/collation/order"},
|
||||||
|
{_CS_FLAG, "charsets/charset/collation/flag"},
|
||||||
|
{_CS_COLLMAP, "charsets/charset/collation/map"},
|
||||||
|
{_CS_RESET, "charsets/charset/collation/rules/reset"},
|
||||||
|
{_CS_DIFF1, "charsets/charset/collation/rules/p"},
|
||||||
|
{_CS_DIFF2, "charsets/charset/collation/rules/s"},
|
||||||
|
{_CS_DIFF3, "charsets/charset/collation/rules/t"},
|
||||||
|
{0, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct my_cs_file_section_st * cs_file_sec(const char *attr, size_t len)
|
||||||
|
{
|
||||||
|
struct my_cs_file_section_st *s;
|
||||||
|
for (s=sec; s->str; s++)
|
||||||
|
{
|
||||||
|
if (!strncmp(attr,s->str,len))
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MY_CS_CSDESCR_SIZE 64
|
||||||
|
#define MY_CS_TAILORING_SIZE 1024
|
||||||
|
|
||||||
|
typedef struct my_cs_file_info
|
||||||
|
{
|
||||||
|
char csname[MY_CS_NAME_SIZE];
|
||||||
|
char name[MY_CS_NAME_SIZE];
|
||||||
|
uchar ctype[MY_CS_CTYPE_TABLE_SIZE];
|
||||||
|
uchar to_lower[MY_CS_TO_LOWER_TABLE_SIZE];
|
||||||
|
uchar to_upper[MY_CS_TO_UPPER_TABLE_SIZE];
|
||||||
|
uchar sort_order[MY_CS_SORT_ORDER_TABLE_SIZE];
|
||||||
|
uint16 tab_to_uni[MY_CS_TO_UNI_TABLE_SIZE];
|
||||||
|
char comment[MY_CS_CSDESCR_SIZE];
|
||||||
|
char tailoring[MY_CS_TAILORING_SIZE];
|
||||||
|
size_t tailoring_length;
|
||||||
|
CHARSET_INFO cs;
|
||||||
|
int (*add_collation)(CHARSET_INFO *cs);
|
||||||
|
} MY_CHARSET_LOADER;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static int fill_uchar(uchar *a,uint size,const char *str, size_t len)
|
||||||
|
{
|
||||||
|
uint i= 0;
|
||||||
|
const char *s, *b, *e=str+len;
|
||||||
|
|
||||||
|
for (s=str ; s < e ; i++)
|
||||||
|
{
|
||||||
|
for ( ; (s < e) && strchr(" \t\r\n",s[0]); s++) ;
|
||||||
|
b=s;
|
||||||
|
for ( ; (s < e) && !strchr(" \t\r\n",s[0]); s++) ;
|
||||||
|
if (s == b || i > size)
|
||||||
|
break;
|
||||||
|
a[i]= (uchar) strtoul(b,NULL,16);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fill_uint16(uint16 *a,uint size,const char *str, size_t len)
|
||||||
|
{
|
||||||
|
uint i= 0;
|
||||||
|
|
||||||
|
const char *s, *b, *e=str+len;
|
||||||
|
for (s=str ; s < e ; i++)
|
||||||
|
{
|
||||||
|
for ( ; (s < e) && strchr(" \t\r\n",s[0]); s++) ;
|
||||||
|
b=s;
|
||||||
|
for ( ; (s < e) && !strchr(" \t\r\n",s[0]); s++) ;
|
||||||
|
if (s == b || i > size)
|
||||||
|
break;
|
||||||
|
a[i]= (uint16) strtol(b,NULL,16);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int cs_enter(MY_XML_PARSER *st,const char *attr, size_t len)
|
||||||
|
{
|
||||||
|
struct my_cs_file_info *i= (struct my_cs_file_info *)st->user_data;
|
||||||
|
struct my_cs_file_section_st *s= cs_file_sec(attr,len);
|
||||||
|
|
||||||
|
if ( s && (s->state == _CS_CHARSET))
|
||||||
|
bzero(&i->cs,sizeof(i->cs));
|
||||||
|
|
||||||
|
if (s && (s->state == _CS_COLLATION))
|
||||||
|
i->tailoring_length= 0;
|
||||||
|
|
||||||
|
return MY_XML_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int cs_leave(MY_XML_PARSER *st,const char *attr, size_t len)
|
||||||
|
{
|
||||||
|
struct my_cs_file_info *i= (struct my_cs_file_info *)st->user_data;
|
||||||
|
struct my_cs_file_section_st *s= cs_file_sec(attr,len);
|
||||||
|
int state= s ? s->state : 0;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
switch(state){
|
||||||
|
case _CS_COLLATION:
|
||||||
|
rc= i->add_collation ? i->add_collation(&i->cs) : MY_XML_OK;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
rc=MY_XML_OK;
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int cs_value(MY_XML_PARSER *st,const char *attr, size_t len)
|
||||||
|
{
|
||||||
|
struct my_cs_file_info *i= (struct my_cs_file_info *)st->user_data;
|
||||||
|
struct my_cs_file_section_st *s;
|
||||||
|
int state= (int)((s=cs_file_sec(st->attr, strlen(st->attr))) ? s->state :
|
||||||
|
0);
|
||||||
|
|
||||||
|
switch (state) {
|
||||||
|
case _CS_ID:
|
||||||
|
i->cs.number= strtol(attr,(char**)NULL,10);
|
||||||
|
break;
|
||||||
|
case _CS_BINARY_ID:
|
||||||
|
i->cs.binary_number= strtol(attr,(char**)NULL,10);
|
||||||
|
break;
|
||||||
|
case _CS_PRIMARY_ID:
|
||||||
|
i->cs.primary_number= strtol(attr,(char**)NULL,10);
|
||||||
|
break;
|
||||||
|
case _CS_COLNAME:
|
||||||
|
i->cs.name=mstr(i->name,attr,len,MY_CS_NAME_SIZE-1);
|
||||||
|
break;
|
||||||
|
case _CS_CSNAME:
|
||||||
|
i->cs.csname=mstr(i->csname,attr,len,MY_CS_NAME_SIZE-1);
|
||||||
|
break;
|
||||||
|
case _CS_CSDESCRIPT:
|
||||||
|
i->cs.comment=mstr(i->comment,attr,len,MY_CS_CSDESCR_SIZE-1);
|
||||||
|
break;
|
||||||
|
case _CS_FLAG:
|
||||||
|
if (!strncmp("primary",attr,len))
|
||||||
|
i->cs.state|= MY_CS_PRIMARY;
|
||||||
|
else if (!strncmp("binary",attr,len))
|
||||||
|
i->cs.state|= MY_CS_BINSORT;
|
||||||
|
else if (!strncmp("compiled",attr,len))
|
||||||
|
i->cs.state|= MY_CS_COMPILED;
|
||||||
|
break;
|
||||||
|
case _CS_UPPERMAP:
|
||||||
|
fill_uchar(i->to_upper,MY_CS_TO_UPPER_TABLE_SIZE,attr,len);
|
||||||
|
i->cs.to_upper=i->to_upper;
|
||||||
|
break;
|
||||||
|
case _CS_LOWERMAP:
|
||||||
|
fill_uchar(i->to_lower,MY_CS_TO_LOWER_TABLE_SIZE,attr,len);
|
||||||
|
i->cs.to_lower=i->to_lower;
|
||||||
|
break;
|
||||||
|
case _CS_UNIMAP:
|
||||||
|
fill_uint16(i->tab_to_uni,MY_CS_TO_UNI_TABLE_SIZE,attr,len);
|
||||||
|
i->cs.tab_to_uni=i->tab_to_uni;
|
||||||
|
break;
|
||||||
|
case _CS_COLLMAP:
|
||||||
|
fill_uchar(i->sort_order,MY_CS_SORT_ORDER_TABLE_SIZE,attr,len);
|
||||||
|
i->cs.sort_order=i->sort_order;
|
||||||
|
break;
|
||||||
|
case _CS_CTYPEMAP:
|
||||||
|
fill_uchar(i->ctype,MY_CS_CTYPE_TABLE_SIZE,attr,len);
|
||||||
|
i->cs.ctype=i->ctype;
|
||||||
|
break;
|
||||||
|
case _CS_RESET:
|
||||||
|
case _CS_DIFF1:
|
||||||
|
case _CS_DIFF2:
|
||||||
|
case _CS_DIFF3:
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Convert collation description from
|
||||||
|
Locale Data Markup Language (LDML)
|
||||||
|
into ICU Collation Customization expression.
|
||||||
|
*/
|
||||||
|
char arg[16];
|
||||||
|
const char *cmd[]= {"&","<","<<","<<<"};
|
||||||
|
i->cs.tailoring= i->tailoring;
|
||||||
|
mstr(arg,attr,len,sizeof(arg)-1);
|
||||||
|
if (i->tailoring_length + 20 < sizeof(i->tailoring))
|
||||||
|
{
|
||||||
|
char *dst= i->tailoring_length + i->tailoring;
|
||||||
|
i->tailoring_length+= sprintf(dst," %s %s",cmd[state-_CS_RESET],arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return MY_XML_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
my_bool my_parse_charset_xml(const char *buf, size_t len,
|
||||||
|
int (*add_collation)(CHARSET_INFO *cs))
|
||||||
|
{
|
||||||
|
MY_XML_PARSER p;
|
||||||
|
struct my_cs_file_info i;
|
||||||
|
my_bool rc;
|
||||||
|
|
||||||
|
my_xml_parser_create(&p);
|
||||||
|
my_xml_set_enter_handler(&p,cs_enter);
|
||||||
|
my_xml_set_value_handler(&p,cs_value);
|
||||||
|
my_xml_set_leave_handler(&p,cs_leave);
|
||||||
|
i.add_collation= add_collation;
|
||||||
|
my_xml_set_user_data(&p,(void*)&i);
|
||||||
|
rc= (my_xml_parse(&p,buf,len) == MY_XML_OK) ? FALSE : TRUE;
|
||||||
|
my_xml_parser_free(&p);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Check repertoire: detect pure ascii strings
|
||||||
|
*/
|
||||||
|
uint
|
||||||
|
my_string_repertoire(CHARSET_INFO *cs, const char *str, ulong length)
|
||||||
|
{
|
||||||
|
const char *strend= str + length;
|
||||||
|
if (cs->mbminlen == 1)
|
||||||
|
{
|
||||||
|
for ( ; str < strend; str++)
|
||||||
|
{
|
||||||
|
if (((uchar) *str) > 0x7F)
|
||||||
|
return MY_REPERTOIRE_UNICODE30;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
my_wc_t wc;
|
||||||
|
int chlen;
|
||||||
|
for (;
|
||||||
|
(chlen= cs->cset->mb_wc(cs, &wc, (uchar*) str, (uchar*) strend)) > 0;
|
||||||
|
str+= chlen)
|
||||||
|
{
|
||||||
|
if (wc > 0x7F)
|
||||||
|
return MY_REPERTOIRE_UNICODE30;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return MY_REPERTOIRE_ASCII;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Returns repertoire for charset
|
||||||
|
*/
|
||||||
|
uint my_charset_repertoire(CHARSET_INFO *cs)
|
||||||
|
{
|
||||||
|
return cs->state & MY_CS_PUREASCII ?
|
||||||
|
MY_REPERTOIRE_ASCII : MY_REPERTOIRE_UNICODE30;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Detect whether a character set is ASCII compatible.
|
||||||
|
|
||||||
|
Returns TRUE for:
|
||||||
|
|
||||||
|
- all 8bit character sets whose Unicode mapping of 0x7B is '{'
|
||||||
|
(ignores swe7 which maps 0x7B to "LATIN LETTER A WITH DIAERESIS")
|
||||||
|
|
||||||
|
- all multi-byte character sets having mbminlen == 1
|
||||||
|
(ignores ucs2 whose mbminlen is 2)
|
||||||
|
|
||||||
|
TODO:
|
||||||
|
|
||||||
|
When merging to 5.2, this function should be changed
|
||||||
|
to check a new flag MY_CS_NONASCII,
|
||||||
|
|
||||||
|
return (cs->flag & MY_CS_NONASCII) ? 0 : 1;
|
||||||
|
|
||||||
|
This flag was previously added into 5.2 under terms
|
||||||
|
of WL#3759 "Optimize identifier conversion in client-server protocol"
|
||||||
|
especially to mark character sets not compatible with ASCII.
|
||||||
|
|
||||||
|
We won't backport this flag to 5.0 or 5.1.
|
||||||
|
This function is Ok for 5.0 and 5.1, because we're not going
|
||||||
|
to introduce new tricky character sets between 5.0 and 5.2.
|
||||||
|
*/
|
||||||
|
my_bool
|
||||||
|
my_charset_is_ascii_based(CHARSET_INFO *cs)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
(cs->mbmaxlen == 1 && cs->tab_to_uni && cs->tab_to_uni['{'] == '{') ||
|
||||||
|
(cs->mbminlen == 1 && cs->mbmaxlen > 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Detect if a character set is 8bit,
|
||||||
|
and it is pure ascii, i.e. doesn't have
|
||||||
|
characters outside U+0000..U+007F
|
||||||
|
This functions is shared between "conf_to_src"
|
||||||
|
and dynamic charsets loader in "mysqld".
|
||||||
|
*/
|
||||||
|
my_bool
|
||||||
|
my_charset_is_8bit_pure_ascii(CHARSET_INFO *cs)
|
||||||
|
{
|
||||||
|
size_t code;
|
||||||
|
if (!cs->tab_to_uni)
|
||||||
|
return 0;
|
||||||
|
for (code= 0; code < 256; code++)
|
||||||
|
{
|
||||||
|
if (cs->tab_to_uni[code] > 0x7F)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
2404
MySQL/dbug.c
Normal file
2404
MySQL/dbug.c
Normal file
File diff suppressed because it is too large
Load Diff
1147
MySQL/default.c
Normal file
1147
MySQL/default.c
Normal file
File diff suppressed because it is too large
Load Diff
252
MySQL/default_modify.c
Normal file
252
MySQL/default_modify.c
Normal file
@ -0,0 +1,252 @@
|
|||||||
|
/* Copyright (C) 2005 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
#include "my_global.h"
|
||||||
|
#include "mysys_priv.h"
|
||||||
|
#include "m_string.h"
|
||||||
|
#include <my_dir.h>
|
||||||
|
|
||||||
|
#define BUFF_SIZE 1024
|
||||||
|
#define RESERVE 1024 /* Extend buffer with this extent */
|
||||||
|
|
||||||
|
#ifdef __WIN__
|
||||||
|
#define NEWLINE "\r\n"
|
||||||
|
#define NEWLINE_LEN 2
|
||||||
|
#else
|
||||||
|
#define NEWLINE "\n"
|
||||||
|
#define NEWLINE_LEN 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static char *add_option(char *dst, const char *option_value,
|
||||||
|
const char *option, int remove_option);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Add/remove option to the option file section.
|
||||||
|
|
||||||
|
SYNOPSYS
|
||||||
|
modify_defaults_file()
|
||||||
|
file_location The location of configuration file to edit
|
||||||
|
option The name of the option to look for (can be NULL)
|
||||||
|
option value The value of the option we would like to set (can be NULL)
|
||||||
|
section_name The name of the section (must be NOT NULL)
|
||||||
|
remove_option This defines what we want to remove:
|
||||||
|
- MY_REMOVE_NONE -- nothing to remove;
|
||||||
|
- MY_REMOVE_OPTION -- remove the specified option;
|
||||||
|
- MY_REMOVE_SECTION -- remove the specified section;
|
||||||
|
IMPLEMENTATION
|
||||||
|
We open the option file first, then read the file line-by-line,
|
||||||
|
looking for the section we need. At the same time we put these lines
|
||||||
|
into a buffer. Then we look for the option within this section and
|
||||||
|
change/remove it. In the end we get a buffer with modified version of the
|
||||||
|
file. Then we write it to the file, truncate it if needed and close it.
|
||||||
|
Note that there is a small time gap, when the file is incomplete,
|
||||||
|
and this theoretically might introduce a problem.
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
0 - ok
|
||||||
|
1 - some error has occured. Probably due to the lack of resourses
|
||||||
|
2 - cannot open the file
|
||||||
|
*/
|
||||||
|
|
||||||
|
int modify_defaults_file(const char *file_location, const char *option,
|
||||||
|
const char *option_value,
|
||||||
|
const char *section_name, int remove_option)
|
||||||
|
{
|
||||||
|
FILE *cnf_file;
|
||||||
|
MY_STAT file_stat;
|
||||||
|
char linebuff[BUFF_SIZE], *src_ptr, *dst_ptr, *file_buffer;
|
||||||
|
size_t opt_len= 0, optval_len= 0, sect_len, new_opt_len, reserve_extended;
|
||||||
|
uint nr_newlines= 0, buffer_size;
|
||||||
|
my_bool in_section= FALSE, opt_applied= 0;
|
||||||
|
int reserve_occupied= 0;
|
||||||
|
DBUG_ENTER("modify_defaults_file");
|
||||||
|
|
||||||
|
if (!(cnf_file= my_fopen(file_location, O_RDWR | O_BINARY, MYF(0))))
|
||||||
|
DBUG_RETURN(2);
|
||||||
|
|
||||||
|
/* my_fstat doesn't use the flag parameter */
|
||||||
|
if (my_fstat(fileno(cnf_file), &file_stat, MYF(0)))
|
||||||
|
goto malloc_err;
|
||||||
|
|
||||||
|
if (option && option_value)
|
||||||
|
{
|
||||||
|
opt_len= strlen(option);
|
||||||
|
optval_len= strlen(option_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
new_opt_len= opt_len + 1 + optval_len + NEWLINE_LEN;
|
||||||
|
|
||||||
|
/* calculate the size of the buffer we need */
|
||||||
|
reserve_extended= (opt_len +
|
||||||
|
1 + /* For '=' char */
|
||||||
|
optval_len + /* Option value len */
|
||||||
|
NEWLINE_LEN + /* Space for newline */
|
||||||
|
RESERVE); /* Some additional space */
|
||||||
|
|
||||||
|
buffer_size= (file_stat.st_size +
|
||||||
|
1); /* The ending zero */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Reserve space to read the contents of the file and some more
|
||||||
|
for the option we want to add.
|
||||||
|
*/
|
||||||
|
if (!(file_buffer= (char*) my_malloc(buffer_size + reserve_extended,
|
||||||
|
MYF(MY_WME))))
|
||||||
|
goto malloc_err;
|
||||||
|
|
||||||
|
sect_len= strlen(section_name);
|
||||||
|
|
||||||
|
for (dst_ptr= file_buffer; fgets(linebuff, BUFF_SIZE, cnf_file); )
|
||||||
|
{
|
||||||
|
/* Skip over whitespaces */
|
||||||
|
for (src_ptr= linebuff; my_isspace(&my_charset_latin1, *src_ptr);
|
||||||
|
src_ptr++)
|
||||||
|
{}
|
||||||
|
|
||||||
|
if (!*src_ptr) /* Empty line */
|
||||||
|
{
|
||||||
|
nr_newlines++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* correct the option (if requested) */
|
||||||
|
if (option && in_section && !strncmp(src_ptr, option, opt_len) &&
|
||||||
|
(*(src_ptr + opt_len) == '=' ||
|
||||||
|
my_isspace(&my_charset_latin1, *(src_ptr + opt_len)) ||
|
||||||
|
*(src_ptr + opt_len) == '\0'))
|
||||||
|
{
|
||||||
|
char *old_src_ptr= src_ptr;
|
||||||
|
src_ptr= strend(src_ptr+ opt_len); /* Find the end of the line */
|
||||||
|
|
||||||
|
/* could be negative */
|
||||||
|
reserve_occupied+= (int) new_opt_len - (int) (src_ptr - old_src_ptr);
|
||||||
|
if (reserve_occupied >= (int) reserve_extended)
|
||||||
|
{
|
||||||
|
reserve_extended= (uint) reserve_occupied + RESERVE;
|
||||||
|
if (!(file_buffer= (char*) my_realloc(file_buffer, buffer_size +
|
||||||
|
reserve_extended,
|
||||||
|
MYF(MY_WME|MY_FREE_ON_ERROR))))
|
||||||
|
goto malloc_err;
|
||||||
|
}
|
||||||
|
opt_applied= 1;
|
||||||
|
dst_ptr= add_option(dst_ptr, option_value, option, remove_option);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
If we are going to the new group and have an option to apply, do
|
||||||
|
it now. If we are removing a single option or the whole section
|
||||||
|
this will only trigger opt_applied flag.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (in_section && !opt_applied && *src_ptr == '[')
|
||||||
|
{
|
||||||
|
dst_ptr= add_option(dst_ptr, option_value, option, remove_option);
|
||||||
|
opt_applied= 1; /* set the flag to do write() later */
|
||||||
|
reserve_occupied= new_opt_len+ opt_len + 1 + NEWLINE_LEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; nr_newlines; nr_newlines--)
|
||||||
|
dst_ptr= strmov(dst_ptr, NEWLINE);
|
||||||
|
|
||||||
|
/* Skip the section if MY_REMOVE_SECTION was given */
|
||||||
|
if (!in_section || remove_option != MY_REMOVE_SECTION)
|
||||||
|
dst_ptr= strmov(dst_ptr, linebuff);
|
||||||
|
}
|
||||||
|
/* Look for a section */
|
||||||
|
if (*src_ptr == '[')
|
||||||
|
{
|
||||||
|
/* Copy the line to the buffer */
|
||||||
|
if (!strncmp(++src_ptr, section_name, sect_len))
|
||||||
|
{
|
||||||
|
src_ptr+= sect_len;
|
||||||
|
/* Skip over whitespaces. They are allowed after section name */
|
||||||
|
for (; my_isspace(&my_charset_latin1, *src_ptr); src_ptr++)
|
||||||
|
{}
|
||||||
|
|
||||||
|
if (*src_ptr != ']')
|
||||||
|
{
|
||||||
|
in_section= FALSE;
|
||||||
|
continue; /* Missing closing parenthesis. Assume this was no group */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remove_option == MY_REMOVE_SECTION)
|
||||||
|
dst_ptr= dst_ptr - strlen(linebuff);
|
||||||
|
|
||||||
|
in_section= TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
in_section= FALSE; /* mark that this section is of no interest to us */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
File ended. Apply an option or set opt_applied flag (in case of
|
||||||
|
MY_REMOVE_SECTION) so that the changes are saved. Do not do anything
|
||||||
|
if we are removing non-existent option.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!opt_applied && in_section && (remove_option != MY_REMOVE_OPTION))
|
||||||
|
{
|
||||||
|
/* New option still remains to apply at the end */
|
||||||
|
if (!remove_option && *(dst_ptr - 1) != '\n')
|
||||||
|
dst_ptr= strmov(dst_ptr, NEWLINE);
|
||||||
|
dst_ptr= add_option(dst_ptr, option_value, option, remove_option);
|
||||||
|
opt_applied= 1;
|
||||||
|
}
|
||||||
|
for (; nr_newlines; nr_newlines--)
|
||||||
|
dst_ptr= strmov(dst_ptr, NEWLINE);
|
||||||
|
|
||||||
|
if (opt_applied)
|
||||||
|
{
|
||||||
|
/* Don't write the file if there are no changes to be made */
|
||||||
|
if (my_chsize(fileno(cnf_file), (my_off_t) (dst_ptr - file_buffer), 0,
|
||||||
|
MYF(MY_WME)) ||
|
||||||
|
my_fseek(cnf_file, 0, MY_SEEK_SET, MYF(0)) ||
|
||||||
|
my_fwrite(cnf_file, (uchar*) file_buffer, (size_t) (dst_ptr - file_buffer),
|
||||||
|
MYF(MY_NABP)))
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
if (my_fclose(cnf_file, MYF(MY_WME)))
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
|
||||||
|
my_free(file_buffer, MYF(0));
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
|
||||||
|
err:
|
||||||
|
my_free(file_buffer, MYF(0));
|
||||||
|
malloc_err:
|
||||||
|
my_fclose(cnf_file, MYF(0));
|
||||||
|
DBUG_RETURN(1); /* out of resources */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static char *add_option(char *dst, const char *option_value,
|
||||||
|
const char *option, int remove_option)
|
||||||
|
{
|
||||||
|
if (!remove_option)
|
||||||
|
{
|
||||||
|
dst= strmov(dst, option);
|
||||||
|
if (*option_value)
|
||||||
|
{
|
||||||
|
*dst++= '=';
|
||||||
|
dst= strmov(dst, option_value);
|
||||||
|
}
|
||||||
|
/* add a newline */
|
||||||
|
dst= strmov(dst, NEWLINE);
|
||||||
|
}
|
||||||
|
return dst;
|
||||||
|
}
|
125
MySQL/dll.c
Normal file
125
MySQL/dll.c
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
/* Copyright (C) 2000-2004 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation.
|
||||||
|
|
||||||
|
There are special exceptions to the terms and conditions of the GPL as it
|
||||||
|
is applied to this software. View the full text of the exception in file
|
||||||
|
EXCEPTIONS-CLIENT in the directory of this software distribution.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Handling initialization of the dll library
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <my_global.h>
|
||||||
|
#include <my_sys.h>
|
||||||
|
#include <my_pthread.h>
|
||||||
|
|
||||||
|
static my_bool libmysql_inited=0;
|
||||||
|
|
||||||
|
void libmysql_init(void)
|
||||||
|
{
|
||||||
|
if (libmysql_inited)
|
||||||
|
return;
|
||||||
|
libmysql_inited=1;
|
||||||
|
my_init();
|
||||||
|
{
|
||||||
|
DBUG_ENTER("libmysql_init");
|
||||||
|
#ifdef LOG_ALL
|
||||||
|
DBUG_PUSH("d:t:S:O,c::\\tmp\\libmysql.log");
|
||||||
|
#else
|
||||||
|
if (getenv("LIBMYSQL_LOG") != NULL)
|
||||||
|
DBUG_PUSH(getenv("LIBMYSQL_LOG"));
|
||||||
|
#endif
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __WIN__
|
||||||
|
|
||||||
|
static int inited=0,threads=0;
|
||||||
|
HINSTANCE NEAR s_hModule; /* Saved module handle */
|
||||||
|
DWORD main_thread;
|
||||||
|
|
||||||
|
BOOL APIENTRY LibMain(HANDLE hInst,DWORD ul_reason_being_called,
|
||||||
|
LPVOID lpReserved)
|
||||||
|
{
|
||||||
|
switch (ul_reason_being_called) {
|
||||||
|
case DLL_PROCESS_ATTACH: /* case of libentry call in win 3.x */
|
||||||
|
if (!inited++)
|
||||||
|
{
|
||||||
|
s_hModule=hInst;
|
||||||
|
libmysql_init();
|
||||||
|
main_thread=GetCurrentThreadId();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DLL_THREAD_ATTACH:
|
||||||
|
threads++;
|
||||||
|
my_thread_init();
|
||||||
|
break;
|
||||||
|
case DLL_PROCESS_DETACH: /* case of wep call in win 3.x */
|
||||||
|
if (!--inited) /* Safety */
|
||||||
|
{
|
||||||
|
/* my_thread_init() */ /* This may give extra safety */
|
||||||
|
my_end(0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DLL_THREAD_DETACH:
|
||||||
|
/* Main thread will free by my_end() */
|
||||||
|
threads--;
|
||||||
|
if (main_thread != GetCurrentThreadId())
|
||||||
|
my_thread_end();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
} /* switch */
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
UNREFERENCED_PARAMETER(lpReserved);
|
||||||
|
} /* LibMain */
|
||||||
|
|
||||||
|
|
||||||
|
static BOOL do_libmain;
|
||||||
|
int __stdcall DllMain(HANDLE hInst,DWORD ul_reason_being_called,LPVOID lpReserved)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Unless environment variable LIBMYSQL_DLLINIT is set, do nothing.
|
||||||
|
The environment variable is checked once, during the first call to DllMain()
|
||||||
|
(in DLL_PROCESS_ATTACH hook).
|
||||||
|
*/
|
||||||
|
if (ul_reason_being_called == DLL_PROCESS_ATTACH)
|
||||||
|
do_libmain = (getenv("LIBMYSQL_DLLINIT") != NULL);
|
||||||
|
if (do_libmain)
|
||||||
|
return LibMain(hInst,ul_reason_being_called,lpReserved);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(WINDOWS)
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
** This routine is called by LIBSTART.ASM at module load time. All it
|
||||||
|
** does in this sample is remember the DLL module handle. The module
|
||||||
|
** handle is needed if you want to do things like load stuff from the
|
||||||
|
** resource file (for instance string resources).
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int _export FAR PASCAL libmain(HANDLE hModule,short cbHeapSize,
|
||||||
|
UCHAR FAR *lszCmdLine)
|
||||||
|
{
|
||||||
|
s_hModule = hModule;
|
||||||
|
libmysql_init();
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
252
MySQL/errmsg.c
Normal file
252
MySQL/errmsg.c
Normal file
@ -0,0 +1,252 @@
|
|||||||
|
/* Copyright (C) 2000-2004 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation.
|
||||||
|
|
||||||
|
There are special exceptions to the terms and conditions of the GPL as it
|
||||||
|
is applied to this software. View the full text of the exception in file
|
||||||
|
EXCEPTIONS-CLIENT in the directory of this software distribution.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
/* Error messages for MySQL clients */
|
||||||
|
/* (Error messages for the daemon are in share/language/errmsg.sys) */
|
||||||
|
|
||||||
|
#include <my_global.h>
|
||||||
|
#include <my_sys.h>
|
||||||
|
#include "errmsg.h"
|
||||||
|
|
||||||
|
#ifdef GERMAN
|
||||||
|
const char *client_errors[]=
|
||||||
|
{
|
||||||
|
"Unbekannter MySQL Fehler",
|
||||||
|
"Kann UNIX-Socket nicht anlegen (%d)",
|
||||||
|
"Keine Verbindung zu lokalem MySQL Server, socket: '%-.100s' (%d)",
|
||||||
|
"Keine Verbindung zu MySQL Server auf %-.100s (%d)",
|
||||||
|
"Kann TCP/IP-Socket nicht anlegen (%d)",
|
||||||
|
"Unbekannter MySQL Server Host (%-.100s) (%d)",
|
||||||
|
"MySQL Server nicht vorhanden",
|
||||||
|
"Protokolle ungleich; Server Version = %d, Client Version = %d",
|
||||||
|
"MySQL client ran out of memory",
|
||||||
|
"Wrong host info",
|
||||||
|
"Localhost via UNIX socket",
|
||||||
|
"%-.100s via TCP/IP",
|
||||||
|
"Error in server handshake",
|
||||||
|
"Lost connection to MySQL server during query",
|
||||||
|
"Commands out of sync; you can't run this command now",
|
||||||
|
"Verbindung ueber Named Pipe: %-.32s",
|
||||||
|
"Kann nicht auf Named Pipe warten. Host: %-.64s pipe: %-.32s (%lu)",
|
||||||
|
"Kann Named Pipe nicht oeffnen. Host: %-.64s pipe: %-.32s (%lu)",
|
||||||
|
"Kann den Status der Named Pipe nicht setzen. Host: %-.64s pipe: %-.32s (%lu)",
|
||||||
|
"Can't initialize character set %-.32s (path: %-.100s)",
|
||||||
|
"Got packet bigger than 'max_allowed_packet' bytes",
|
||||||
|
"Embedded server",
|
||||||
|
"Error on SHOW SLAVE STATUS:",
|
||||||
|
"Error on SHOW SLAVE HOSTS:",
|
||||||
|
"Error connecting to slave:",
|
||||||
|
"Error connecting to master:",
|
||||||
|
"SSL connection error",
|
||||||
|
"Malformed packet",
|
||||||
|
"This client library is licensed only for use with MySQL servers having '%s' license",
|
||||||
|
"Invalid use of null pointer",
|
||||||
|
"Statement not prepared",
|
||||||
|
"No data supplied for parameters in prepared statement",
|
||||||
|
"Data truncated",
|
||||||
|
"No parameters exist in the statement",
|
||||||
|
"Invalid parameter number",
|
||||||
|
"Can't send long data for non-string/non-binary data types (parameter: %d)",
|
||||||
|
"Using unsupported buffer type: %d (parameter: %d)",
|
||||||
|
"Shared memory: %-.100s",
|
||||||
|
"Can't open shared memory; client could not create request event (%lu)",
|
||||||
|
"Can't open shared memory; no answer event received from server (%lu)",
|
||||||
|
"Can't open shared memory; server could not allocate file mapping (%lu)",
|
||||||
|
"Can't open shared memory; server could not get pointer to file mapping (%lu)",
|
||||||
|
"Can't open shared memory; client could not allocate file mapping (%lu)",
|
||||||
|
"Can't open shared memory; client could not get pointer to file mapping (%lu)",
|
||||||
|
"Can't open shared memory; client could not create %s event (%lu)",
|
||||||
|
"Can't open shared memory; no answer from server (%lu)",
|
||||||
|
"Can't open shared memory; cannot send request event to server (%lu)",
|
||||||
|
"Wrong or unknown protocol",
|
||||||
|
"Invalid connection handle",
|
||||||
|
"Connection using old (pre-4.1.1) authentication protocol refused (client option 'secure_auth' enabled)",
|
||||||
|
"Row retrieval was canceled by mysql_stmt_close() call",
|
||||||
|
"Attempt to read column without prior row fetch",
|
||||||
|
"Prepared statement contains no metadata",
|
||||||
|
"Attempt to read a row while there is no result set associated with the statement",
|
||||||
|
"This feature is not implemented yet",
|
||||||
|
"Lost connection to MySQL server at '%s', system error: %d",
|
||||||
|
"Statement closed indirectly because of a preceeding %s() call",
|
||||||
|
"The number of columns in the result set differs from the number of bound buffers. You must reset the statement, rebind the result set columns, and execute the statement again",
|
||||||
|
""
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Start of code added by Roberto M. Serqueira - martinsc@uol.com.br - 05.24.2001 */
|
||||||
|
|
||||||
|
#elif defined PORTUGUESE
|
||||||
|
const char *client_errors[]=
|
||||||
|
{
|
||||||
|
"Erro desconhecido do MySQL",
|
||||||
|
"Não pode criar 'UNIX socket' (%d)",
|
||||||
|
"Não pode se conectar ao servidor MySQL local através do 'socket' '%-.100s' (%d)",
|
||||||
|
"Não pode se conectar ao servidor MySQL em '%-.100s' (%d)",
|
||||||
|
"Não pode criar 'socket TCP/IP' (%d)",
|
||||||
|
"'Host' servidor MySQL '%-.100s' (%d) desconhecido",
|
||||||
|
"Servidor MySQL desapareceu",
|
||||||
|
"Incompatibilidade de protocolos; versão do servidor = %d, versão do cliente = %d",
|
||||||
|
"Cliente do MySQL com falta de memória",
|
||||||
|
"Informação inválida de 'host'",
|
||||||
|
"Localhost via 'UNIX socket'",
|
||||||
|
"%-.100s via 'TCP/IP'",
|
||||||
|
"Erro na negociação de acesso ao servidor",
|
||||||
|
"Conexão perdida com servidor MySQL durante 'query'",
|
||||||
|
"Comandos fora de sincronismo; você não pode executar este comando agora",
|
||||||
|
"Named pipe: %-.32s",
|
||||||
|
"Não pode esperar pelo 'named pipe' para o 'host' %-.64s - 'pipe' %-.32s (%lu)",
|
||||||
|
"Não pode abrir 'named pipe' para o 'host' %-.64s - 'pipe' %-.32s (%lu)",
|
||||||
|
"Não pode estabelecer o estado do 'named pipe' para o 'host' %-.64s - 'pipe' %-.32s (%lu)",
|
||||||
|
"Não pode inicializar conjunto de caracteres %-.32s (caminho %-.100s)",
|
||||||
|
"Obteve pacote maior do que 'max_allowed_packet' bytes",
|
||||||
|
"Embedded server"
|
||||||
|
"Error on SHOW SLAVE STATUS:",
|
||||||
|
"Error on SHOW SLAVE HOSTS:",
|
||||||
|
"Error connecting to slave:",
|
||||||
|
"Error connecting to master:",
|
||||||
|
"SSL connection error",
|
||||||
|
"Malformed packet",
|
||||||
|
"This client library is licensed only for use with MySQL servers having '%s' license",
|
||||||
|
"Invalid use of null pointer",
|
||||||
|
"Statement not prepared",
|
||||||
|
"No data supplied for parameters in prepared statement",
|
||||||
|
"Data truncated",
|
||||||
|
"No parameters exist in the statement",
|
||||||
|
"Invalid parameter number",
|
||||||
|
"Can't send long data for non-string/non-binary data types (parameter: %d)",
|
||||||
|
"Using unsupported buffer type: %d (parameter: %d)",
|
||||||
|
"Shared memory: %-.100s",
|
||||||
|
"Can't open shared memory; client could not create request event (%lu)",
|
||||||
|
"Can't open shared memory; no answer event received from server (%lu)",
|
||||||
|
"Can't open shared memory; server could not allocate file mapping (%lu)",
|
||||||
|
"Can't open shared memory; server could not get pointer to file mapping (%lu)",
|
||||||
|
"Can't open shared memory; client could not allocate file mapping (%lu)",
|
||||||
|
"Can't open shared memory; client could not get pointer to file mapping (%lu)",
|
||||||
|
"Can't open shared memory; client could not create %s event (%lu)",
|
||||||
|
"Can't open shared memory; no answer from server (%lu)",
|
||||||
|
"Can't open shared memory; cannot send request event to server (%lu)",
|
||||||
|
"Wrong or unknown protocol",
|
||||||
|
"Invalid connection handle",
|
||||||
|
"Connection using old (pre-4.1.1) authentication protocol refused (client option 'secure_auth' enabled)",
|
||||||
|
"Row retrieval was canceled by mysql_stmt_close() call",
|
||||||
|
"Attempt to read column without prior row fetch",
|
||||||
|
"Prepared statement contains no metadata",
|
||||||
|
"Attempt to read a row while there is no result set associated with the statement",
|
||||||
|
"This feature is not implemented yet",
|
||||||
|
"Lost connection to MySQL server at '%s', system error: %d",
|
||||||
|
"Statement closed indirectly because of a preceeding %s() call",
|
||||||
|
"The number of columns in the result set differs from the number of bound buffers. You must reset the statement, rebind the result set columns, and execute the statement again",
|
||||||
|
""
|
||||||
|
};
|
||||||
|
|
||||||
|
#else /* ENGLISH */
|
||||||
|
const char *client_errors[]=
|
||||||
|
{
|
||||||
|
"Unknown MySQL error",
|
||||||
|
"Can't create UNIX socket (%d)",
|
||||||
|
"Can't connect to local MySQL server through socket '%-.100s' (%d)",
|
||||||
|
"Can't connect to MySQL server on '%-.100s' (%d)",
|
||||||
|
"Can't create TCP/IP socket (%d)",
|
||||||
|
"Unknown MySQL server host '%-.100s' (%d)",
|
||||||
|
"MySQL server has gone away",
|
||||||
|
"Protocol mismatch; server version = %d, client version = %d",
|
||||||
|
"MySQL client ran out of memory",
|
||||||
|
"Wrong host info",
|
||||||
|
"Localhost via UNIX socket",
|
||||||
|
"%-.100s via TCP/IP",
|
||||||
|
"Error in server handshake",
|
||||||
|
"Lost connection to MySQL server during query",
|
||||||
|
"Commands out of sync; you can't run this command now",
|
||||||
|
"Named pipe: %-.32s",
|
||||||
|
"Can't wait for named pipe to host: %-.64s pipe: %-.32s (%lu)",
|
||||||
|
"Can't open named pipe to host: %-.64s pipe: %-.32s (%lu)",
|
||||||
|
"Can't set state of named pipe to host: %-.64s pipe: %-.32s (%lu)",
|
||||||
|
"Can't initialize character set %-.32s (path: %-.100s)",
|
||||||
|
"Got packet bigger than 'max_allowed_packet' bytes",
|
||||||
|
"Embedded server",
|
||||||
|
"Error on SHOW SLAVE STATUS:",
|
||||||
|
"Error on SHOW SLAVE HOSTS:",
|
||||||
|
"Error connecting to slave:",
|
||||||
|
"Error connecting to master:",
|
||||||
|
"SSL connection error",
|
||||||
|
"Malformed packet",
|
||||||
|
"This client library is licensed only for use with MySQL servers having '%s' license",
|
||||||
|
"Invalid use of null pointer",
|
||||||
|
"Statement not prepared",
|
||||||
|
"No data supplied for parameters in prepared statement",
|
||||||
|
"Data truncated",
|
||||||
|
"No parameters exist in the statement",
|
||||||
|
"Invalid parameter number",
|
||||||
|
"Can't send long data for non-string/non-binary data types (parameter: %d)",
|
||||||
|
"Using unsupported buffer type: %d (parameter: %d)",
|
||||||
|
"Shared memory: %-.100s",
|
||||||
|
"Can't open shared memory; client could not create request event (%lu)",
|
||||||
|
"Can't open shared memory; no answer event received from server (%lu)",
|
||||||
|
"Can't open shared memory; server could not allocate file mapping (%lu)",
|
||||||
|
"Can't open shared memory; server could not get pointer to file mapping (%lu)",
|
||||||
|
"Can't open shared memory; client could not allocate file mapping (%lu)",
|
||||||
|
"Can't open shared memory; client could not get pointer to file mapping (%lu)",
|
||||||
|
"Can't open shared memory; client could not create %s event (%lu)",
|
||||||
|
"Can't open shared memory; no answer from server (%lu)",
|
||||||
|
"Can't open shared memory; cannot send request event to server (%lu)",
|
||||||
|
"Wrong or unknown protocol",
|
||||||
|
"Invalid connection handle",
|
||||||
|
"Connection using old (pre-4.1.1) authentication protocol refused (client option 'secure_auth' enabled)",
|
||||||
|
"Row retrieval was canceled by mysql_stmt_close() call",
|
||||||
|
"Attempt to read column without prior row fetch",
|
||||||
|
"Prepared statement contains no metadata",
|
||||||
|
"Attempt to read a row while there is no result set associated with the statement",
|
||||||
|
"This feature is not implemented yet",
|
||||||
|
"Lost connection to MySQL server at '%s', system error: %d",
|
||||||
|
"Statement closed indirectly because of a preceeding %s() call",
|
||||||
|
"The number of columns in the result set differs from the number of bound buffers. You must reset the statement, rebind the result set columns, and execute the statement again",
|
||||||
|
""
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Register client error messages for use with my_error().
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
init_client_errs()
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
void
|
||||||
|
*/
|
||||||
|
|
||||||
|
void init_client_errs(void)
|
||||||
|
{
|
||||||
|
(void) my_error_register(client_errors, CR_ERROR_FIRST, CR_ERROR_LAST);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Unregister client error messages.
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
finish_client_errs()
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
void
|
||||||
|
*/
|
||||||
|
|
||||||
|
void finish_client_errs(void)
|
||||||
|
{
|
||||||
|
(void) my_error_unregister(CR_ERROR_FIRST, CR_ERROR_LAST);
|
||||||
|
}
|
102
MySQL/errmsg.h
Normal file
102
MySQL/errmsg.h
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
/* Copyright (C) 2000 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
/* Error messages for MySQL clients */
|
||||||
|
/* (Error messages for the daemon are in sql/share/errmsg.txt) */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
void init_client_errs(void);
|
||||||
|
void finish_client_errs(void);
|
||||||
|
extern const char *client_errors[]; /* Error messages */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CR_MIN_ERROR 2000 /* For easier client code */
|
||||||
|
#define CR_MAX_ERROR 2999
|
||||||
|
#if !defined(ER)
|
||||||
|
#define ER(X) client_errors[(X)-CR_MIN_ERROR]
|
||||||
|
#endif
|
||||||
|
#define CLIENT_ERRMAP 2 /* Errormap used by my_error() */
|
||||||
|
|
||||||
|
/* Do not add error numbers before CR_ERROR_FIRST. */
|
||||||
|
/* If necessary to add lower numbers, change CR_ERROR_FIRST accordingly. */
|
||||||
|
#define CR_ERROR_FIRST 2000 /*Copy first error nr.*/
|
||||||
|
#define CR_UNKNOWN_ERROR 2000
|
||||||
|
#define CR_SOCKET_CREATE_ERROR 2001
|
||||||
|
#define CR_CONNECTION_ERROR 2002
|
||||||
|
#define CR_CONN_HOST_ERROR 2003
|
||||||
|
#define CR_IPSOCK_ERROR 2004
|
||||||
|
#define CR_UNKNOWN_HOST 2005
|
||||||
|
#define CR_SERVER_GONE_ERROR 2006
|
||||||
|
#define CR_VERSION_ERROR 2007
|
||||||
|
#define CR_OUT_OF_MEMORY 2008
|
||||||
|
#define CR_WRONG_HOST_INFO 2009
|
||||||
|
#define CR_LOCALHOST_CONNECTION 2010
|
||||||
|
#define CR_TCP_CONNECTION 2011
|
||||||
|
#define CR_SERVER_HANDSHAKE_ERR 2012
|
||||||
|
#define CR_SERVER_LOST 2013
|
||||||
|
#define CR_COMMANDS_OUT_OF_SYNC 2014
|
||||||
|
#define CR_NAMEDPIPE_CONNECTION 2015
|
||||||
|
#define CR_NAMEDPIPEWAIT_ERROR 2016
|
||||||
|
#define CR_NAMEDPIPEOPEN_ERROR 2017
|
||||||
|
#define CR_NAMEDPIPESETSTATE_ERROR 2018
|
||||||
|
#define CR_CANT_READ_CHARSET 2019
|
||||||
|
#define CR_NET_PACKET_TOO_LARGE 2020
|
||||||
|
#define CR_EMBEDDED_CONNECTION 2021
|
||||||
|
#define CR_PROBE_SLAVE_STATUS 2022
|
||||||
|
#define CR_PROBE_SLAVE_HOSTS 2023
|
||||||
|
#define CR_PROBE_SLAVE_CONNECT 2024
|
||||||
|
#define CR_PROBE_MASTER_CONNECT 2025
|
||||||
|
#define CR_SSL_CONNECTION_ERROR 2026
|
||||||
|
#define CR_MALFORMED_PACKET 2027
|
||||||
|
#define CR_WRONG_LICENSE 2028
|
||||||
|
|
||||||
|
/* new 4.1 error codes */
|
||||||
|
#define CR_NULL_POINTER 2029
|
||||||
|
#define CR_NO_PREPARE_STMT 2030
|
||||||
|
#define CR_PARAMS_NOT_BOUND 2031
|
||||||
|
#define CR_DATA_TRUNCATED 2032
|
||||||
|
#define CR_NO_PARAMETERS_EXISTS 2033
|
||||||
|
#define CR_INVALID_PARAMETER_NO 2034
|
||||||
|
#define CR_INVALID_BUFFER_USE 2035
|
||||||
|
#define CR_UNSUPPORTED_PARAM_TYPE 2036
|
||||||
|
|
||||||
|
#define CR_SHARED_MEMORY_CONNECTION 2037
|
||||||
|
#define CR_SHARED_MEMORY_CONNECT_REQUEST_ERROR 2038
|
||||||
|
#define CR_SHARED_MEMORY_CONNECT_ANSWER_ERROR 2039
|
||||||
|
#define CR_SHARED_MEMORY_CONNECT_FILE_MAP_ERROR 2040
|
||||||
|
#define CR_SHARED_MEMORY_CONNECT_MAP_ERROR 2041
|
||||||
|
#define CR_SHARED_MEMORY_FILE_MAP_ERROR 2042
|
||||||
|
#define CR_SHARED_MEMORY_MAP_ERROR 2043
|
||||||
|
#define CR_SHARED_MEMORY_EVENT_ERROR 2044
|
||||||
|
#define CR_SHARED_MEMORY_CONNECT_ABANDONED_ERROR 2045
|
||||||
|
#define CR_SHARED_MEMORY_CONNECT_SET_ERROR 2046
|
||||||
|
#define CR_CONN_UNKNOW_PROTOCOL 2047
|
||||||
|
#define CR_INVALID_CONN_HANDLE 2048
|
||||||
|
#define CR_SECURE_AUTH 2049
|
||||||
|
#define CR_FETCH_CANCELED 2050
|
||||||
|
#define CR_NO_DATA 2051
|
||||||
|
#define CR_NO_STMT_METADATA 2052
|
||||||
|
#define CR_NO_RESULT_SET 2053
|
||||||
|
#define CR_NOT_IMPLEMENTED 2054
|
||||||
|
#define CR_SERVER_LOST_EXTENDED 2055
|
||||||
|
#define CR_STMT_CLOSED 2056
|
||||||
|
#define CR_NEW_STMT_METADATA 2057
|
||||||
|
#define CR_ERROR_LAST /*Copy last error nr:*/ 2057
|
||||||
|
/* Add error numbers before CR_ERROR_LAST and change it accordingly. */
|
||||||
|
|
108
MySQL/errors.c
Normal file
108
MySQL/errors.c
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
/* Copyright (C) 2000 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
#include "mysys_priv.h"
|
||||||
|
#include "mysys_err.h"
|
||||||
|
|
||||||
|
#ifndef SHARED_LIBRARY
|
||||||
|
|
||||||
|
const char * NEAR globerrs[GLOBERRS]=
|
||||||
|
{
|
||||||
|
"Can't create/write to file '%s' (Errcode: %d)",
|
||||||
|
"Error reading file '%s' (Errcode: %d)",
|
||||||
|
"Error writing file '%s' (Errcode: %d)",
|
||||||
|
"Error on close of '%s' (Errcode: %d)",
|
||||||
|
"Out of memory (Needed %u bytes)",
|
||||||
|
"Error on delete of '%s' (Errcode: %d)",
|
||||||
|
"Error on rename of '%s' to '%s' (Errcode: %d)",
|
||||||
|
"",
|
||||||
|
"Unexpected eof found when reading file '%s' (Errcode: %d)",
|
||||||
|
"Can't lock file (Errcode: %d)",
|
||||||
|
"Can't unlock file (Errcode: %d)",
|
||||||
|
"Can't read dir of '%s' (Errcode: %d)",
|
||||||
|
"Can't get stat of '%s' (Errcode: %d)",
|
||||||
|
"Can't change size of file (Errcode: %d)",
|
||||||
|
"Can't open stream from handle (Errcode: %d)",
|
||||||
|
"Can't get working dirctory (Errcode: %d)",
|
||||||
|
"Can't change dir to '%s' (Errcode: %d)",
|
||||||
|
"Warning: '%s' had %d links",
|
||||||
|
"Warning: %d files and %d streams is left open\n",
|
||||||
|
"Disk is full writing '%s' (Errcode: %d). Waiting for someone to free space... (Expect up to %d secs delay for server to continue after freeing disk space)",
|
||||||
|
"Can't create directory '%s' (Errcode: %d)",
|
||||||
|
"Character set '%s' is not a compiled character set and is not specified in the '%s' file",
|
||||||
|
"Out of resources when opening file '%s' (Errcode: %d)",
|
||||||
|
"Can't read value for symlink '%s' (Error %d)",
|
||||||
|
"Can't create symlink '%s' pointing at '%s' (Error %d)",
|
||||||
|
"Error on realpath() on '%s' (Error %d)",
|
||||||
|
"Can't sync file '%s' to disk (Errcode: %d)",
|
||||||
|
"Collation '%s' is not a compiled collation and is not specified in the '%s' file",
|
||||||
|
"File '%s' not found (Errcode: %d)",
|
||||||
|
"File '%s' (fileno: %d) was not closed"
|
||||||
|
};
|
||||||
|
|
||||||
|
void init_glob_errs(void)
|
||||||
|
{
|
||||||
|
/* This is now done statically. */
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
void init_glob_errs()
|
||||||
|
{
|
||||||
|
EE(EE_CANTCREATEFILE) = "Can't create/write to file '%s' (Errcode: %d)";
|
||||||
|
EE(EE_READ) = "Error reading file '%s' (Errcode: %d)";
|
||||||
|
EE(EE_WRITE) = "Error writing file '%s' (Errcode: %d)";
|
||||||
|
EE(EE_BADCLOSE) = "Error on close of '%'s (Errcode: %d)";
|
||||||
|
EE(EE_OUTOFMEMORY) = "Out of memory (Needed %u bytes)";
|
||||||
|
EE(EE_DELETE) = "Error on delete of '%s' (Errcode: %d)";
|
||||||
|
EE(EE_LINK) = "Error on rename of '%s' to '%s' (Errcode: %d)";
|
||||||
|
EE(EE_EOFERR) = "Unexpected eof found when reading file '%s' (Errcode: %d)";
|
||||||
|
EE(EE_CANTLOCK) = "Can't lock file (Errcode: %d)";
|
||||||
|
EE(EE_CANTUNLOCK) = "Can't unlock file (Errcode: %d)";
|
||||||
|
EE(EE_DIR) = "Can't read dir of '%s' (Errcode: %d)";
|
||||||
|
EE(EE_STAT) = "Can't get stat of '%s' (Errcode: %d)";
|
||||||
|
EE(EE_CANT_CHSIZE) = "Can't change size of file (Errcode: %d)";
|
||||||
|
EE(EE_CANT_OPEN_STREAM)= "Can't open stream from handle (Errcode: %d)";
|
||||||
|
EE(EE_GETWD) = "Can't get working directory (Errcode: %d)";
|
||||||
|
EE(EE_SETWD) = "Can't change dir to '%s' (Errcode: %d)";
|
||||||
|
EE(EE_LINK_WARNING) = "Warning: '%s' had %d links";
|
||||||
|
EE(EE_OPEN_WARNING) = "Warning: %d files and %d streams is left open\n";
|
||||||
|
EE(EE_DISK_FULL) = "Disk is full writing '%s'. Waiting for someone to free space...";
|
||||||
|
EE(EE_CANT_MKDIR) ="Can't create directory '%s' (Errcode: %d)";
|
||||||
|
EE(EE_UNKNOWN_CHARSET)= "Character set '%s' is not a compiled character set and is not specified in the %s file";
|
||||||
|
EE(EE_OUT_OF_FILERESOURCES)="Out of resources when opening file '%s' (Errcode: %d)";
|
||||||
|
EE(EE_CANT_READLINK)= "Can't read value for symlink '%s' (Error %d)";
|
||||||
|
EE(EE_CANT_SYMLINK)= "Can't create symlink '%s' pointing at '%s' (Error %d)";
|
||||||
|
EE(EE_REALPATH)= "Error on realpath() on '%s' (Error %d)";
|
||||||
|
EE(EE_SYNC)= "Can't sync file '%s' to disk (Errcode: %d)";
|
||||||
|
EE(EE_UNKNOWN_COLLATION)= "Collation '%s' is not a compiled collation and is not specified in the %s file";
|
||||||
|
EE(EE_FILENOTFOUND) = "File '%s' not found (Errcode: %d)";
|
||||||
|
EE(EE_FILE_NOT_CLOSED) = "File '%s' (fileno: %d) was not closed";
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void wait_for_free_space(const char *filename, int errors)
|
||||||
|
{
|
||||||
|
if (errors == 0)
|
||||||
|
my_error(EE_DISK_FULL,MYF(ME_BELL | ME_NOREFRESH),
|
||||||
|
filename,my_errno,MY_WAIT_FOR_USER_TO_FIX_PANIC);
|
||||||
|
if (!(errors % MY_WAIT_GIVE_USER_A_MESSAGE))
|
||||||
|
my_printf_error(EE_DISK_FULL,
|
||||||
|
"Retry in %d secs. Message reprinted in %d secs",
|
||||||
|
MYF(ME_BELL | ME_NOREFRESH),
|
||||||
|
MY_WAIT_FOR_USER_TO_FIX_PANIC,
|
||||||
|
MY_WAIT_GIVE_USER_A_MESSAGE * MY_WAIT_FOR_USER_TO_FIX_PANIC );
|
||||||
|
VOID(sleep(MY_WAIT_FOR_USER_TO_FIX_PANIC));
|
||||||
|
}
|
220
MySQL/get_password.c
Normal file
220
MySQL/get_password.c
Normal file
@ -0,0 +1,220 @@
|
|||||||
|
/* Copyright (C) 2000-2004 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation.
|
||||||
|
|
||||||
|
There are special exceptions to the terms and conditions of the GPL as it
|
||||||
|
is applied to this software. View the full text of the exception in file
|
||||||
|
EXCEPTIONS-CLIENT in the directory of this software distribution.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Ask for a password from tty
|
||||||
|
** This is an own file to avoid conflicts with curses
|
||||||
|
*/
|
||||||
|
#include <my_global.h>
|
||||||
|
#include <my_sys.h>
|
||||||
|
#include "mysql.h"
|
||||||
|
#include <m_string.h>
|
||||||
|
#include <m_ctype.h>
|
||||||
|
|
||||||
|
#if defined(HAVE_BROKEN_GETPASS) && !defined(HAVE_GETPASSPHRASE)
|
||||||
|
#undef HAVE_GETPASS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_GETPASS
|
||||||
|
#ifdef HAVE_PWD_H
|
||||||
|
#include <pwd.h>
|
||||||
|
#endif /* HAVE_PWD_H */
|
||||||
|
#else /* ! HAVE_GETPASS */
|
||||||
|
#if !defined(__WIN__) && !defined(__NETWARE__)
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#ifdef HAVE_TERMIOS_H /* For tty-password */
|
||||||
|
#include <termios.h>
|
||||||
|
#define TERMIO struct termios
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_TERMIO_H /* For tty-password */
|
||||||
|
#include <termio.h>
|
||||||
|
#define TERMIO struct termio
|
||||||
|
#else
|
||||||
|
#include <sgtty.h>
|
||||||
|
#define TERMIO struct sgttyb
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#ifdef alpha_linux_port
|
||||||
|
#include <asm/ioctls.h> /* QQ; Fix this in configure */
|
||||||
|
#include <asm/termiobits.h>
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#ifndef __NETWARE__
|
||||||
|
#include <conio.h>
|
||||||
|
#endif /* __NETWARE__ */
|
||||||
|
#endif /* __WIN__ */
|
||||||
|
#endif /* HAVE_GETPASS */
|
||||||
|
|
||||||
|
#ifdef HAVE_GETPASSPHRASE /* For Solaris */
|
||||||
|
#define getpass(A) getpassphrase(A)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined( __WIN__) || defined(__NETWARE__)
|
||||||
|
/* were just going to fake it here and get input from the keyboard */
|
||||||
|
|
||||||
|
#ifdef __NETWARE__
|
||||||
|
#undef _getch
|
||||||
|
#undef _cputs
|
||||||
|
#define _getch getcharacter
|
||||||
|
#define _cputs(A) putstring(A)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
char *get_tty_password(const char *opt_message)
|
||||||
|
{
|
||||||
|
char to[80];
|
||||||
|
char *pos=to,*end=to+sizeof(to)-1;
|
||||||
|
int i=0;
|
||||||
|
DBUG_ENTER("get_tty_password");
|
||||||
|
_cputs(opt_message ? opt_message : "Enter password: ");
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
char tmp;
|
||||||
|
tmp=_getch();
|
||||||
|
if (tmp == '\b' || (int) tmp == 127)
|
||||||
|
{
|
||||||
|
if (pos != to)
|
||||||
|
{
|
||||||
|
_cputs("\b \b");
|
||||||
|
pos--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (tmp == '\n' || tmp == '\r' || tmp == 3)
|
||||||
|
break;
|
||||||
|
if (iscntrl(tmp) || pos == end)
|
||||||
|
continue;
|
||||||
|
_cputs("*");
|
||||||
|
*(pos++) = tmp;
|
||||||
|
}
|
||||||
|
while (pos != to && isspace(pos[-1]) == ' ')
|
||||||
|
pos--; /* Allow dummy space at end */
|
||||||
|
*pos=0;
|
||||||
|
_cputs("\n");
|
||||||
|
DBUG_RETURN(my_strdup(to,MYF(MY_FAE)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#ifndef HAVE_GETPASS
|
||||||
|
/*
|
||||||
|
Can't use fgets, because readline will get confused
|
||||||
|
length is max number of chars in to, not counting \0
|
||||||
|
to will not include the eol characters.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void get_password(char *to,uint length,int fd, my_bool echo)
|
||||||
|
{
|
||||||
|
char *pos=to,*end=to+length;
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
char tmp;
|
||||||
|
if (my_read(fd,&tmp,1,MYF(0)) != 1)
|
||||||
|
break;
|
||||||
|
if (tmp == '\b' || (int) tmp == 127)
|
||||||
|
{
|
||||||
|
if (pos != to)
|
||||||
|
{
|
||||||
|
if (echo)
|
||||||
|
{
|
||||||
|
fputs("\b \b",stdout);
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
pos--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (tmp == '\n' || tmp == '\r' || tmp == 3)
|
||||||
|
break;
|
||||||
|
if (iscntrl(tmp) || pos == end)
|
||||||
|
continue;
|
||||||
|
if (echo)
|
||||||
|
{
|
||||||
|
fputc('*',stdout);
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
*(pos++) = tmp;
|
||||||
|
}
|
||||||
|
while (pos != to && isspace(pos[-1]) == ' ')
|
||||||
|
pos--; /* Allow dummy space at end */
|
||||||
|
*pos=0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif /* ! HAVE_GETPASS */
|
||||||
|
|
||||||
|
|
||||||
|
char *get_tty_password(const char *opt_message)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_GETPASS
|
||||||
|
char *passbuff;
|
||||||
|
#else /* ! HAVE_GETPASS */
|
||||||
|
TERMIO org,tmp;
|
||||||
|
#endif /* HAVE_GETPASS */
|
||||||
|
char buff[80];
|
||||||
|
|
||||||
|
DBUG_ENTER("get_tty_password");
|
||||||
|
|
||||||
|
#ifdef HAVE_GETPASS
|
||||||
|
passbuff = getpass(opt_message ? opt_message : "Enter password: ");
|
||||||
|
|
||||||
|
/* copy the password to buff and clear original (static) buffer */
|
||||||
|
strnmov(buff, passbuff, sizeof(buff) - 1);
|
||||||
|
#ifdef _PASSWORD_LEN
|
||||||
|
memset(passbuff, 0, _PASSWORD_LEN);
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
if (isatty(fileno(stdout)))
|
||||||
|
{
|
||||||
|
fputs(opt_message ? opt_message : "Enter password: ",stdout);
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
#if defined(HAVE_TERMIOS_H)
|
||||||
|
tcgetattr(fileno(stdin), &org);
|
||||||
|
tmp = org;
|
||||||
|
tmp.c_lflag &= ~(ECHO | ISIG | ICANON);
|
||||||
|
tmp.c_cc[VMIN] = 1;
|
||||||
|
tmp.c_cc[VTIME] = 0;
|
||||||
|
tcsetattr(fileno(stdin), TCSADRAIN, &tmp);
|
||||||
|
get_password(buff, sizeof(buff)-1, fileno(stdin), isatty(fileno(stdout)));
|
||||||
|
tcsetattr(fileno(stdin), TCSADRAIN, &org);
|
||||||
|
#elif defined(HAVE_TERMIO_H)
|
||||||
|
ioctl(fileno(stdin), (int) TCGETA, &org);
|
||||||
|
tmp=org;
|
||||||
|
tmp.c_lflag &= ~(ECHO | ISIG | ICANON);
|
||||||
|
tmp.c_cc[VMIN] = 1;
|
||||||
|
tmp.c_cc[VTIME]= 0;
|
||||||
|
ioctl(fileno(stdin),(int) TCSETA, &tmp);
|
||||||
|
get_password(buff,sizeof(buff)-1,fileno(stdin),isatty(fileno(stdout)));
|
||||||
|
ioctl(fileno(stdin),(int) TCSETA, &org);
|
||||||
|
#else
|
||||||
|
gtty(fileno(stdin), &org);
|
||||||
|
tmp=org;
|
||||||
|
tmp.sg_flags &= ~ECHO;
|
||||||
|
tmp.sg_flags |= RAW;
|
||||||
|
stty(fileno(stdin), &tmp);
|
||||||
|
get_password(buff,sizeof(buff)-1,fileno(stdin),isatty(fileno(stdout)));
|
||||||
|
stty(fileno(stdin), &org);
|
||||||
|
#endif
|
||||||
|
if (isatty(fileno(stdout)))
|
||||||
|
fputc('\n',stdout);
|
||||||
|
#endif /* HAVE_GETPASS */
|
||||||
|
|
||||||
|
DBUG_RETURN(my_strdup(buff,MYF(MY_FAE)));
|
||||||
|
}
|
||||||
|
#endif /*__WIN__*/
|
732
MySQL/hash.c
Normal file
732
MySQL/hash.c
Normal file
@ -0,0 +1,732 @@
|
|||||||
|
/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
/* The hash functions used for saveing keys */
|
||||||
|
/* One of key_length or key_length_offset must be given */
|
||||||
|
/* Key length of 0 isn't allowed */
|
||||||
|
|
||||||
|
#include "mysys_priv.h"
|
||||||
|
#include <m_string.h>
|
||||||
|
#include <m_ctype.h>
|
||||||
|
#include "hash.h"
|
||||||
|
|
||||||
|
#define NO_RECORD ((uint) -1)
|
||||||
|
#define LOWFIND 1
|
||||||
|
#define LOWUSED 2
|
||||||
|
#define HIGHFIND 4
|
||||||
|
#define HIGHUSED 8
|
||||||
|
|
||||||
|
typedef struct st_hash_info {
|
||||||
|
uint next; /* index to next key */
|
||||||
|
uchar *data; /* data for current entry */
|
||||||
|
} HASH_LINK;
|
||||||
|
|
||||||
|
static uint my_hash_mask(size_t hashnr, size_t buffmax, size_t maxlength);
|
||||||
|
static void movelink(HASH_LINK *array,uint pos,uint next_link,uint newlink);
|
||||||
|
static int hashcmp(const HASH *hash, HASH_LINK *pos, const uchar *key,
|
||||||
|
size_t length);
|
||||||
|
|
||||||
|
static uint calc_hash(const HASH *hash, const uchar *key, size_t length)
|
||||||
|
{
|
||||||
|
ulong nr1=1, nr2=4;
|
||||||
|
hash->charset->coll->hash_sort(hash->charset,(uchar*) key,length,&nr1,&nr2);
|
||||||
|
return nr1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief Initialize the hash
|
||||||
|
|
||||||
|
@details
|
||||||
|
|
||||||
|
Initialize the hash, by defining and giving valid values for
|
||||||
|
its elements. The failure to allocate memory for the
|
||||||
|
hash->array element will not result in a fatal failure. The
|
||||||
|
dynamic array that is part of the hash will allocate memory
|
||||||
|
as required during insertion.
|
||||||
|
|
||||||
|
@param[in,out] hash The hash that is initialized
|
||||||
|
@param[in] charset The charater set information
|
||||||
|
@param[in] size The hash size
|
||||||
|
@param[in] key_offest The key offset for the hash
|
||||||
|
@param[in] key_length The length of the key used in
|
||||||
|
the hash
|
||||||
|
@param[in] get_key get the key for the hash
|
||||||
|
@param[in] free_element pointer to the function that
|
||||||
|
does cleanup
|
||||||
|
@param[in] CALLER_INFO_PROTO flag that define the behaviour
|
||||||
|
of the hash
|
||||||
|
@return inidicates success or failure of initialization
|
||||||
|
@retval 0 success
|
||||||
|
@retval 1 failure
|
||||||
|
*/
|
||||||
|
my_bool
|
||||||
|
_my_hash_init(HASH *hash, uint growth_size, CHARSET_INFO *charset,
|
||||||
|
ulong size, size_t key_offset, size_t key_length,
|
||||||
|
my_hash_get_key get_key,
|
||||||
|
void (*free_element)(void*), uint flags CALLER_INFO_PROTO)
|
||||||
|
{
|
||||||
|
DBUG_ENTER("my_hash_init");
|
||||||
|
DBUG_PRINT("enter",("hash: 0x%lx size: %u", (long) hash, (uint) size));
|
||||||
|
|
||||||
|
hash->records=0;
|
||||||
|
hash->key_offset=key_offset;
|
||||||
|
hash->key_length=key_length;
|
||||||
|
hash->blength=1;
|
||||||
|
hash->get_key=get_key;
|
||||||
|
hash->free=free_element;
|
||||||
|
hash->flags=flags;
|
||||||
|
hash->charset=charset;
|
||||||
|
DBUG_RETURN(my_init_dynamic_array_ci(&hash->array,
|
||||||
|
sizeof(HASH_LINK), size, growth_size));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Call hash->free on all elements in hash.
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
my_hash_free_elements()
|
||||||
|
hash hash table
|
||||||
|
|
||||||
|
NOTES:
|
||||||
|
Sets records to 0
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline void my_hash_free_elements(HASH *hash)
|
||||||
|
{
|
||||||
|
if (hash->free)
|
||||||
|
{
|
||||||
|
HASH_LINK *data=dynamic_element(&hash->array,0,HASH_LINK*);
|
||||||
|
HASH_LINK *end= data + hash->records;
|
||||||
|
while (data < end)
|
||||||
|
(*hash->free)((data++)->data);
|
||||||
|
}
|
||||||
|
hash->records=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Free memory used by hash.
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
my_hash_free()
|
||||||
|
hash the hash to delete elements of
|
||||||
|
|
||||||
|
NOTES: Hash can't be reused without calling my_hash_init again.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void my_hash_free(HASH *hash)
|
||||||
|
{
|
||||||
|
DBUG_ENTER("my_hash_free");
|
||||||
|
DBUG_PRINT("enter",("hash: 0x%lx", (long) hash));
|
||||||
|
|
||||||
|
my_hash_free_elements(hash);
|
||||||
|
hash->free= 0;
|
||||||
|
delete_dynamic(&hash->array);
|
||||||
|
hash->blength= 0;
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Delete all elements from the hash (the hash itself is to be reused).
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
my_hash_reset()
|
||||||
|
hash the hash to delete elements of
|
||||||
|
*/
|
||||||
|
|
||||||
|
void my_hash_reset(HASH *hash)
|
||||||
|
{
|
||||||
|
DBUG_ENTER("my_hash_reset");
|
||||||
|
DBUG_PRINT("enter",("hash: 0x%lxd", (long) hash));
|
||||||
|
|
||||||
|
my_hash_free_elements(hash);
|
||||||
|
reset_dynamic(&hash->array);
|
||||||
|
/* Set row pointers so that the hash can be reused at once */
|
||||||
|
hash->blength= 1;
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* some helper functions */
|
||||||
|
|
||||||
|
/*
|
||||||
|
This function is char* instead of uchar* as HPUX11 compiler can't
|
||||||
|
handle inline functions that are not defined as native types
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline char*
|
||||||
|
my_hash_key(const HASH *hash, const uchar *record, size_t *length,
|
||||||
|
my_bool first)
|
||||||
|
{
|
||||||
|
if (hash->get_key)
|
||||||
|
return (char*) (*hash->get_key)(record,length,first);
|
||||||
|
*length=hash->key_length;
|
||||||
|
return (char*) record+hash->key_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calculate pos according to keys */
|
||||||
|
|
||||||
|
static uint my_hash_mask(size_t hashnr, size_t buffmax, size_t maxlength)
|
||||||
|
{
|
||||||
|
if ((hashnr & (buffmax-1)) < maxlength) return (hashnr & (buffmax-1));
|
||||||
|
return (hashnr & ((buffmax >> 1) -1));
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint my_hash_rec_mask(const HASH *hash, HASH_LINK *pos,
|
||||||
|
size_t buffmax, size_t maxlength)
|
||||||
|
{
|
||||||
|
size_t length;
|
||||||
|
uchar *key= (uchar*) my_hash_key(hash, pos->data, &length, 0);
|
||||||
|
return my_hash_mask(calc_hash(hash, key, length), buffmax, maxlength);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* for compilers which can not handle inline */
|
||||||
|
static
|
||||||
|
#if !defined(__USLC__) && !defined(__sgi)
|
||||||
|
inline
|
||||||
|
#endif
|
||||||
|
unsigned int rec_hashnr(HASH *hash,const uchar *record)
|
||||||
|
{
|
||||||
|
size_t length;
|
||||||
|
uchar *key= (uchar*) my_hash_key(hash, record, &length, 0);
|
||||||
|
return calc_hash(hash,key,length);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uchar* my_hash_search(const HASH *hash, const uchar *key, size_t length)
|
||||||
|
{
|
||||||
|
HASH_SEARCH_STATE state;
|
||||||
|
return my_hash_first(hash, key, length, &state);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Search after a record based on a key
|
||||||
|
|
||||||
|
NOTE
|
||||||
|
Assigns the number of the found record to HASH_SEARCH_STATE state
|
||||||
|
*/
|
||||||
|
|
||||||
|
uchar* my_hash_first(const HASH *hash, const uchar *key, size_t length,
|
||||||
|
HASH_SEARCH_STATE *current_record)
|
||||||
|
{
|
||||||
|
HASH_LINK *pos;
|
||||||
|
uint flag,idx;
|
||||||
|
DBUG_ENTER("my_hash_first");
|
||||||
|
|
||||||
|
flag=1;
|
||||||
|
if (hash->records)
|
||||||
|
{
|
||||||
|
idx= my_hash_mask(calc_hash(hash, key, length ? length : hash->key_length),
|
||||||
|
hash->blength, hash->records);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
pos= dynamic_element(&hash->array,idx,HASH_LINK*);
|
||||||
|
if (!hashcmp(hash,pos,key,length))
|
||||||
|
{
|
||||||
|
DBUG_PRINT("exit",("found key at %d",idx));
|
||||||
|
*current_record= idx;
|
||||||
|
DBUG_RETURN (pos->data);
|
||||||
|
}
|
||||||
|
if (flag)
|
||||||
|
{
|
||||||
|
flag=0; /* Reset flag */
|
||||||
|
if (my_hash_rec_mask(hash, pos, hash->blength, hash->records) != idx)
|
||||||
|
break; /* Wrong link */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while ((idx=pos->next) != NO_RECORD);
|
||||||
|
}
|
||||||
|
*current_record= NO_RECORD;
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get next record with identical key */
|
||||||
|
/* Can only be called if previous calls was my_hash_search */
|
||||||
|
|
||||||
|
uchar* my_hash_next(const HASH *hash, const uchar *key, size_t length,
|
||||||
|
HASH_SEARCH_STATE *current_record)
|
||||||
|
{
|
||||||
|
HASH_LINK *pos;
|
||||||
|
uint idx;
|
||||||
|
|
||||||
|
if (*current_record != NO_RECORD)
|
||||||
|
{
|
||||||
|
HASH_LINK *data=dynamic_element(&hash->array,0,HASH_LINK*);
|
||||||
|
for (idx=data[*current_record].next; idx != NO_RECORD ; idx=pos->next)
|
||||||
|
{
|
||||||
|
pos=data+idx;
|
||||||
|
if (!hashcmp(hash,pos,key,length))
|
||||||
|
{
|
||||||
|
*current_record= idx;
|
||||||
|
return pos->data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*current_record= NO_RECORD;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Change link from pos to new_link */
|
||||||
|
|
||||||
|
static void movelink(HASH_LINK *array,uint find,uint next_link,uint newlink)
|
||||||
|
{
|
||||||
|
HASH_LINK *old_link;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
old_link=array+next_link;
|
||||||
|
}
|
||||||
|
while ((next_link=old_link->next) != find);
|
||||||
|
old_link->next= newlink;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Compare a key in a record to a whole key. Return 0 if identical
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
hashcmp()
|
||||||
|
hash hash table
|
||||||
|
pos position of hash record to use in comparison
|
||||||
|
key key for comparison
|
||||||
|
length length of key
|
||||||
|
|
||||||
|
NOTES:
|
||||||
|
If length is 0, comparison is done using the length of the
|
||||||
|
record being compared against.
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
= 0 key of record == key
|
||||||
|
!= 0 key of record != key
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int hashcmp(const HASH *hash, HASH_LINK *pos, const uchar *key,
|
||||||
|
size_t length)
|
||||||
|
{
|
||||||
|
size_t rec_keylength;
|
||||||
|
uchar *rec_key= (uchar*) my_hash_key(hash, pos->data, &rec_keylength, 1);
|
||||||
|
return ((length && length != rec_keylength) ||
|
||||||
|
my_strnncoll(hash->charset, (uchar*) rec_key, rec_keylength,
|
||||||
|
(uchar*) key, rec_keylength));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Write a hash-key to the hash-index */
|
||||||
|
|
||||||
|
my_bool my_hash_insert(HASH *info, const uchar *record)
|
||||||
|
{
|
||||||
|
int flag;
|
||||||
|
size_t idx,halfbuff,hash_nr,first_index;
|
||||||
|
uchar *UNINIT_VAR(ptr_to_rec),*UNINIT_VAR(ptr_to_rec2);
|
||||||
|
HASH_LINK *data,*empty,*UNINIT_VAR(gpos),*UNINIT_VAR(gpos2),*pos;
|
||||||
|
|
||||||
|
if (HASH_UNIQUE & info->flags)
|
||||||
|
{
|
||||||
|
uchar *key= (uchar*) my_hash_key(info, record, &idx, 1);
|
||||||
|
if (my_hash_search(info, key, idx))
|
||||||
|
return(TRUE); /* Duplicate entry */
|
||||||
|
}
|
||||||
|
|
||||||
|
flag=0;
|
||||||
|
if (!(empty=(HASH_LINK*) alloc_dynamic(&info->array)))
|
||||||
|
return(TRUE); /* No more memory */
|
||||||
|
|
||||||
|
data=dynamic_element(&info->array,0,HASH_LINK*);
|
||||||
|
halfbuff= info->blength >> 1;
|
||||||
|
|
||||||
|
idx=first_index=info->records-halfbuff;
|
||||||
|
if (idx != info->records) /* If some records */
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
pos=data+idx;
|
||||||
|
hash_nr=rec_hashnr(info,pos->data);
|
||||||
|
if (flag == 0) /* First loop; Check if ok */
|
||||||
|
if (my_hash_mask(hash_nr, info->blength, info->records) != first_index)
|
||||||
|
break;
|
||||||
|
if (!(hash_nr & halfbuff))
|
||||||
|
{ /* Key will not move */
|
||||||
|
if (!(flag & LOWFIND))
|
||||||
|
{
|
||||||
|
if (flag & HIGHFIND)
|
||||||
|
{
|
||||||
|
flag=LOWFIND | HIGHFIND;
|
||||||
|
/* key shall be moved to the current empty position */
|
||||||
|
gpos=empty;
|
||||||
|
ptr_to_rec=pos->data;
|
||||||
|
empty=pos; /* This place is now free */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
flag=LOWFIND | LOWUSED; /* key isn't changed */
|
||||||
|
gpos=pos;
|
||||||
|
ptr_to_rec=pos->data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!(flag & LOWUSED))
|
||||||
|
{
|
||||||
|
/* Change link of previous LOW-key */
|
||||||
|
gpos->data=ptr_to_rec;
|
||||||
|
gpos->next= (uint) (pos-data);
|
||||||
|
flag= (flag & HIGHFIND) | (LOWFIND | LOWUSED);
|
||||||
|
}
|
||||||
|
gpos=pos;
|
||||||
|
ptr_to_rec=pos->data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ /* key will be moved */
|
||||||
|
if (!(flag & HIGHFIND))
|
||||||
|
{
|
||||||
|
flag= (flag & LOWFIND) | HIGHFIND;
|
||||||
|
/* key shall be moved to the last (empty) position */
|
||||||
|
gpos2 = empty; empty=pos;
|
||||||
|
ptr_to_rec2=pos->data;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!(flag & HIGHUSED))
|
||||||
|
{
|
||||||
|
/* Change link of previous hash-key and save */
|
||||||
|
gpos2->data=ptr_to_rec2;
|
||||||
|
gpos2->next=(uint) (pos-data);
|
||||||
|
flag= (flag & LOWFIND) | (HIGHFIND | HIGHUSED);
|
||||||
|
}
|
||||||
|
gpos2=pos;
|
||||||
|
ptr_to_rec2=pos->data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while ((idx=pos->next) != NO_RECORD);
|
||||||
|
|
||||||
|
if ((flag & (LOWFIND | LOWUSED)) == LOWFIND)
|
||||||
|
{
|
||||||
|
gpos->data=ptr_to_rec;
|
||||||
|
gpos->next=NO_RECORD;
|
||||||
|
}
|
||||||
|
if ((flag & (HIGHFIND | HIGHUSED)) == HIGHFIND)
|
||||||
|
{
|
||||||
|
gpos2->data=ptr_to_rec2;
|
||||||
|
gpos2->next=NO_RECORD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Check if we are at the empty position */
|
||||||
|
|
||||||
|
idx= my_hash_mask(rec_hashnr(info, record), info->blength, info->records + 1);
|
||||||
|
pos=data+idx;
|
||||||
|
if (pos == empty)
|
||||||
|
{
|
||||||
|
pos->data=(uchar*) record;
|
||||||
|
pos->next=NO_RECORD;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Check if more records in same hash-nr family */
|
||||||
|
empty[0]=pos[0];
|
||||||
|
gpos= data + my_hash_rec_mask(info, pos, info->blength, info->records + 1);
|
||||||
|
if (pos == gpos)
|
||||||
|
{
|
||||||
|
pos->data=(uchar*) record;
|
||||||
|
pos->next=(uint) (empty - data);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pos->data=(uchar*) record;
|
||||||
|
pos->next=NO_RECORD;
|
||||||
|
movelink(data,(uint) (pos-data),(uint) (gpos-data),(uint) (empty-data));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (++info->records == info->blength)
|
||||||
|
info->blength+= info->blength;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
** Remove one record from hash-table. The record with the same record
|
||||||
|
** ptr is removed.
|
||||||
|
** if there is a free-function it's called for record if found
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
my_bool my_hash_delete(HASH *hash, uchar *record)
|
||||||
|
{
|
||||||
|
uint blength,pos2,pos_hashnr,lastpos_hashnr,idx,empty_index;
|
||||||
|
HASH_LINK *data,*lastpos,*gpos,*pos,*pos3,*empty;
|
||||||
|
DBUG_ENTER("my_hash_delete");
|
||||||
|
if (!hash->records)
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
|
||||||
|
blength=hash->blength;
|
||||||
|
data=dynamic_element(&hash->array,0,HASH_LINK*);
|
||||||
|
/* Search after record with key */
|
||||||
|
pos= data + my_hash_mask(rec_hashnr(hash, record), blength, hash->records);
|
||||||
|
gpos = 0;
|
||||||
|
|
||||||
|
while (pos->data != record)
|
||||||
|
{
|
||||||
|
gpos=pos;
|
||||||
|
if (pos->next == NO_RECORD)
|
||||||
|
DBUG_RETURN(1); /* Key not found */
|
||||||
|
pos=data+pos->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( --(hash->records) < hash->blength >> 1) hash->blength>>=1;
|
||||||
|
lastpos=data+hash->records;
|
||||||
|
|
||||||
|
/* Remove link to record */
|
||||||
|
empty=pos; empty_index=(uint) (empty-data);
|
||||||
|
if (gpos)
|
||||||
|
gpos->next=pos->next; /* unlink current ptr */
|
||||||
|
else if (pos->next != NO_RECORD)
|
||||||
|
{
|
||||||
|
empty=data+(empty_index=pos->next);
|
||||||
|
pos->data=empty->data;
|
||||||
|
pos->next=empty->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty == lastpos) /* last key at wrong pos or no next link */
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
/* Move the last key (lastpos) */
|
||||||
|
lastpos_hashnr=rec_hashnr(hash,lastpos->data);
|
||||||
|
/* pos is where lastpos should be */
|
||||||
|
pos= data + my_hash_mask(lastpos_hashnr, hash->blength, hash->records);
|
||||||
|
if (pos == empty) /* Move to empty position. */
|
||||||
|
{
|
||||||
|
empty[0]=lastpos[0];
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
pos_hashnr=rec_hashnr(hash,pos->data);
|
||||||
|
/* pos3 is where the pos should be */
|
||||||
|
pos3= data + my_hash_mask(pos_hashnr, hash->blength, hash->records);
|
||||||
|
if (pos != pos3)
|
||||||
|
{ /* pos is on wrong posit */
|
||||||
|
empty[0]=pos[0]; /* Save it here */
|
||||||
|
pos[0]=lastpos[0]; /* This should be here */
|
||||||
|
movelink(data,(uint) (pos-data),(uint) (pos3-data),empty_index);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
pos2= my_hash_mask(lastpos_hashnr, blength, hash->records + 1);
|
||||||
|
if (pos2 == my_hash_mask(pos_hashnr, blength, hash->records + 1))
|
||||||
|
{ /* Identical key-positions */
|
||||||
|
if (pos2 != hash->records)
|
||||||
|
{
|
||||||
|
empty[0]=lastpos[0];
|
||||||
|
movelink(data,(uint) (lastpos-data),(uint) (pos-data),empty_index);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
idx= (uint) (pos-data); /* Link pos->next after lastpos */
|
||||||
|
}
|
||||||
|
else idx= NO_RECORD; /* Different positions merge */
|
||||||
|
|
||||||
|
empty[0]=lastpos[0];
|
||||||
|
movelink(data,idx,empty_index,pos->next);
|
||||||
|
pos->next=empty_index;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
VOID(pop_dynamic(&hash->array));
|
||||||
|
if (hash->free)
|
||||||
|
(*hash->free)((uchar*) record);
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Update keys when record has changed.
|
||||||
|
This is much more efficent than using a delete & insert.
|
||||||
|
*/
|
||||||
|
|
||||||
|
my_bool my_hash_update(HASH *hash, uchar *record, uchar *old_key,
|
||||||
|
size_t old_key_length)
|
||||||
|
{
|
||||||
|
uint new_index,new_pos_index,blength,records;
|
||||||
|
size_t idx,empty;
|
||||||
|
HASH_LINK org_link,*data,*previous,*pos;
|
||||||
|
DBUG_ENTER("my_hash_update");
|
||||||
|
|
||||||
|
if (HASH_UNIQUE & hash->flags)
|
||||||
|
{
|
||||||
|
HASH_SEARCH_STATE state;
|
||||||
|
uchar *found, *new_key= (uchar*) my_hash_key(hash, record, &idx, 1);
|
||||||
|
if ((found= my_hash_first(hash, new_key, idx, &state)))
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (found != record)
|
||||||
|
DBUG_RETURN(1); /* Duplicate entry */
|
||||||
|
}
|
||||||
|
while ((found= my_hash_next(hash, new_key, idx, &state)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data=dynamic_element(&hash->array,0,HASH_LINK*);
|
||||||
|
blength=hash->blength; records=hash->records;
|
||||||
|
|
||||||
|
/* Search after record with key */
|
||||||
|
|
||||||
|
idx= my_hash_mask(calc_hash(hash, old_key, (old_key_length ?
|
||||||
|
old_key_length :
|
||||||
|
hash->key_length)),
|
||||||
|
blength, records);
|
||||||
|
new_index= my_hash_mask(rec_hashnr(hash, record), blength, records);
|
||||||
|
if (idx == new_index)
|
||||||
|
DBUG_RETURN(0); /* Nothing to do (No record check) */
|
||||||
|
previous=0;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
|
||||||
|
if ((pos= data+idx)->data == record)
|
||||||
|
break;
|
||||||
|
previous=pos;
|
||||||
|
if ((idx=pos->next) == NO_RECORD)
|
||||||
|
DBUG_RETURN(1); /* Not found in links */
|
||||||
|
}
|
||||||
|
org_link= *pos;
|
||||||
|
empty=idx;
|
||||||
|
|
||||||
|
/* Relink record from current chain */
|
||||||
|
|
||||||
|
if (!previous)
|
||||||
|
{
|
||||||
|
if (pos->next != NO_RECORD)
|
||||||
|
{
|
||||||
|
empty=pos->next;
|
||||||
|
*pos= data[pos->next];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
previous->next=pos->next; /* unlink pos */
|
||||||
|
|
||||||
|
/* Move data to correct position */
|
||||||
|
if (new_index == empty)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
At this point record is unlinked from the old chain, thus it holds
|
||||||
|
random position. By the chance this position is equal to position
|
||||||
|
for the first element in the new chain. That means updated record
|
||||||
|
is the only record in the new chain.
|
||||||
|
*/
|
||||||
|
if (empty != idx)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Record was moved while unlinking it from the old chain.
|
||||||
|
Copy data to a new position.
|
||||||
|
*/
|
||||||
|
data[empty]= org_link;
|
||||||
|
}
|
||||||
|
data[empty].next= NO_RECORD;
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
}
|
||||||
|
pos=data+new_index;
|
||||||
|
new_pos_index= my_hash_rec_mask(hash, pos, blength, records);
|
||||||
|
if (new_index != new_pos_index)
|
||||||
|
{ /* Other record in wrong position */
|
||||||
|
data[empty] = *pos;
|
||||||
|
movelink(data,new_index,new_pos_index,empty);
|
||||||
|
org_link.next=NO_RECORD;
|
||||||
|
data[new_index]= org_link;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ /* Link in chain at right position */
|
||||||
|
org_link.next=data[new_index].next;
|
||||||
|
data[empty]=org_link;
|
||||||
|
data[new_index].next=empty;
|
||||||
|
}
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uchar *my_hash_element(HASH *hash, ulong idx)
|
||||||
|
{
|
||||||
|
if (idx < hash->records)
|
||||||
|
return dynamic_element(&hash->array,idx,HASH_LINK*)->data;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Replace old row with new row. This should only be used when key
|
||||||
|
isn't changed
|
||||||
|
*/
|
||||||
|
|
||||||
|
void my_hash_replace(HASH *hash, HASH_SEARCH_STATE *current_record,
|
||||||
|
uchar *new_row)
|
||||||
|
{
|
||||||
|
if (*current_record != NO_RECORD) /* Safety */
|
||||||
|
dynamic_element(&hash->array, *current_record, HASH_LINK*)->data= new_row;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef DBUG_OFF
|
||||||
|
|
||||||
|
my_bool my_hash_check(HASH *hash)
|
||||||
|
{
|
||||||
|
int error;
|
||||||
|
uint i,rec_link,found,max_links,seek,links,idx;
|
||||||
|
uint records,blength;
|
||||||
|
HASH_LINK *data,*hash_info;
|
||||||
|
|
||||||
|
records=hash->records; blength=hash->blength;
|
||||||
|
data=dynamic_element(&hash->array,0,HASH_LINK*);
|
||||||
|
error=0;
|
||||||
|
|
||||||
|
for (i=found=max_links=seek=0 ; i < records ; i++)
|
||||||
|
{
|
||||||
|
if (my_hash_rec_mask(hash, data + i, blength, records) == i)
|
||||||
|
{
|
||||||
|
found++; seek++; links=1;
|
||||||
|
for (idx=data[i].next ;
|
||||||
|
idx != NO_RECORD && found < records + 1;
|
||||||
|
idx=hash_info->next)
|
||||||
|
{
|
||||||
|
if (idx >= records)
|
||||||
|
{
|
||||||
|
DBUG_PRINT("error",
|
||||||
|
("Found pointer outside array to %d from link starting at %d",
|
||||||
|
idx,i));
|
||||||
|
error=1;
|
||||||
|
}
|
||||||
|
hash_info=data+idx;
|
||||||
|
seek+= ++links;
|
||||||
|
if ((rec_link= my_hash_rec_mask(hash, hash_info,
|
||||||
|
blength, records)) != i)
|
||||||
|
{
|
||||||
|
DBUG_PRINT("error", ("Record in wrong link at %d: Start %d "
|
||||||
|
"Record: 0x%lx Record-link %d",
|
||||||
|
idx, i, (long) hash_info->data, rec_link));
|
||||||
|
error=1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
found++;
|
||||||
|
}
|
||||||
|
if (links > max_links) max_links=links;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (found != records)
|
||||||
|
{
|
||||||
|
DBUG_PRINT("error",("Found %u of %u records", found, records));
|
||||||
|
error=1;
|
||||||
|
}
|
||||||
|
if (records)
|
||||||
|
DBUG_PRINT("info",
|
||||||
|
("records: %u seeks: %d max links: %d hitrate: %.2f",
|
||||||
|
records,seek,max_links,(float) seek / (float) records));
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
#endif
|
116
MySQL/hash.h
Normal file
116
MySQL/hash.h
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
/* Dynamic hashing of record with different key-length */
|
||||||
|
|
||||||
|
#ifndef _hash_h
|
||||||
|
#define _hash_h
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
There was a problem on MacOSX with a shared object ha_example.so.
|
||||||
|
It used hash_search(). During build of ha_example.so no libmysys
|
||||||
|
was specified. Since MacOSX had a hash_search() in the system
|
||||||
|
library, it built the shared object so that the dynamic linker
|
||||||
|
linked hash_search() to the system library, which caused a crash
|
||||||
|
when called. To come around this, we renamed hash_search() to
|
||||||
|
my_hash_search(), as we did long ago with hash_insert() and
|
||||||
|
hash_reset(). However, this time we made the move complete with
|
||||||
|
all names. To keep compatibility, we redefine the old names.
|
||||||
|
Since every C and C++ file, that uses HASH, needs to include
|
||||||
|
this file, the change is complete. Both names could be used
|
||||||
|
in the code, but the my_* versions are recommended now.
|
||||||
|
*/
|
||||||
|
#define hash_get_key my_hash_get_key
|
||||||
|
#define hash_free_key my_hash_free_key
|
||||||
|
#define hash_init my_hash_init
|
||||||
|
#define hash_init2 my_hash_init2
|
||||||
|
#define _hash_init _my_hash_init
|
||||||
|
#define hash_free my_hash_free
|
||||||
|
#define hash_reset my_hash_reset
|
||||||
|
#define hash_element my_hash_element
|
||||||
|
#define hash_search my_hash_search
|
||||||
|
#define hash_first my_hash_first
|
||||||
|
#define hash_next my_hash_next
|
||||||
|
#define hash_insert my_hash_insert
|
||||||
|
#define hash_delete my_hash_delete
|
||||||
|
#define hash_update my_hash_update
|
||||||
|
#define hash_replace my_hash_replace
|
||||||
|
#define hash_check my_hash_check
|
||||||
|
#define hash_clear my_hash_clear
|
||||||
|
#define hash_inited my_hash_inited
|
||||||
|
#define hash_init_opt my_hash_init_opt
|
||||||
|
|
||||||
|
/*
|
||||||
|
Overhead to store an element in hash
|
||||||
|
Can be used to approximate memory consumption for a hash
|
||||||
|
*/
|
||||||
|
#define HASH_OVERHEAD (sizeof(char*)*2)
|
||||||
|
|
||||||
|
/* flags for hash_init */
|
||||||
|
#define HASH_UNIQUE 1 /* hash_insert fails on duplicate key */
|
||||||
|
|
||||||
|
typedef uchar *(*my_hash_get_key)(const uchar *,size_t*,my_bool);
|
||||||
|
typedef void (*my_hash_free_key)(void *);
|
||||||
|
|
||||||
|
typedef struct st_hash {
|
||||||
|
size_t key_offset,key_length; /* Length of key if const length */
|
||||||
|
size_t blength;
|
||||||
|
ulong records;
|
||||||
|
uint flags;
|
||||||
|
DYNAMIC_ARRAY array; /* Place for hash_keys */
|
||||||
|
my_hash_get_key get_key;
|
||||||
|
void (*free)(void *);
|
||||||
|
CHARSET_INFO *charset;
|
||||||
|
} HASH;
|
||||||
|
|
||||||
|
/* A search iterator state */
|
||||||
|
typedef uint HASH_SEARCH_STATE;
|
||||||
|
|
||||||
|
#define my_hash_init(A,B,C,D,E,F,G,H) \
|
||||||
|
_my_hash_init(A,0,B,C,D,E,F,G,H CALLER_INFO)
|
||||||
|
#define my_hash_init2(A,B,C,D,E,F,G,H,I) \
|
||||||
|
_my_hash_init(A,B,C,D,E,F,G,H,I CALLER_INFO)
|
||||||
|
my_bool _my_hash_init(HASH *hash, uint growth_size, CHARSET_INFO *charset,
|
||||||
|
ulong default_array_elements, size_t key_offset,
|
||||||
|
size_t key_length, my_hash_get_key get_key,
|
||||||
|
void (*free_element)(void*),
|
||||||
|
uint flags CALLER_INFO_PROTO);
|
||||||
|
void my_hash_free(HASH *tree);
|
||||||
|
void my_hash_reset(HASH *hash);
|
||||||
|
uchar *my_hash_element(HASH *hash, ulong idx);
|
||||||
|
uchar *my_hash_search(const HASH *info, const uchar *key, size_t length);
|
||||||
|
uchar *my_hash_first(const HASH *info, const uchar *key, size_t length,
|
||||||
|
HASH_SEARCH_STATE *state);
|
||||||
|
uchar *my_hash_next(const HASH *info, const uchar *key, size_t length,
|
||||||
|
HASH_SEARCH_STATE *state);
|
||||||
|
my_bool my_hash_insert(HASH *info, const uchar *data);
|
||||||
|
my_bool my_hash_delete(HASH *hash, uchar *record);
|
||||||
|
my_bool my_hash_update(HASH *hash, uchar *record, uchar *old_key,
|
||||||
|
size_t old_key_length);
|
||||||
|
void my_hash_replace(HASH *hash, HASH_SEARCH_STATE *state, uchar *new_row);
|
||||||
|
my_bool my_hash_check(HASH *hash); /* Only in debug library */
|
||||||
|
|
||||||
|
#define my_hash_clear(H) bzero((char*) (H), sizeof(*(H)))
|
||||||
|
#define my_hash_inited(H) ((H)->blength != 0)
|
||||||
|
#define my_hash_init_opt(A,B,C,D,E,F,G,H) \
|
||||||
|
(!my_hash_inited(A) && _my_hash_init(A,0,B,C,D,E,F,G, H CALLER_INFO))
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
22
MySQL/help_end.h
Normal file
22
MySQL/help_end.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
/* Copyright (C) 2004-2005 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
|
||||||
|
|
||||||
|
#ifdef __NETWARE__
|
||||||
|
#undef printf
|
||||||
|
#undef puts
|
||||||
|
#undef fputs
|
||||||
|
#undef fputc
|
||||||
|
#undef putchar
|
||||||
|
#endif
|
24
MySQL/help_start.h
Normal file
24
MySQL/help_start.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
/* Copyright (C) 2004-2005 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
|
||||||
|
|
||||||
|
/* Divert all help information on NetWare to logger screen. */
|
||||||
|
|
||||||
|
#ifdef __NETWARE__
|
||||||
|
#define printf consoleprintf
|
||||||
|
#define puts(s) consoleprintf("%s\n",s)
|
||||||
|
#define fputs(s,f) puts(s)
|
||||||
|
#define fputc(s,f) consoleprintf("%c", s)
|
||||||
|
#define putchar(s) consoleprintf("%c", s)
|
||||||
|
#endif
|
164
MySQL/int2str.c
Normal file
164
MySQL/int2str.c
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
/* Copyright (C) 2000 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
#include <my_global.h>
|
||||||
|
#include "m_string.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
_dig_vec arrays are public because they are used in several outer places.
|
||||||
|
*/
|
||||||
|
char NEAR _dig_vec_upper[] =
|
||||||
|
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||||
|
char NEAR _dig_vec_lower[] =
|
||||||
|
"0123456789abcdefghijklmnopqrstuvwxyz";
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Convert integer to its string representation in given scale of notation.
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
int2str()
|
||||||
|
val - value to convert
|
||||||
|
dst - points to buffer where string representation should be stored
|
||||||
|
radix - radix of scale of notation
|
||||||
|
upcase - set to 1 if we should use upper-case digits
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Converts the (long) integer value to its character form and moves it to
|
||||||
|
the destination buffer followed by a terminating NUL.
|
||||||
|
If radix is -2..-36, val is taken to be SIGNED, if radix is 2..36, val is
|
||||||
|
taken to be UNSIGNED. That is, val is signed if and only if radix is.
|
||||||
|
All other radixes treated as bad and nothing will be changed in this case.
|
||||||
|
|
||||||
|
For conversion to decimal representation (radix is -10 or 10) one can use
|
||||||
|
optimized int10_to_str() function.
|
||||||
|
|
||||||
|
RETURN VALUE
|
||||||
|
Pointer to ending NUL character or NullS if radix is bad.
|
||||||
|
*/
|
||||||
|
|
||||||
|
char *
|
||||||
|
int2str(register long int val, register char *dst, register int radix,
|
||||||
|
int upcase)
|
||||||
|
{
|
||||||
|
char buffer[65];
|
||||||
|
register char *p;
|
||||||
|
long int new_val;
|
||||||
|
char *dig_vec= upcase ? _dig_vec_upper : _dig_vec_lower;
|
||||||
|
ulong uval= (ulong) val;
|
||||||
|
|
||||||
|
if (radix < 0)
|
||||||
|
{
|
||||||
|
if (radix < -36 || radix > -2)
|
||||||
|
return NullS;
|
||||||
|
if (val < 0)
|
||||||
|
{
|
||||||
|
*dst++ = '-';
|
||||||
|
/* Avoid integer overflow in (-val) for LONGLONG_MIN (BUG#31799). */
|
||||||
|
uval = (ulong)0 - uval;
|
||||||
|
}
|
||||||
|
radix = -radix;
|
||||||
|
}
|
||||||
|
else if (radix > 36 || radix < 2)
|
||||||
|
return NullS;
|
||||||
|
|
||||||
|
/*
|
||||||
|
The slightly contorted code which follows is due to the fact that
|
||||||
|
few machines directly support unsigned long / and %. Certainly
|
||||||
|
the VAX C compiler generates a subroutine call. In the interests
|
||||||
|
of efficiency (hollow laugh) I let this happen for the first digit
|
||||||
|
only; after that "val" will be in range so that signed integer
|
||||||
|
division will do. Sorry 'bout that. CHECK THE CODE PRODUCED BY
|
||||||
|
YOUR C COMPILER. The first % and / should be unsigned, the second
|
||||||
|
% and / signed, but C compilers tend to be extraordinarily
|
||||||
|
sensitive to minor details of style. This works on a VAX, that's
|
||||||
|
all I claim for it.
|
||||||
|
*/
|
||||||
|
p = &buffer[sizeof(buffer)-1];
|
||||||
|
*p = '\0';
|
||||||
|
new_val= uval / (ulong) radix;
|
||||||
|
*--p = dig_vec[(uchar) (uval- (ulong) new_val*(ulong) radix)];
|
||||||
|
val = new_val;
|
||||||
|
#ifdef HAVE_LDIV
|
||||||
|
while (val != 0)
|
||||||
|
{
|
||||||
|
ldiv_t res;
|
||||||
|
res=ldiv(val,radix);
|
||||||
|
*--p = dig_vec[res.rem];
|
||||||
|
val= res.quot;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
while (val != 0)
|
||||||
|
{
|
||||||
|
new_val=val/radix;
|
||||||
|
*--p = dig_vec[(uchar) (val-new_val*radix)];
|
||||||
|
val= new_val;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
while ((*dst++ = *p++) != 0) ;
|
||||||
|
return dst-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Converts integer to its string representation in decimal notation.
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
int10_to_str()
|
||||||
|
val - value to convert
|
||||||
|
dst - points to buffer where string representation should be stored
|
||||||
|
radix - flag that shows whenever val should be taken as signed or not
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
This is version of int2str() function which is optimized for normal case
|
||||||
|
of radix 10/-10. It takes only sign of radix parameter into account and
|
||||||
|
not its absolute value.
|
||||||
|
|
||||||
|
RETURN VALUE
|
||||||
|
Pointer to ending NUL character.
|
||||||
|
*/
|
||||||
|
|
||||||
|
char *int10_to_str(long int val,char *dst,int radix)
|
||||||
|
{
|
||||||
|
char buffer[65];
|
||||||
|
register char *p;
|
||||||
|
long int new_val;
|
||||||
|
unsigned long int uval = (unsigned long int) val;
|
||||||
|
|
||||||
|
if (radix < 0) /* -10 */
|
||||||
|
{
|
||||||
|
if (val < 0)
|
||||||
|
{
|
||||||
|
*dst++ = '-';
|
||||||
|
/* Avoid integer overflow in (-val) for LONGLONG_MIN (BUG#31799). */
|
||||||
|
uval = (unsigned long int)0 - uval;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p = &buffer[sizeof(buffer)-1];
|
||||||
|
*p = '\0';
|
||||||
|
new_val= (long) (uval / 10);
|
||||||
|
*--p = '0'+ (char) (uval - (unsigned long) new_val * 10);
|
||||||
|
val = new_val;
|
||||||
|
|
||||||
|
while (val != 0)
|
||||||
|
{
|
||||||
|
new_val=val/10;
|
||||||
|
*--p = '0' + (char) (val-new_val*10);
|
||||||
|
val= new_val;
|
||||||
|
}
|
||||||
|
while ((*dst++ = *p++) != 0) ;
|
||||||
|
return dst-1;
|
||||||
|
}
|
32
MySQL/is_prefix.c
Normal file
32
MySQL/is_prefix.c
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/* Copyright (C) 2000 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
/* File : is_prefix.c
|
||||||
|
Author : Michael Widenius
|
||||||
|
Defines: is_prefix()
|
||||||
|
|
||||||
|
is_prefix(s, t) returns 1 if s starts with t.
|
||||||
|
A empty t is allways a prefix.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <my_global.h>
|
||||||
|
#include "m_string.h"
|
||||||
|
|
||||||
|
int is_prefix(register const char *s, register const char *t)
|
||||||
|
{
|
||||||
|
while (*t)
|
||||||
|
if (*s++ != *t++) return 0;
|
||||||
|
return 1; /* WRONG */
|
||||||
|
}
|
5249
MySQL/libmysql.c
Normal file
5249
MySQL/libmysql.c
Normal file
File diff suppressed because it is too large
Load Diff
114
MySQL/list.c
Normal file
114
MySQL/list.c
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
/* Copyright (C) 2000 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Code for handling dubble-linked lists in C
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mysys_priv.h"
|
||||||
|
#include <my_list.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Add a element to start of list */
|
||||||
|
|
||||||
|
LIST *list_add(LIST *root, LIST *element)
|
||||||
|
{
|
||||||
|
DBUG_ENTER("list_add");
|
||||||
|
DBUG_PRINT("enter",("root: 0x%lx element: 0x%lx", (long) root, (long) element));
|
||||||
|
if (root)
|
||||||
|
{
|
||||||
|
if (root->prev) /* If add in mid of list */
|
||||||
|
root->prev->next= element;
|
||||||
|
element->prev=root->prev;
|
||||||
|
root->prev=element;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
element->prev=0;
|
||||||
|
element->next=root;
|
||||||
|
DBUG_RETURN(element); /* New root */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LIST *list_delete(LIST *root, LIST *element)
|
||||||
|
{
|
||||||
|
if (element->prev)
|
||||||
|
element->prev->next=element->next;
|
||||||
|
else
|
||||||
|
root=element->next;
|
||||||
|
if (element->next)
|
||||||
|
element->next->prev=element->prev;
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void list_free(LIST *root, uint free_data)
|
||||||
|
{
|
||||||
|
LIST *next;
|
||||||
|
while (root)
|
||||||
|
{
|
||||||
|
next=root->next;
|
||||||
|
if (free_data)
|
||||||
|
my_free((uchar*) root->data,MYF(0));
|
||||||
|
my_free((uchar*) root,MYF(0));
|
||||||
|
root=next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LIST *list_cons(void *data, LIST *list)
|
||||||
|
{
|
||||||
|
LIST *new_charset=(LIST*) my_malloc(sizeof(LIST),MYF(MY_FAE));
|
||||||
|
if (!new_charset)
|
||||||
|
return 0;
|
||||||
|
new_charset->data=data;
|
||||||
|
return list_add(list,new_charset);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LIST *list_reverse(LIST *root)
|
||||||
|
{
|
||||||
|
LIST *last;
|
||||||
|
|
||||||
|
last=root;
|
||||||
|
while (root)
|
||||||
|
{
|
||||||
|
last=root;
|
||||||
|
root=root->next;
|
||||||
|
last->next=last->prev;
|
||||||
|
last->prev=root;
|
||||||
|
}
|
||||||
|
return last;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint list_length(LIST *list)
|
||||||
|
{
|
||||||
|
uint count;
|
||||||
|
for (count=0 ; list ; list=list->next, count++) ;
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int list_walk(LIST *list, list_walk_action action, uchar* argument)
|
||||||
|
{
|
||||||
|
int error=0;
|
||||||
|
while (list)
|
||||||
|
{
|
||||||
|
if ((error = (*action)(list->data,argument)))
|
||||||
|
return error;
|
||||||
|
list=list_rest(list);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
40
MySQL/llstr.c
Normal file
40
MySQL/llstr.c
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/* Copyright (C) 2000 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Defines: llstr();
|
||||||
|
|
||||||
|
llstr(value, buff);
|
||||||
|
|
||||||
|
This function saves a longlong value in a buffer and returns the pointer to
|
||||||
|
the buffer. This is useful when trying to portable print longlong
|
||||||
|
variables with printf() as there is no usable printf() standard one can use.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <my_global.h>
|
||||||
|
#include "m_string.h"
|
||||||
|
|
||||||
|
char *llstr(longlong value,char *buff)
|
||||||
|
{
|
||||||
|
longlong10_to_str(value,buff,-10);
|
||||||
|
return buff;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *ullstr(longlong value,char *buff)
|
||||||
|
{
|
||||||
|
longlong10_to_str(value,buff,10);
|
||||||
|
return buff;
|
||||||
|
}
|
143
MySQL/longlong2str.c
Normal file
143
MySQL/longlong2str.c
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
/* Copyright (C) 2000 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Defines: longlong2str();
|
||||||
|
|
||||||
|
longlong2str(dst, radix, val)
|
||||||
|
converts the (longlong) integer "val" to character form and moves it to
|
||||||
|
the destination string "dst" followed by a terminating NUL. The
|
||||||
|
result is normally a pointer to this NUL character, but if the radix
|
||||||
|
is dud the result will be NullS and nothing will be changed.
|
||||||
|
|
||||||
|
If radix is -2..-36, val is taken to be SIGNED.
|
||||||
|
If radix is 2.. 36, val is taken to be UNSIGNED.
|
||||||
|
That is, val is signed if and only if radix is. You will normally
|
||||||
|
use radix -10 only through itoa and ltoa, for radix 2, 8, or 16
|
||||||
|
unsigned is what you generally want.
|
||||||
|
|
||||||
|
_dig_vec is public just in case someone has a use for it.
|
||||||
|
The definitions of itoa and ltoa are actually macros in m_string.h,
|
||||||
|
but this is where the code is.
|
||||||
|
|
||||||
|
Note: The standard itoa() returns a pointer to the argument, when int2str
|
||||||
|
returns the pointer to the end-null.
|
||||||
|
itoa assumes that 10 -base numbers are allways signed and other arn't.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <my_global.h>
|
||||||
|
#include "m_string.h"
|
||||||
|
|
||||||
|
#if defined(HAVE_LONG_LONG) && !defined(longlong2str) && !defined(HAVE_LONGLONG2STR)
|
||||||
|
|
||||||
|
/*
|
||||||
|
This assumes that longlong multiplication is faster than longlong division.
|
||||||
|
*/
|
||||||
|
|
||||||
|
char *longlong2str(longlong val,char *dst,int radix)
|
||||||
|
{
|
||||||
|
char buffer[65];
|
||||||
|
register char *p;
|
||||||
|
long long_val;
|
||||||
|
ulonglong uval= (ulonglong) val;
|
||||||
|
|
||||||
|
if (radix < 0)
|
||||||
|
{
|
||||||
|
if (radix < -36 || radix > -2) return (char*) 0;
|
||||||
|
if (val < 0) {
|
||||||
|
*dst++ = '-';
|
||||||
|
/* Avoid integer overflow in (-val) for LONGLONG_MIN (BUG#31799). */
|
||||||
|
uval = (ulonglong)0 - uval;
|
||||||
|
}
|
||||||
|
radix = -radix;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (radix > 36 || radix < 2) return (char*) 0;
|
||||||
|
}
|
||||||
|
if (uval == 0)
|
||||||
|
{
|
||||||
|
*dst++='0';
|
||||||
|
*dst='\0';
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
p = &buffer[sizeof(buffer)-1];
|
||||||
|
*p = '\0';
|
||||||
|
|
||||||
|
while (uval > (ulonglong) LONG_MAX)
|
||||||
|
{
|
||||||
|
ulonglong quo= uval/(uint) radix;
|
||||||
|
uint rem= (uint) (uval- quo* (uint) radix);
|
||||||
|
*--p = _dig_vec_upper[rem];
|
||||||
|
uval= quo;
|
||||||
|
}
|
||||||
|
long_val= (long) uval;
|
||||||
|
while (long_val != 0)
|
||||||
|
{
|
||||||
|
long quo= long_val/radix;
|
||||||
|
*--p = _dig_vec_upper[(uchar) (long_val - quo*radix)];
|
||||||
|
long_val= quo;
|
||||||
|
}
|
||||||
|
while ((*dst++ = *p++) != 0) ;
|
||||||
|
return dst-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef longlong10_to_str
|
||||||
|
char *longlong10_to_str(longlong val,char *dst,int radix)
|
||||||
|
{
|
||||||
|
char buffer[65];
|
||||||
|
register char *p;
|
||||||
|
long long_val;
|
||||||
|
ulonglong uval= (ulonglong) val;
|
||||||
|
|
||||||
|
if (radix < 0)
|
||||||
|
{
|
||||||
|
if (val < 0)
|
||||||
|
{
|
||||||
|
*dst++ = '-';
|
||||||
|
/* Avoid integer overflow in (-val) for LONGLONG_MIN (BUG#31799). */
|
||||||
|
uval = (ulonglong)0 - uval;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uval == 0)
|
||||||
|
{
|
||||||
|
*dst++='0';
|
||||||
|
*dst='\0';
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
p = &buffer[sizeof(buffer)-1];
|
||||||
|
*p = '\0';
|
||||||
|
|
||||||
|
while (uval > (ulonglong) LONG_MAX)
|
||||||
|
{
|
||||||
|
ulonglong quo= uval/(uint) 10;
|
||||||
|
uint rem= (uint) (uval- quo* (uint) 10);
|
||||||
|
*--p = _dig_vec_upper[rem];
|
||||||
|
uval= quo;
|
||||||
|
}
|
||||||
|
long_val= (long) uval;
|
||||||
|
while (long_val != 0)
|
||||||
|
{
|
||||||
|
long quo= long_val/10;
|
||||||
|
*--p = _dig_vec_upper[(uchar) (long_val - quo*10)];
|
||||||
|
long_val= quo;
|
||||||
|
}
|
||||||
|
while ((*dst++ = *p++) != 0) ;
|
||||||
|
return dst-1;
|
||||||
|
}
|
||||||
|
#endif
|
549
MySQL/m_ctype.h
Normal file
549
MySQL/m_ctype.h
Normal file
@ -0,0 +1,549 @@
|
|||||||
|
/* Copyright (C) 2000 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
/*
|
||||||
|
A better inplementation of the UNIX ctype(3) library.
|
||||||
|
Notes: my_global.h should be included before ctype.h
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _m_ctype_h
|
||||||
|
#define _m_ctype_h
|
||||||
|
|
||||||
|
#include <my_attribute.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MY_CS_NAME_SIZE 32
|
||||||
|
#define MY_CS_CTYPE_TABLE_SIZE 257
|
||||||
|
#define MY_CS_TO_LOWER_TABLE_SIZE 256
|
||||||
|
#define MY_CS_TO_UPPER_TABLE_SIZE 256
|
||||||
|
#define MY_CS_SORT_ORDER_TABLE_SIZE 256
|
||||||
|
#define MY_CS_TO_UNI_TABLE_SIZE 256
|
||||||
|
|
||||||
|
#define CHARSET_DIR "charsets/"
|
||||||
|
|
||||||
|
#define my_wc_t ulong
|
||||||
|
|
||||||
|
typedef struct unicase_info_st
|
||||||
|
{
|
||||||
|
uint16 toupper;
|
||||||
|
uint16 tolower;
|
||||||
|
uint16 sort;
|
||||||
|
} MY_UNICASE_INFO;
|
||||||
|
|
||||||
|
|
||||||
|
extern MY_UNICASE_INFO *my_unicase_default[256];
|
||||||
|
extern MY_UNICASE_INFO *my_unicase_turkish[256];
|
||||||
|
|
||||||
|
typedef struct uni_ctype_st
|
||||||
|
{
|
||||||
|
uchar pctype;
|
||||||
|
uchar *ctype;
|
||||||
|
} MY_UNI_CTYPE;
|
||||||
|
|
||||||
|
extern MY_UNI_CTYPE my_uni_ctype[256];
|
||||||
|
|
||||||
|
/* wm_wc and wc_mb return codes */
|
||||||
|
#define MY_CS_ILSEQ 0 /* Wrong by sequence: wb_wc */
|
||||||
|
#define MY_CS_ILUNI 0 /* Cannot encode Unicode to charset: wc_mb */
|
||||||
|
#define MY_CS_TOOSMALL -101 /* Need at least one byte: wc_mb and mb_wc */
|
||||||
|
#define MY_CS_TOOSMALL2 -102 /* Need at least two bytes: wc_mb and mb_wc */
|
||||||
|
#define MY_CS_TOOSMALL3 -103 /* Need at least three bytes: wc_mb and mb_wc */
|
||||||
|
/* These following three are currently not really used */
|
||||||
|
#define MY_CS_TOOSMALL4 -104 /* Need at least 4 bytes: wc_mb and mb_wc */
|
||||||
|
#define MY_CS_TOOSMALL5 -105 /* Need at least 5 bytes: wc_mb and mb_wc */
|
||||||
|
#define MY_CS_TOOSMALL6 -106 /* Need at least 6 bytes: wc_mb and mb_wc */
|
||||||
|
/* A helper macros for "need at least n bytes" */
|
||||||
|
#define MY_CS_TOOSMALLN(n) (-100-(n))
|
||||||
|
|
||||||
|
#define MY_SEQ_INTTAIL 1
|
||||||
|
#define MY_SEQ_SPACES 2
|
||||||
|
|
||||||
|
/* My charsets_list flags */
|
||||||
|
#define MY_CS_COMPILED 1 /* compiled-in sets */
|
||||||
|
#define MY_CS_CONFIG 2 /* sets that have a *.conf file */
|
||||||
|
#define MY_CS_INDEX 4 /* sets listed in the Index file */
|
||||||
|
#define MY_CS_LOADED 8 /* sets that are currently loaded */
|
||||||
|
#define MY_CS_BINSORT 16 /* if binary sort order */
|
||||||
|
#define MY_CS_PRIMARY 32 /* if primary collation */
|
||||||
|
#define MY_CS_STRNXFRM 64 /* if strnxfrm is used for sort */
|
||||||
|
#define MY_CS_UNICODE 128 /* is a charset is full unicode */
|
||||||
|
#define MY_CS_READY 256 /* if a charset is initialized */
|
||||||
|
#define MY_CS_AVAILABLE 512 /* If either compiled-in or loaded*/
|
||||||
|
#define MY_CS_CSSORT 1024 /* if case sensitive sort order */
|
||||||
|
#define MY_CS_HIDDEN 2048 /* don't display in SHOW */
|
||||||
|
#define MY_CS_PUREASCII 4096 /* if a charset is pure ascii */
|
||||||
|
#define MY_CHARSET_UNDEFINED 0
|
||||||
|
|
||||||
|
/* Character repertoire flags */
|
||||||
|
#define MY_REPERTOIRE_ASCII 1 /* Pure ASCII U+0000..U+007F */
|
||||||
|
#define MY_REPERTOIRE_EXTENDED 2 /* Extended characters: U+0080..U+FFFF */
|
||||||
|
#define MY_REPERTOIRE_UNICODE30 3 /* ASCII | EXTENDED: U+0000..U+FFFF */
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct my_uni_idx_st
|
||||||
|
{
|
||||||
|
uint16 from;
|
||||||
|
uint16 to;
|
||||||
|
uchar *tab;
|
||||||
|
} MY_UNI_IDX;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint beg;
|
||||||
|
uint end;
|
||||||
|
uint mb_len;
|
||||||
|
} my_match_t;
|
||||||
|
|
||||||
|
enum my_lex_states
|
||||||
|
{
|
||||||
|
MY_LEX_START, MY_LEX_CHAR, MY_LEX_IDENT,
|
||||||
|
MY_LEX_IDENT_SEP, MY_LEX_IDENT_START,
|
||||||
|
MY_LEX_REAL, MY_LEX_HEX_NUMBER, MY_LEX_BIN_NUMBER,
|
||||||
|
MY_LEX_CMP_OP, MY_LEX_LONG_CMP_OP, MY_LEX_STRING, MY_LEX_COMMENT, MY_LEX_END,
|
||||||
|
MY_LEX_OPERATOR_OR_IDENT, MY_LEX_NUMBER_IDENT, MY_LEX_INT_OR_REAL,
|
||||||
|
MY_LEX_REAL_OR_POINT, MY_LEX_BOOL, MY_LEX_EOL, MY_LEX_ESCAPE,
|
||||||
|
MY_LEX_LONG_COMMENT, MY_LEX_END_LONG_COMMENT, MY_LEX_SEMICOLON,
|
||||||
|
MY_LEX_SET_VAR, MY_LEX_USER_END, MY_LEX_HOSTNAME, MY_LEX_SKIP,
|
||||||
|
MY_LEX_USER_VARIABLE_DELIMITER, MY_LEX_SYSTEM_VAR,
|
||||||
|
MY_LEX_IDENT_OR_KEYWORD,
|
||||||
|
MY_LEX_IDENT_OR_HEX, MY_LEX_IDENT_OR_BIN, MY_LEX_IDENT_OR_NCHAR,
|
||||||
|
MY_LEX_STRING_OR_DELIMITER
|
||||||
|
};
|
||||||
|
|
||||||
|
struct charset_info_st;
|
||||||
|
|
||||||
|
|
||||||
|
/* See strings/CHARSET_INFO.txt for information about this structure */
|
||||||
|
typedef struct my_collation_handler_st
|
||||||
|
{
|
||||||
|
my_bool (*init)(struct charset_info_st *, void *(*alloc)(size_t));
|
||||||
|
/* Collation routines */
|
||||||
|
int (*strnncoll)(struct charset_info_st *,
|
||||||
|
const uchar *, size_t, const uchar *, size_t, my_bool);
|
||||||
|
int (*strnncollsp)(struct charset_info_st *,
|
||||||
|
const uchar *, size_t, const uchar *, size_t,
|
||||||
|
my_bool diff_if_only_endspace_difference);
|
||||||
|
size_t (*strnxfrm)(struct charset_info_st *,
|
||||||
|
uchar *, size_t, const uchar *, size_t);
|
||||||
|
size_t (*strnxfrmlen)(struct charset_info_st *, size_t);
|
||||||
|
my_bool (*like_range)(struct charset_info_st *,
|
||||||
|
const char *s, size_t s_length,
|
||||||
|
pchar w_prefix, pchar w_one, pchar w_many,
|
||||||
|
size_t res_length,
|
||||||
|
char *min_str, char *max_str,
|
||||||
|
size_t *min_len, size_t *max_len);
|
||||||
|
int (*wildcmp)(struct charset_info_st *,
|
||||||
|
const char *str,const char *str_end,
|
||||||
|
const char *wildstr,const char *wildend,
|
||||||
|
int escape,int w_one, int w_many);
|
||||||
|
|
||||||
|
int (*strcasecmp)(struct charset_info_st *, const char *, const char *);
|
||||||
|
|
||||||
|
uint (*instr)(struct charset_info_st *,
|
||||||
|
const char *b, size_t b_length,
|
||||||
|
const char *s, size_t s_length,
|
||||||
|
my_match_t *match, uint nmatch);
|
||||||
|
|
||||||
|
/* Hash calculation */
|
||||||
|
void (*hash_sort)(struct charset_info_st *cs, const uchar *key, size_t len,
|
||||||
|
ulong *nr1, ulong *nr2);
|
||||||
|
my_bool (*propagate)(struct charset_info_st *cs, const uchar *str, size_t len);
|
||||||
|
} MY_COLLATION_HANDLER;
|
||||||
|
|
||||||
|
extern MY_COLLATION_HANDLER my_collation_mb_bin_handler;
|
||||||
|
extern MY_COLLATION_HANDLER my_collation_8bit_bin_handler;
|
||||||
|
extern MY_COLLATION_HANDLER my_collation_8bit_simple_ci_handler;
|
||||||
|
extern MY_COLLATION_HANDLER my_collation_ucs2_uca_handler;
|
||||||
|
|
||||||
|
/* Some typedef to make it easy for C++ to make function pointers */
|
||||||
|
typedef int (*my_charset_conv_mb_wc)(struct charset_info_st *, my_wc_t *,
|
||||||
|
const uchar *, const uchar *);
|
||||||
|
typedef int (*my_charset_conv_wc_mb)(struct charset_info_st *, my_wc_t,
|
||||||
|
uchar *, uchar *);
|
||||||
|
typedef size_t (*my_charset_conv_case)(struct charset_info_st *,
|
||||||
|
char *, size_t, char *, size_t);
|
||||||
|
|
||||||
|
|
||||||
|
/* See strings/CHARSET_INFO.txt about information on this structure */
|
||||||
|
typedef struct my_charset_handler_st
|
||||||
|
{
|
||||||
|
my_bool (*init)(struct charset_info_st *, void *(*alloc)(size_t));
|
||||||
|
/* Multibyte routines */
|
||||||
|
uint (*ismbchar)(struct charset_info_st *, const char *, const char *);
|
||||||
|
uint (*mbcharlen)(struct charset_info_st *, uint c);
|
||||||
|
size_t (*numchars)(struct charset_info_st *, const char *b, const char *e);
|
||||||
|
size_t (*charpos)(struct charset_info_st *, const char *b, const char *e,
|
||||||
|
size_t pos);
|
||||||
|
size_t (*well_formed_len)(struct charset_info_st *,
|
||||||
|
const char *b,const char *e,
|
||||||
|
size_t nchars, int *error);
|
||||||
|
size_t (*lengthsp)(struct charset_info_st *, const char *ptr, size_t length);
|
||||||
|
size_t (*numcells)(struct charset_info_st *, const char *b, const char *e);
|
||||||
|
|
||||||
|
/* Unicode conversion */
|
||||||
|
my_charset_conv_mb_wc mb_wc;
|
||||||
|
my_charset_conv_wc_mb wc_mb;
|
||||||
|
|
||||||
|
/* CTYPE scanner */
|
||||||
|
int (*ctype)(struct charset_info_st *cs, int *ctype,
|
||||||
|
const uchar *s, const uchar *e);
|
||||||
|
|
||||||
|
/* Functions for case and sort conversion */
|
||||||
|
size_t (*caseup_str)(struct charset_info_st *, char *);
|
||||||
|
size_t (*casedn_str)(struct charset_info_st *, char *);
|
||||||
|
|
||||||
|
my_charset_conv_case caseup;
|
||||||
|
my_charset_conv_case casedn;
|
||||||
|
|
||||||
|
/* Charset dependant snprintf() */
|
||||||
|
size_t (*snprintf)(struct charset_info_st *, char *to, size_t n,
|
||||||
|
const char *fmt,
|
||||||
|
...) ATTRIBUTE_FORMAT_FPTR(printf, 4, 5);
|
||||||
|
size_t (*long10_to_str)(struct charset_info_st *, char *to, size_t n,
|
||||||
|
int radix, long int val);
|
||||||
|
size_t (*longlong10_to_str)(struct charset_info_st *, char *to, size_t n,
|
||||||
|
int radix, longlong val);
|
||||||
|
|
||||||
|
void (*fill)(struct charset_info_st *, char *to, size_t len, int fill);
|
||||||
|
|
||||||
|
/* String-to-number conversion routines */
|
||||||
|
long (*strntol)(struct charset_info_st *, const char *s, size_t l,
|
||||||
|
int base, char **e, int *err);
|
||||||
|
ulong (*strntoul)(struct charset_info_st *, const char *s, size_t l,
|
||||||
|
int base, char **e, int *err);
|
||||||
|
longlong (*strntoll)(struct charset_info_st *, const char *s, size_t l,
|
||||||
|
int base, char **e, int *err);
|
||||||
|
ulonglong (*strntoull)(struct charset_info_st *, const char *s, size_t l,
|
||||||
|
int base, char **e, int *err);
|
||||||
|
double (*strntod)(struct charset_info_st *, char *s, size_t l, char **e,
|
||||||
|
int *err);
|
||||||
|
longlong (*strtoll10)(struct charset_info_st *cs,
|
||||||
|
const char *nptr, char **endptr, int *error);
|
||||||
|
ulonglong (*strntoull10rnd)(struct charset_info_st *cs,
|
||||||
|
const char *str, size_t length,
|
||||||
|
int unsigned_fl,
|
||||||
|
char **endptr, int *error);
|
||||||
|
size_t (*scan)(struct charset_info_st *, const char *b, const char *e,
|
||||||
|
int sq);
|
||||||
|
} MY_CHARSET_HANDLER;
|
||||||
|
|
||||||
|
extern MY_CHARSET_HANDLER my_charset_8bit_handler;
|
||||||
|
extern MY_CHARSET_HANDLER my_charset_ucs2_handler;
|
||||||
|
|
||||||
|
|
||||||
|
/* See strings/CHARSET_INFO.txt about information on this structure */
|
||||||
|
typedef struct charset_info_st
|
||||||
|
{
|
||||||
|
uint number;
|
||||||
|
uint primary_number;
|
||||||
|
uint binary_number;
|
||||||
|
uint state;
|
||||||
|
const char *csname;
|
||||||
|
const char *name;
|
||||||
|
const char *comment;
|
||||||
|
const char *tailoring;
|
||||||
|
uchar *ctype;
|
||||||
|
uchar *to_lower;
|
||||||
|
uchar *to_upper;
|
||||||
|
uchar *sort_order;
|
||||||
|
uint16 *contractions;
|
||||||
|
uint16 **sort_order_big;
|
||||||
|
uint16 *tab_to_uni;
|
||||||
|
MY_UNI_IDX *tab_from_uni;
|
||||||
|
MY_UNICASE_INFO **caseinfo;
|
||||||
|
uchar *state_map;
|
||||||
|
uchar *ident_map;
|
||||||
|
uint strxfrm_multiply;
|
||||||
|
uchar caseup_multiply;
|
||||||
|
uchar casedn_multiply;
|
||||||
|
uint mbminlen;
|
||||||
|
uint mbmaxlen;
|
||||||
|
uint16 min_sort_char;
|
||||||
|
uint16 max_sort_char; /* For LIKE optimization */
|
||||||
|
uchar pad_char;
|
||||||
|
my_bool escape_with_backslash_is_dangerous;
|
||||||
|
|
||||||
|
MY_CHARSET_HANDLER *cset;
|
||||||
|
MY_COLLATION_HANDLER *coll;
|
||||||
|
|
||||||
|
} CHARSET_INFO;
|
||||||
|
#define ILLEGAL_CHARSET_INFO_NUMBER (~0U)
|
||||||
|
|
||||||
|
|
||||||
|
extern MYSQL_PLUGIN_IMPORT CHARSET_INFO my_charset_bin;
|
||||||
|
extern CHARSET_INFO my_charset_big5_chinese_ci;
|
||||||
|
extern CHARSET_INFO my_charset_big5_bin;
|
||||||
|
extern CHARSET_INFO my_charset_cp932_japanese_ci;
|
||||||
|
extern CHARSET_INFO my_charset_cp932_bin;
|
||||||
|
extern CHARSET_INFO my_charset_eucjpms_japanese_ci;
|
||||||
|
extern CHARSET_INFO my_charset_eucjpms_bin;
|
||||||
|
extern CHARSET_INFO my_charset_euckr_korean_ci;
|
||||||
|
extern CHARSET_INFO my_charset_euckr_bin;
|
||||||
|
extern CHARSET_INFO my_charset_gb2312_chinese_ci;
|
||||||
|
extern CHARSET_INFO my_charset_gb2312_bin;
|
||||||
|
extern CHARSET_INFO my_charset_gbk_chinese_ci;
|
||||||
|
extern CHARSET_INFO my_charset_gbk_bin;
|
||||||
|
extern MYSQL_PLUGIN_IMPORT CHARSET_INFO my_charset_latin1;
|
||||||
|
extern CHARSET_INFO my_charset_latin1_german2_ci;
|
||||||
|
extern CHARSET_INFO my_charset_latin1_bin;
|
||||||
|
extern CHARSET_INFO my_charset_latin2_czech_ci;
|
||||||
|
extern CHARSET_INFO my_charset_sjis_japanese_ci;
|
||||||
|
extern CHARSET_INFO my_charset_sjis_bin;
|
||||||
|
extern CHARSET_INFO my_charset_tis620_thai_ci;
|
||||||
|
extern CHARSET_INFO my_charset_tis620_bin;
|
||||||
|
extern CHARSET_INFO my_charset_ucs2_general_ci;
|
||||||
|
extern CHARSET_INFO my_charset_ucs2_bin;
|
||||||
|
extern CHARSET_INFO my_charset_ucs2_unicode_ci;
|
||||||
|
extern CHARSET_INFO my_charset_ujis_japanese_ci;
|
||||||
|
extern CHARSET_INFO my_charset_ujis_bin;
|
||||||
|
extern CHARSET_INFO my_charset_utf8_general_ci;
|
||||||
|
extern CHARSET_INFO my_charset_utf8_unicode_ci;
|
||||||
|
extern CHARSET_INFO my_charset_utf8_bin;
|
||||||
|
extern CHARSET_INFO my_charset_cp1250_czech_ci;
|
||||||
|
extern MYSQL_PLUGIN_IMPORT CHARSET_INFO my_charset_filename;
|
||||||
|
|
||||||
|
/* declarations for simple charsets */
|
||||||
|
extern size_t my_strnxfrm_simple(CHARSET_INFO *, uchar *, size_t,
|
||||||
|
const uchar *, size_t);
|
||||||
|
size_t my_strnxfrmlen_simple(CHARSET_INFO *, size_t);
|
||||||
|
extern int my_strnncoll_simple(CHARSET_INFO *, const uchar *, size_t,
|
||||||
|
const uchar *, size_t, my_bool);
|
||||||
|
|
||||||
|
extern int my_strnncollsp_simple(CHARSET_INFO *, const uchar *, size_t,
|
||||||
|
const uchar *, size_t,
|
||||||
|
my_bool diff_if_only_endspace_difference);
|
||||||
|
|
||||||
|
extern void my_hash_sort_simple(CHARSET_INFO *cs,
|
||||||
|
const uchar *key, size_t len,
|
||||||
|
ulong *nr1, ulong *nr2);
|
||||||
|
|
||||||
|
extern size_t my_lengthsp_8bit(CHARSET_INFO *cs, const char *ptr, size_t length);
|
||||||
|
|
||||||
|
extern uint my_instr_simple(struct charset_info_st *,
|
||||||
|
const char *b, size_t b_length,
|
||||||
|
const char *s, size_t s_length,
|
||||||
|
my_match_t *match, uint nmatch);
|
||||||
|
|
||||||
|
|
||||||
|
/* Functions for 8bit */
|
||||||
|
extern size_t my_caseup_str_8bit(CHARSET_INFO *, char *);
|
||||||
|
extern size_t my_casedn_str_8bit(CHARSET_INFO *, char *);
|
||||||
|
extern size_t my_caseup_8bit(CHARSET_INFO *, char *src, size_t srclen,
|
||||||
|
char *dst, size_t dstlen);
|
||||||
|
extern size_t my_casedn_8bit(CHARSET_INFO *, char *src, size_t srclen,
|
||||||
|
char *dst, size_t dstlen);
|
||||||
|
|
||||||
|
extern int my_strcasecmp_8bit(CHARSET_INFO * cs, const char *, const char *);
|
||||||
|
|
||||||
|
int my_mb_wc_8bit(CHARSET_INFO *cs,my_wc_t *wc, const uchar *s,const uchar *e);
|
||||||
|
int my_wc_mb_8bit(CHARSET_INFO *cs,my_wc_t wc, uchar *s, uchar *e);
|
||||||
|
|
||||||
|
int my_mb_ctype_8bit(CHARSET_INFO *,int *, const uchar *,const uchar *);
|
||||||
|
int my_mb_ctype_mb(CHARSET_INFO *,int *, const uchar *,const uchar *);
|
||||||
|
|
||||||
|
size_t my_scan_8bit(CHARSET_INFO *cs, const char *b, const char *e, int sq);
|
||||||
|
|
||||||
|
size_t my_snprintf_8bit(struct charset_info_st *, char *to, size_t n,
|
||||||
|
const char *fmt, ...)
|
||||||
|
ATTRIBUTE_FORMAT(printf, 4, 5);
|
||||||
|
|
||||||
|
long my_strntol_8bit(CHARSET_INFO *, const char *s, size_t l, int base,
|
||||||
|
char **e, int *err);
|
||||||
|
ulong my_strntoul_8bit(CHARSET_INFO *, const char *s, size_t l, int base,
|
||||||
|
char **e, int *err);
|
||||||
|
longlong my_strntoll_8bit(CHARSET_INFO *, const char *s, size_t l, int base,
|
||||||
|
char **e, int *err);
|
||||||
|
ulonglong my_strntoull_8bit(CHARSET_INFO *, const char *s, size_t l, int base,
|
||||||
|
char **e, int *err);
|
||||||
|
double my_strntod_8bit(CHARSET_INFO *, char *s, size_t l,char **e,
|
||||||
|
int *err);
|
||||||
|
size_t my_long10_to_str_8bit(CHARSET_INFO *, char *to, size_t l, int radix,
|
||||||
|
long int val);
|
||||||
|
size_t my_longlong10_to_str_8bit(CHARSET_INFO *, char *to, size_t l, int radix,
|
||||||
|
longlong val);
|
||||||
|
|
||||||
|
longlong my_strtoll10_8bit(CHARSET_INFO *cs,
|
||||||
|
const char *nptr, char **endptr, int *error);
|
||||||
|
longlong my_strtoll10_ucs2(CHARSET_INFO *cs,
|
||||||
|
const char *nptr, char **endptr, int *error);
|
||||||
|
|
||||||
|
ulonglong my_strntoull10rnd_8bit(CHARSET_INFO *cs,
|
||||||
|
const char *str, size_t length, int
|
||||||
|
unsigned_fl, char **endptr, int *error);
|
||||||
|
ulonglong my_strntoull10rnd_ucs2(CHARSET_INFO *cs,
|
||||||
|
const char *str, size_t length,
|
||||||
|
int unsigned_fl, char **endptr, int *error);
|
||||||
|
|
||||||
|
void my_fill_8bit(CHARSET_INFO *cs, char* to, size_t l, int fill);
|
||||||
|
|
||||||
|
my_bool my_like_range_simple(CHARSET_INFO *cs,
|
||||||
|
const char *ptr, size_t ptr_length,
|
||||||
|
pbool escape, pbool w_one, pbool w_many,
|
||||||
|
size_t res_length,
|
||||||
|
char *min_str, char *max_str,
|
||||||
|
size_t *min_length, size_t *max_length);
|
||||||
|
|
||||||
|
my_bool my_like_range_mb(CHARSET_INFO *cs,
|
||||||
|
const char *ptr, size_t ptr_length,
|
||||||
|
pbool escape, pbool w_one, pbool w_many,
|
||||||
|
size_t res_length,
|
||||||
|
char *min_str, char *max_str,
|
||||||
|
size_t *min_length, size_t *max_length);
|
||||||
|
|
||||||
|
my_bool my_like_range_ucs2(CHARSET_INFO *cs,
|
||||||
|
const char *ptr, size_t ptr_length,
|
||||||
|
pbool escape, pbool w_one, pbool w_many,
|
||||||
|
size_t res_length,
|
||||||
|
char *min_str, char *max_str,
|
||||||
|
size_t *min_length, size_t *max_length);
|
||||||
|
|
||||||
|
|
||||||
|
int my_wildcmp_8bit(CHARSET_INFO *,
|
||||||
|
const char *str,const char *str_end,
|
||||||
|
const char *wildstr,const char *wildend,
|
||||||
|
int escape, int w_one, int w_many);
|
||||||
|
|
||||||
|
int my_wildcmp_bin(CHARSET_INFO *,
|
||||||
|
const char *str,const char *str_end,
|
||||||
|
const char *wildstr,const char *wildend,
|
||||||
|
int escape, int w_one, int w_many);
|
||||||
|
|
||||||
|
size_t my_numchars_8bit(CHARSET_INFO *, const char *b, const char *e);
|
||||||
|
size_t my_numcells_8bit(CHARSET_INFO *, const char *b, const char *e);
|
||||||
|
size_t my_charpos_8bit(CHARSET_INFO *, const char *b, const char *e, size_t pos);
|
||||||
|
size_t my_well_formed_len_8bit(CHARSET_INFO *, const char *b, const char *e,
|
||||||
|
size_t pos, int *error);
|
||||||
|
uint my_mbcharlen_8bit(CHARSET_INFO *, uint c);
|
||||||
|
|
||||||
|
|
||||||
|
/* Functions for multibyte charsets */
|
||||||
|
extern size_t my_caseup_str_mb(CHARSET_INFO *, char *);
|
||||||
|
extern size_t my_casedn_str_mb(CHARSET_INFO *, char *);
|
||||||
|
extern size_t my_caseup_mb(CHARSET_INFO *, char *src, size_t srclen,
|
||||||
|
char *dst, size_t dstlen);
|
||||||
|
extern size_t my_casedn_mb(CHARSET_INFO *, char *src, size_t srclen,
|
||||||
|
char *dst, size_t dstlen);
|
||||||
|
extern int my_strcasecmp_mb(CHARSET_INFO * cs,const char *, const char *);
|
||||||
|
|
||||||
|
int my_wildcmp_mb(CHARSET_INFO *,
|
||||||
|
const char *str,const char *str_end,
|
||||||
|
const char *wildstr,const char *wildend,
|
||||||
|
int escape, int w_one, int w_many);
|
||||||
|
size_t my_numchars_mb(CHARSET_INFO *, const char *b, const char *e);
|
||||||
|
size_t my_numcells_mb(CHARSET_INFO *, const char *b, const char *e);
|
||||||
|
size_t my_charpos_mb(CHARSET_INFO *, const char *b, const char *e, size_t pos);
|
||||||
|
size_t my_well_formed_len_mb(CHARSET_INFO *, const char *b, const char *e,
|
||||||
|
size_t pos, int *error);
|
||||||
|
uint my_instr_mb(struct charset_info_st *,
|
||||||
|
const char *b, size_t b_length,
|
||||||
|
const char *s, size_t s_length,
|
||||||
|
my_match_t *match, uint nmatch);
|
||||||
|
|
||||||
|
int my_wildcmp_unicode(CHARSET_INFO *cs,
|
||||||
|
const char *str, const char *str_end,
|
||||||
|
const char *wildstr, const char *wildend,
|
||||||
|
int escape, int w_one, int w_many,
|
||||||
|
MY_UNICASE_INFO **weights);
|
||||||
|
|
||||||
|
extern my_bool my_parse_charset_xml(const char *bug, size_t len,
|
||||||
|
int (*add)(CHARSET_INFO *cs));
|
||||||
|
extern char *my_strchr(CHARSET_INFO *cs, const char *str, const char *end,
|
||||||
|
pchar c);
|
||||||
|
|
||||||
|
my_bool my_propagate_simple(CHARSET_INFO *cs, const uchar *str, size_t len);
|
||||||
|
my_bool my_propagate_complex(CHARSET_INFO *cs, const uchar *str, size_t len);
|
||||||
|
|
||||||
|
|
||||||
|
uint my_string_repertoire(CHARSET_INFO *cs, const char *str, ulong len);
|
||||||
|
my_bool my_charset_is_ascii_based(CHARSET_INFO *cs);
|
||||||
|
my_bool my_charset_is_8bit_pure_ascii(CHARSET_INFO *cs);
|
||||||
|
uint my_charset_repertoire(CHARSET_INFO *cs);
|
||||||
|
|
||||||
|
|
||||||
|
#define _MY_U 01 /* Upper case */
|
||||||
|
#define _MY_L 02 /* Lower case */
|
||||||
|
#define _MY_NMR 04 /* Numeral (digit) */
|
||||||
|
#define _MY_SPC 010 /* Spacing character */
|
||||||
|
#define _MY_PNT 020 /* Punctuation */
|
||||||
|
#define _MY_CTR 040 /* Control character */
|
||||||
|
#define _MY_B 0100 /* Blank */
|
||||||
|
#define _MY_X 0200 /* heXadecimal digit */
|
||||||
|
|
||||||
|
|
||||||
|
#define my_isascii(c) (!((c) & ~0177))
|
||||||
|
#define my_toascii(c) ((c) & 0177)
|
||||||
|
#define my_tocntrl(c) ((c) & 31)
|
||||||
|
#define my_toprint(c) ((c) | 64)
|
||||||
|
#define my_toupper(s,c) (char) ((s)->to_upper[(uchar) (c)])
|
||||||
|
#define my_tolower(s,c) (char) ((s)->to_lower[(uchar) (c)])
|
||||||
|
#define my_isalpha(s, c) (((s)->ctype+1)[(uchar) (c)] & (_MY_U | _MY_L))
|
||||||
|
#define my_isupper(s, c) (((s)->ctype+1)[(uchar) (c)] & _MY_U)
|
||||||
|
#define my_islower(s, c) (((s)->ctype+1)[(uchar) (c)] & _MY_L)
|
||||||
|
#define my_isdigit(s, c) (((s)->ctype+1)[(uchar) (c)] & _MY_NMR)
|
||||||
|
#define my_isxdigit(s, c) (((s)->ctype+1)[(uchar) (c)] & _MY_X)
|
||||||
|
#define my_isalnum(s, c) (((s)->ctype+1)[(uchar) (c)] & (_MY_U | _MY_L | _MY_NMR))
|
||||||
|
#define my_isspace(s, c) (((s)->ctype+1)[(uchar) (c)] & _MY_SPC)
|
||||||
|
#define my_ispunct(s, c) (((s)->ctype+1)[(uchar) (c)] & _MY_PNT)
|
||||||
|
#define my_isprint(s, c) (((s)->ctype+1)[(uchar) (c)] & (_MY_PNT | _MY_U | _MY_L | _MY_NMR | _MY_B))
|
||||||
|
#define my_isgraph(s, c) (((s)->ctype+1)[(uchar) (c)] & (_MY_PNT | _MY_U | _MY_L | _MY_NMR))
|
||||||
|
#define my_iscntrl(s, c) (((s)->ctype+1)[(uchar) (c)] & _MY_CTR)
|
||||||
|
|
||||||
|
/* Some macros that should be cleaned up a little */
|
||||||
|
#define my_isvar(s,c) (my_isalnum(s,c) || (c) == '_')
|
||||||
|
#define my_isvar_start(s,c) (my_isalpha(s,c) || (c) == '_')
|
||||||
|
|
||||||
|
#define my_binary_compare(s) ((s)->state & MY_CS_BINSORT)
|
||||||
|
#define use_strnxfrm(s) ((s)->state & MY_CS_STRNXFRM)
|
||||||
|
#define my_strnxfrm(s, a, b, c, d) ((s)->coll->strnxfrm((s), (a), (b), (c), (d)))
|
||||||
|
#define my_strnncoll(s, a, b, c, d) ((s)->coll->strnncoll((s), (a), (b), (c), (d), 0))
|
||||||
|
#define my_like_range(s, a, b, c, d, e, f, g, h, i, j) \
|
||||||
|
((s)->coll->like_range((s), (a), (b), (c), (d), (e), (f), (g), (h), (i), (j)))
|
||||||
|
#define my_wildcmp(cs,s,se,w,we,e,o,m) ((cs)->coll->wildcmp((cs),(s),(se),(w),(we),(e),(o),(m)))
|
||||||
|
#define my_strcasecmp(s, a, b) ((s)->coll->strcasecmp((s), (a), (b)))
|
||||||
|
#define my_charpos(cs, b, e, num) (cs)->cset->charpos((cs), (const char*) (b), (const char *)(e), (num))
|
||||||
|
|
||||||
|
|
||||||
|
#define use_mb(s) ((s)->cset->ismbchar != NULL)
|
||||||
|
#define my_ismbchar(s, a, b) ((s)->cset->ismbchar((s), (a), (b)))
|
||||||
|
#ifdef USE_MB
|
||||||
|
#define my_mbcharlen(s, a) ((s)->cset->mbcharlen((s),(a)))
|
||||||
|
#else
|
||||||
|
#define my_mbcharlen(s, a) 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define my_caseup_str(s, a) ((s)->cset->caseup_str((s), (a)))
|
||||||
|
#define my_casedn_str(s, a) ((s)->cset->casedn_str((s), (a)))
|
||||||
|
#define my_strntol(s, a, b, c, d, e) ((s)->cset->strntol((s),(a),(b),(c),(d),(e)))
|
||||||
|
#define my_strntoul(s, a, b, c, d, e) ((s)->cset->strntoul((s),(a),(b),(c),(d),(e)))
|
||||||
|
#define my_strntoll(s, a, b, c, d, e) ((s)->cset->strntoll((s),(a),(b),(c),(d),(e)))
|
||||||
|
#define my_strntoull(s, a, b, c,d, e) ((s)->cset->strntoull((s),(a),(b),(c),(d),(e)))
|
||||||
|
#define my_strntod(s, a, b, c, d) ((s)->cset->strntod((s),(a),(b),(c),(d)))
|
||||||
|
|
||||||
|
|
||||||
|
/* XXX: still need to take care of this one */
|
||||||
|
#ifdef MY_CHARSET_TIS620
|
||||||
|
#error The TIS620 charset is broken at the moment. Tell tim to fix it.
|
||||||
|
#define USE_TIS620
|
||||||
|
#include "t_ctype.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _m_ctype_h */
|
269
MySQL/m_string.h
Normal file
269
MySQL/m_string.h
Normal file
@ -0,0 +1,269 @@
|
|||||||
|
/* Copyright (C) 2000 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
/* There may be prolems include all of theese. Try to test in
|
||||||
|
configure with ones are needed? */
|
||||||
|
|
||||||
|
/* This is needed for the definitions of strchr... on solaris */
|
||||||
|
|
||||||
|
#ifndef _m_string_h
|
||||||
|
#define _m_string_h
|
||||||
|
#ifndef __USE_GNU
|
||||||
|
#define __USE_GNU /* We want to use stpcpy */
|
||||||
|
#endif
|
||||||
|
#if defined(HAVE_STRINGS_H)
|
||||||
|
#include <strings.h>
|
||||||
|
#endif
|
||||||
|
#if defined(HAVE_STRING_H)
|
||||||
|
#include <string.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* need by my_vsnprintf */
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#ifdef _AIX
|
||||||
|
#undef HAVE_BCMP
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* This is needed for the definitions of bzero... on solaris */
|
||||||
|
#if defined(HAVE_STRINGS_H)
|
||||||
|
#include <strings.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* This is needed for the definitions of memcpy... on solaris */
|
||||||
|
#if defined(HAVE_MEMORY_H) && !defined(__cplusplus)
|
||||||
|
#include <memory.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(HAVE_MEMCPY) && !defined(HAVE_MEMMOVE)
|
||||||
|
# define memcpy(d, s, n) bcopy ((s), (d), (n))
|
||||||
|
# define memset(A,C,B) bfill((A),(B),(C))
|
||||||
|
# define memmove(d, s, n) bmove ((d), (s), (n))
|
||||||
|
#elif defined(HAVE_MEMMOVE)
|
||||||
|
# define bmove(d, s, n) memmove((d), (s), (n))
|
||||||
|
#else
|
||||||
|
# define memmove(d, s, n) bmove((d), (s), (n)) /* our bmove */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Unixware 7 */
|
||||||
|
#if !defined(HAVE_BFILL)
|
||||||
|
# define bfill(A,B,C) memset((A),(C),(B))
|
||||||
|
# define bmove_align(A,B,C) memcpy((A),(B),(C))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(HAVE_BCMP)
|
||||||
|
# define bcopy(s, d, n) memcpy((d), (s), (n))
|
||||||
|
# define bcmp(A,B,C) memcmp((A),(B),(C))
|
||||||
|
# define bzero(A,B) memset((A),0,(B))
|
||||||
|
# define bmove_align(A,B,C) memcpy((A),(B),(C))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
my_str_malloc() and my_str_free() are assigned to implementations in
|
||||||
|
strings/alloc.c, but can be overridden in the calling program.
|
||||||
|
*/
|
||||||
|
extern void *(*my_str_malloc)(size_t);
|
||||||
|
extern void (*my_str_free)(void *);
|
||||||
|
|
||||||
|
#if defined(HAVE_STPCPY)
|
||||||
|
#define strmov(A,B) stpcpy((A),(B))
|
||||||
|
#ifndef stpcpy
|
||||||
|
extern char *stpcpy(char *, const char *); /* For AIX with gcc 2.95.3 */
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Declared in int2str() */
|
||||||
|
extern char NEAR _dig_vec_upper[];
|
||||||
|
extern char NEAR _dig_vec_lower[];
|
||||||
|
|
||||||
|
/* Defined in strtod.c */
|
||||||
|
extern const double log_10[309];
|
||||||
|
|
||||||
|
#ifdef BAD_STRING_COMPILER
|
||||||
|
#define strmov(A,B) (memccpy(A,B,0,INT_MAX)-1)
|
||||||
|
#else
|
||||||
|
#define strmov_overlapp(A,B) strmov(A,B)
|
||||||
|
#define strmake_overlapp(A,B,C) strmake(A,B,C)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef BAD_MEMCPY /* Problem with gcc on Alpha */
|
||||||
|
#define memcpy_fixed(A,B,C) bmove((A),(B),(C))
|
||||||
|
#else
|
||||||
|
#define memcpy_fixed(A,B,C) memcpy((A),(B),(C))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (!defined(USE_BMOVE512) || defined(HAVE_purify)) && !defined(bmove512)
|
||||||
|
#define bmove512(A,B,C) memcpy(A,B,C)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Prototypes for string functions */
|
||||||
|
|
||||||
|
#if !defined(bfill) && !defined(HAVE_BFILL)
|
||||||
|
extern void bfill(uchar *dst,size_t len,pchar fill);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(bzero) && !defined(HAVE_BZERO)
|
||||||
|
extern void bzero(uchar * dst,size_t len);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(bcmp) && !defined(HAVE_BCMP)
|
||||||
|
extern size_t bcmp(const uchar *s1,const uchar *s2,size_t len);
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_purify
|
||||||
|
extern size_t my_bcmp(const uchar *s1,const uchar *s2,size_t len);
|
||||||
|
#undef bcmp
|
||||||
|
#define bcmp(A,B,C) my_bcmp((A),(B),(C))
|
||||||
|
#define bzero_if_purify(A,B) bzero(A,B)
|
||||||
|
#else
|
||||||
|
#define bzero_if_purify(A,B)
|
||||||
|
#endif /* HAVE_purify */
|
||||||
|
|
||||||
|
#ifndef bmove512
|
||||||
|
extern void bmove512(uchar *dst,const uchar *src,size_t len);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(HAVE_BMOVE) && !defined(bmove)
|
||||||
|
extern void bmove(uuchar *dst, const uchar *src,size_t len);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern void bmove_upp(uchar *dst,const uchar *src,size_t len);
|
||||||
|
extern void bchange(uchar *dst,size_t old_len,const uchar *src,
|
||||||
|
size_t new_len,size_t tot_len);
|
||||||
|
extern void strappend(char *s,size_t len,pchar fill);
|
||||||
|
extern char *strend(const char *s);
|
||||||
|
extern char *strcend(const char *, pchar);
|
||||||
|
extern char *strfield(char *src,int fields,int chars,int blanks,
|
||||||
|
int tabch);
|
||||||
|
extern char *strfill(char * s,size_t len,pchar fill);
|
||||||
|
extern size_t strinstr(const char *str,const char *search);
|
||||||
|
extern size_t r_strinstr(const char *str, size_t from, const char *search);
|
||||||
|
extern char *strkey(char *dst,char *head,char *tail,char *flags);
|
||||||
|
extern char *strmake(char *dst,const char *src,size_t length);
|
||||||
|
#ifndef strmake_overlapp
|
||||||
|
extern char *strmake_overlapp(char *dst,const char *src, size_t length);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef strmov
|
||||||
|
extern char *strmov(char *dst,const char *src);
|
||||||
|
#endif
|
||||||
|
extern char *strnmov(char *dst,const char *src,size_t n);
|
||||||
|
extern char *strsuff(const char *src,const char *suffix);
|
||||||
|
extern char *strcont(const char *src,const char *set);
|
||||||
|
extern char *strxcat _VARARGS((char *dst,const char *src, ...));
|
||||||
|
extern char *strxmov _VARARGS((char *dst,const char *src, ...));
|
||||||
|
extern char *strxcpy _VARARGS((char *dst,const char *src, ...));
|
||||||
|
extern char *strxncat _VARARGS((char *dst,size_t len, const char *src, ...));
|
||||||
|
extern char *strxnmov _VARARGS((char *dst,size_t len, const char *src, ...));
|
||||||
|
extern char *strxncpy _VARARGS((char *dst,size_t len, const char *src, ...));
|
||||||
|
|
||||||
|
/* Prototypes of normal stringfunctions (with may ours) */
|
||||||
|
|
||||||
|
#ifdef WANT_STRING_PROTOTYPES
|
||||||
|
extern char *strcat(char *, const char *);
|
||||||
|
extern char *strchr(const char *, pchar);
|
||||||
|
extern char *strrchr(const char *, pchar);
|
||||||
|
extern char *strcpy(char *, const char *);
|
||||||
|
extern int strcmp(const char *, const char *);
|
||||||
|
#ifndef __GNUC__
|
||||||
|
extern size_t strlen(const char *);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#ifndef HAVE_STRNLEN
|
||||||
|
extern size_t strnlen(const char *s, size_t n);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(__cplusplus)
|
||||||
|
#ifndef HAVE_STRPBRK
|
||||||
|
extern char *strpbrk(const char *, const char *);
|
||||||
|
#endif
|
||||||
|
#ifndef HAVE_STRSTR
|
||||||
|
extern char *strstr(const char *, const char *);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
extern int is_prefix(const char *, const char *);
|
||||||
|
|
||||||
|
/* Conversion routines */
|
||||||
|
double my_strtod(const char *str, char **end, int *error);
|
||||||
|
double my_atof(const char *nptr);
|
||||||
|
|
||||||
|
extern char *llstr(longlong value,char *buff);
|
||||||
|
extern char *ullstr(longlong value,char *buff);
|
||||||
|
#ifndef HAVE_STRTOUL
|
||||||
|
extern long strtol(const char *str, char **ptr, int base);
|
||||||
|
extern ulong strtoul(const char *str, char **ptr, int base);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern char *int2str(long val, char *dst, int radix, int upcase);
|
||||||
|
extern char *int10_to_str(long val,char *dst,int radix);
|
||||||
|
extern char *str2int(const char *src,int radix,long lower,long upper,
|
||||||
|
long *val);
|
||||||
|
longlong my_strtoll10(const char *nptr, char **endptr, int *error);
|
||||||
|
#if SIZEOF_LONG == SIZEOF_LONG_LONG
|
||||||
|
#define longlong2str(A,B,C) int2str((A),(B),(C),1)
|
||||||
|
#define longlong10_to_str(A,B,C) int10_to_str((A),(B),(C))
|
||||||
|
#undef strtoll
|
||||||
|
#define strtoll(A,B,C) strtol((A),(B),(C))
|
||||||
|
#define strtoull(A,B,C) strtoul((A),(B),(C))
|
||||||
|
#ifndef HAVE_STRTOULL
|
||||||
|
#define HAVE_STRTOULL
|
||||||
|
#endif
|
||||||
|
#ifndef HAVE_STRTOLL
|
||||||
|
#define HAVE_STRTOLL
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_LONG_LONG
|
||||||
|
extern char *longlong2str(longlong val,char *dst,int radix);
|
||||||
|
extern char *longlong10_to_str(longlong val,char *dst,int radix);
|
||||||
|
#if (!defined(HAVE_STRTOULL) || defined(NO_STRTOLL_PROTO))
|
||||||
|
extern longlong strtoll(const char *str, char **ptr, int base);
|
||||||
|
extern ulonglong strtoull(const char *str, char **ptr, int base);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* my_vsnprintf.c */
|
||||||
|
|
||||||
|
extern size_t my_vsnprintf(char *str, size_t n,
|
||||||
|
const char *format, va_list ap);
|
||||||
|
extern size_t my_snprintf(char *to, size_t n, const char *fmt, ...)
|
||||||
|
ATTRIBUTE_FORMAT(printf, 3, 4);
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
LEX_STRING -- a pair of a C-string and its length.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _my_plugin_h
|
||||||
|
/* This definition must match the one given in mysql/plugin.h */
|
||||||
|
struct st_mysql_lex_string
|
||||||
|
{
|
||||||
|
char *str;
|
||||||
|
size_t length;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
typedef struct st_mysql_lex_string LEX_STRING;
|
||||||
|
|
||||||
|
#define STRING_WITH_LEN(X) (X), ((size_t) (sizeof(X) - 1))
|
||||||
|
#define USTRING_WITH_LEN(X) ((uchar*) X), ((size_t) (sizeof(X) - 1))
|
||||||
|
#define C_STRING_WITH_LEN(X) ((char *) (X)), ((size_t) (sizeof(X) - 1))
|
||||||
|
|
||||||
|
#endif
|
269
MySQL/manager.c
Normal file
269
MySQL/manager.c
Normal file
@ -0,0 +1,269 @@
|
|||||||
|
/* Copyright (C) 2000-2004 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation.
|
||||||
|
|
||||||
|
There are special exceptions to the terms and conditions of the GPL as it
|
||||||
|
is applied to this software. View the full text of the exception in file
|
||||||
|
EXCEPTIONS-CLIENT in the directory of this software distribution.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
#include <my_global.h>
|
||||||
|
#if defined(THREAD)
|
||||||
|
#include <my_pthread.h> /* because of signal() */
|
||||||
|
#endif
|
||||||
|
#include "mysql.h"
|
||||||
|
#include "mysql_version.h"
|
||||||
|
#include "mysqld_error.h"
|
||||||
|
#include <my_sys.h>
|
||||||
|
#include <mysys_err.h>
|
||||||
|
#include <m_string.h>
|
||||||
|
#include <m_ctype.h>
|
||||||
|
#include <my_net.h>
|
||||||
|
#include <errmsg.h>
|
||||||
|
#include <violite.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#if defined(__NETWARE__)
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <sys/select.h>
|
||||||
|
#include <sys/utsname.h>
|
||||||
|
#elif !defined( __WIN__)
|
||||||
|
#include <sys/resource.h>
|
||||||
|
#ifdef HAVE_SYS_UN_H
|
||||||
|
# include <sys/un.h>
|
||||||
|
#endif
|
||||||
|
#include <netdb.h>
|
||||||
|
#ifdef HAVE_SELECT_H
|
||||||
|
# include <select.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SYS_SELECT_H
|
||||||
|
#include <sys/select.h>
|
||||||
|
#endif
|
||||||
|
#include <sys/utsname.h>
|
||||||
|
#endif /* __WIN__ */
|
||||||
|
|
||||||
|
#ifndef INADDR_NONE
|
||||||
|
#define INADDR_NONE -1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define RES_BUF_SHIFT 5
|
||||||
|
#define NET_BUF_SIZE 2048
|
||||||
|
|
||||||
|
MYSQL_MANAGER* STDCALL mysql_manager_init(MYSQL_MANAGER* con)
|
||||||
|
{
|
||||||
|
int net_buf_size=NET_BUF_SIZE;
|
||||||
|
if (!con)
|
||||||
|
{
|
||||||
|
if (!(con=(MYSQL_MANAGER*)my_malloc(sizeof(*con)+net_buf_size,
|
||||||
|
MYF(MY_WME|MY_ZEROFILL))))
|
||||||
|
return 0;
|
||||||
|
con->free_me=1;
|
||||||
|
con->net_buf=(char*)con+sizeof(*con);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bzero((char*)con,sizeof(*con));
|
||||||
|
if (!(con->net_buf=my_malloc(net_buf_size,MYF(0))))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
con->net_buf_pos=con->net_data_end=con->net_buf;
|
||||||
|
con->net_buf_size=net_buf_size;
|
||||||
|
return con;
|
||||||
|
}
|
||||||
|
|
||||||
|
MYSQL_MANAGER* STDCALL mysql_manager_connect(MYSQL_MANAGER* con,
|
||||||
|
const char* host,
|
||||||
|
const char* user,
|
||||||
|
const char* passwd,
|
||||||
|
unsigned int port)
|
||||||
|
{
|
||||||
|
my_socket sock;
|
||||||
|
struct sockaddr_in sock_addr;
|
||||||
|
in_addr_t ip_addr;
|
||||||
|
char msg_buf[MAX_MYSQL_MANAGER_MSG];
|
||||||
|
int msg_len;
|
||||||
|
Vio* vio;
|
||||||
|
my_bool not_used;
|
||||||
|
|
||||||
|
if (!host)
|
||||||
|
host="localhost";
|
||||||
|
if (!user)
|
||||||
|
user="root";
|
||||||
|
if (!passwd)
|
||||||
|
passwd="";
|
||||||
|
|
||||||
|
if ((sock=(my_socket)socket(AF_INET,SOCK_STREAM,0)) == INVALID_SOCKET)
|
||||||
|
{
|
||||||
|
con->last_errno=errno;
|
||||||
|
strmov(con->last_error,"Cannot create socket");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
if (!(vio=vio_new(sock,VIO_TYPE_TCPIP,FALSE)))
|
||||||
|
{
|
||||||
|
con->last_errno=ENOMEM;
|
||||||
|
strmov(con->last_error,"Cannot create network I/O object");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
vio_blocking(vio, TRUE, ¬_used);
|
||||||
|
my_net_init(&con->net,vio);
|
||||||
|
bzero((char*) &sock_addr,sizeof(sock_addr));
|
||||||
|
sock_addr.sin_family = AF_INET;
|
||||||
|
if ((int) (ip_addr = inet_addr(host)) != (int) INADDR_NONE)
|
||||||
|
{
|
||||||
|
memcpy_fixed(&sock_addr.sin_addr,&ip_addr,sizeof(ip_addr));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int tmp_errno;
|
||||||
|
struct hostent tmp_hostent,*hp;
|
||||||
|
char buff2[GETHOSTBYNAME_BUFF_SIZE];
|
||||||
|
hp = my_gethostbyname_r(host,&tmp_hostent,buff2,sizeof(buff2),
|
||||||
|
&tmp_errno);
|
||||||
|
if (!hp)
|
||||||
|
{
|
||||||
|
con->last_errno=tmp_errno;
|
||||||
|
sprintf(con->last_error,"Could not resolve host '%-.64s'",host);
|
||||||
|
my_gethostbyname_r_free();
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
memcpy(&sock_addr.sin_addr,hp->h_addr, (size_t) hp->h_length);
|
||||||
|
my_gethostbyname_r_free();
|
||||||
|
}
|
||||||
|
sock_addr.sin_port = (ushort) htons((ushort) port);
|
||||||
|
if (my_connect(sock,(struct sockaddr *) &sock_addr, sizeof(sock_addr),
|
||||||
|
0))
|
||||||
|
{
|
||||||
|
con->last_errno=errno;
|
||||||
|
sprintf(con->last_error ,"Could not connect to %-.64s", host);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
/* read the greating */
|
||||||
|
if (my_net_read(&con->net) == packet_error)
|
||||||
|
{
|
||||||
|
con->last_errno=errno;
|
||||||
|
strmov(con->last_error,"Read error on socket");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
sprintf(msg_buf,"%-.16s %-.16s\n",user,passwd);
|
||||||
|
msg_len=strlen(msg_buf);
|
||||||
|
if (my_net_write(&con->net,(uchar*) msg_buf,msg_len) || net_flush(&con->net))
|
||||||
|
{
|
||||||
|
con->last_errno=con->net.last_errno;
|
||||||
|
strmov(con->last_error,"Write error on socket");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
if (my_net_read(&con->net) == packet_error)
|
||||||
|
{
|
||||||
|
con->last_errno=errno;
|
||||||
|
strmov(con->last_error,"Read error on socket");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
if ((con->cmd_status=atoi((char*) con->net.read_pos)) != MANAGER_OK)
|
||||||
|
{
|
||||||
|
strmov(con->last_error,"Access denied");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
if (!my_multi_malloc(MYF(0), &con->host, (uint)strlen(host)+1,
|
||||||
|
&con->user, (uint)strlen(user)+1,
|
||||||
|
&con->passwd, (uint)strlen(passwd)+1,
|
||||||
|
NullS))
|
||||||
|
{
|
||||||
|
con->last_errno=ENOMEM;
|
||||||
|
strmov(con->last_error,"Out of memory");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
strmov(con->host,host);
|
||||||
|
strmov(con->user,user);
|
||||||
|
strmov(con->passwd,passwd);
|
||||||
|
return con;
|
||||||
|
|
||||||
|
err:
|
||||||
|
{
|
||||||
|
my_bool free_me=con->free_me;
|
||||||
|
con->free_me=0;
|
||||||
|
mysql_manager_close(con);
|
||||||
|
con->free_me=free_me;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void STDCALL mysql_manager_close(MYSQL_MANAGER* con)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
No need to free con->user and con->passwd, because they were
|
||||||
|
allocated in my_multimalloc() along with con->host, freeing
|
||||||
|
con->hosts frees the whole block
|
||||||
|
*/
|
||||||
|
my_free((uchar*)con->host,MYF(MY_ALLOW_ZERO_PTR));
|
||||||
|
net_end(&con->net);
|
||||||
|
if (con->free_me)
|
||||||
|
my_free((uchar*)con,MYF(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int STDCALL mysql_manager_command(MYSQL_MANAGER* con,const char* cmd,
|
||||||
|
int cmd_len)
|
||||||
|
{
|
||||||
|
if (!cmd_len)
|
||||||
|
cmd_len=strlen(cmd);
|
||||||
|
if (my_net_write(&con->net,(const uchar*)cmd,cmd_len) || net_flush(&con->net))
|
||||||
|
{
|
||||||
|
con->last_errno=errno;
|
||||||
|
strmov(con->last_error,"Write error on socket");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
con->eof=0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int STDCALL mysql_manager_fetch_line(MYSQL_MANAGER* con, char* res_buf,
|
||||||
|
int res_buf_size)
|
||||||
|
{
|
||||||
|
char* res_buf_end=res_buf+res_buf_size;
|
||||||
|
char* net_buf=(char*) con->net.read_pos, *net_buf_end;
|
||||||
|
int res_buf_shift=RES_BUF_SHIFT;
|
||||||
|
ulong num_bytes;
|
||||||
|
|
||||||
|
if (res_buf_size<RES_BUF_SHIFT)
|
||||||
|
{
|
||||||
|
con->last_errno=ENOMEM;
|
||||||
|
strmov(con->last_error,"Result buffer too small");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((num_bytes=my_net_read(&con->net)) == packet_error)
|
||||||
|
{
|
||||||
|
con->last_errno=errno;
|
||||||
|
strmov(con->last_error,"socket read failed");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
net_buf_end=net_buf+num_bytes;
|
||||||
|
|
||||||
|
if ((con->eof=(net_buf[3]==' ')))
|
||||||
|
res_buf_shift--;
|
||||||
|
net_buf+=res_buf_shift;
|
||||||
|
res_buf_end[-1]=0;
|
||||||
|
for (;net_buf<net_buf_end && res_buf < res_buf_end;res_buf++,net_buf++)
|
||||||
|
{
|
||||||
|
if ((*res_buf=*net_buf) == '\r')
|
||||||
|
{
|
||||||
|
*res_buf=0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
325
MySQL/md5.c
Normal file
325
MySQL/md5.c
Normal file
@ -0,0 +1,325 @@
|
|||||||
|
/* Copyright (C) 2000 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This code implements the MD5 message-digest algorithm.
|
||||||
|
* The algorithm is due to Ron Rivest. This code was
|
||||||
|
* written by Colin Plumb in 1993, no copyright is claimed.
|
||||||
|
* This code is in the public domain; do with it what you wish.
|
||||||
|
*
|
||||||
|
* Equivalent code is available from RSA Data Security, Inc.
|
||||||
|
* This code has been tested against that, and is equivalent,
|
||||||
|
* except that you don't need to include two pages of legalese
|
||||||
|
* with every copy.
|
||||||
|
*
|
||||||
|
* To compute the message digest of a chunk of bytes, declare an
|
||||||
|
* MD5Context structure, pass it to MD5Init, call MD5Update as
|
||||||
|
* needed on buffers full of bytes, and then call MD5Final, which
|
||||||
|
* will fill a supplied 16-byte array with the digest.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* This code was modified in 1997 by Jim Kingdon of Cyclic Software to
|
||||||
|
not require an integer type which is exactly 32 bits. This work
|
||||||
|
draws on the changes for the same purpose by Tatu Ylonen
|
||||||
|
<ylo@cs.hut.fi> as part of SSH, but since I didn't actually use
|
||||||
|
that code, there is no copyright issue. I hereby disclaim
|
||||||
|
copyright in any changes I have made; this code remains in the
|
||||||
|
public domain. */
|
||||||
|
|
||||||
|
#include <my_global.h>
|
||||||
|
#include <m_string.h>
|
||||||
|
#include "my_md5.h"
|
||||||
|
|
||||||
|
#include <string.h> /* for memcpy() and memset() */
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
my_MD5Transform (cvs_uint32 buf[4], const unsigned char in[64]);
|
||||||
|
|
||||||
|
/* Little-endian byte-swapping routines. Note that these do not
|
||||||
|
depend on the size of datatypes such as uint32, nor do they require
|
||||||
|
us to detect the endianness of the machine we are running on. It
|
||||||
|
is possible they should be macros for speed, but I would be
|
||||||
|
surprised if they were a performance bottleneck for MD5. */
|
||||||
|
|
||||||
|
static uint32 getu32 (const unsigned char *addr)
|
||||||
|
{
|
||||||
|
return (((((unsigned long)addr[3] << 8) | addr[2]) << 8)
|
||||||
|
| addr[1]) << 8 | addr[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
putu32 (uint32 data, unsigned char *addr)
|
||||||
|
{
|
||||||
|
addr[0] = (unsigned char)data;
|
||||||
|
addr[1] = (unsigned char)(data >> 8);
|
||||||
|
addr[2] = (unsigned char)(data >> 16);
|
||||||
|
addr[3] = (unsigned char)(data >> 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
|
||||||
|
initialization constants.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
my_MD5Init (my_MD5Context *ctx)
|
||||||
|
{
|
||||||
|
ctx->buf[0] = 0x67452301;
|
||||||
|
ctx->buf[1] = 0xefcdab89;
|
||||||
|
ctx->buf[2] = 0x98badcfe;
|
||||||
|
ctx->buf[3] = 0x10325476;
|
||||||
|
|
||||||
|
ctx->bits[0] = 0;
|
||||||
|
ctx->bits[1] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Update context to reflect the concatenation of another buffer full
|
||||||
|
of bytes.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
my_MD5Update (my_MD5Context *ctx, unsigned char const *buf, unsigned len)
|
||||||
|
{
|
||||||
|
uint32 t;
|
||||||
|
|
||||||
|
/* Update bitcount */
|
||||||
|
|
||||||
|
t = ctx->bits[0];
|
||||||
|
if ((ctx->bits[0] = (t + ((uint32)len << 3)) & 0xffffffff) < t)
|
||||||
|
ctx->bits[1]++; /* Carry from low to high */
|
||||||
|
ctx->bits[1] += len >> 29;
|
||||||
|
|
||||||
|
t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
|
||||||
|
|
||||||
|
/* Handle any leading odd-sized chunks */
|
||||||
|
|
||||||
|
if ( t ) {
|
||||||
|
unsigned char *p = ctx->in + t;
|
||||||
|
|
||||||
|
t = 64-t;
|
||||||
|
if (len < t) {
|
||||||
|
memcpy(p, buf, len);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
memcpy(p, buf, t);
|
||||||
|
my_MD5Transform (ctx->buf, ctx->in);
|
||||||
|
buf += t;
|
||||||
|
len -= t;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Process data in 64-byte chunks */
|
||||||
|
|
||||||
|
while (len >= 64) {
|
||||||
|
memcpy(ctx->in, buf, 64);
|
||||||
|
my_MD5Transform (ctx->buf, ctx->in);
|
||||||
|
buf += 64;
|
||||||
|
len -= 64;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handle any remaining bytes of data. */
|
||||||
|
|
||||||
|
memcpy(ctx->in, buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Final wrapup - pad to 64-byte boundary with the bit pattern
|
||||||
|
1 0* (64-bit count of bits processed, MSB-first)
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
my_MD5Final (unsigned char digest[16], my_MD5Context *ctx)
|
||||||
|
{
|
||||||
|
unsigned count;
|
||||||
|
unsigned char *p;
|
||||||
|
|
||||||
|
/* Compute number of bytes mod 64 */
|
||||||
|
count = (ctx->bits[0] >> 3) & 0x3F;
|
||||||
|
|
||||||
|
/* Set the first char of padding to 0x80. This is safe since there is
|
||||||
|
always at least one byte free */
|
||||||
|
p = ctx->in + count;
|
||||||
|
*p++ = 0x80;
|
||||||
|
|
||||||
|
/* Bytes of padding needed to make 64 bytes */
|
||||||
|
count = 64 - 1 - count;
|
||||||
|
|
||||||
|
/* Pad out to 56 mod 64 */
|
||||||
|
if (count < 8) {
|
||||||
|
/* Two lots of padding: Pad the first block to 64 bytes */
|
||||||
|
memset(p, 0, count);
|
||||||
|
my_MD5Transform (ctx->buf, ctx->in);
|
||||||
|
|
||||||
|
/* Now fill the next block with 56 bytes */
|
||||||
|
memset(ctx->in, 0, 56);
|
||||||
|
} else {
|
||||||
|
/* Pad block to 56 bytes */
|
||||||
|
memset(p, 0, count-8);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Append length in bits and transform */
|
||||||
|
putu32(ctx->bits[0], ctx->in + 56);
|
||||||
|
putu32(ctx->bits[1], ctx->in + 60);
|
||||||
|
|
||||||
|
my_MD5Transform (ctx->buf, ctx->in);
|
||||||
|
putu32(ctx->buf[0], digest);
|
||||||
|
putu32(ctx->buf[1], digest + 4);
|
||||||
|
putu32(ctx->buf[2], digest + 8);
|
||||||
|
putu32(ctx->buf[3], digest + 12);
|
||||||
|
memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef ASM_MD5
|
||||||
|
|
||||||
|
/* The four core functions - F1 is optimized somewhat */
|
||||||
|
|
||||||
|
/* #define F1(x, y, z) (x & y | ~x & z) */
|
||||||
|
#define F1(x, y, z) (z ^ (x & (y ^ z)))
|
||||||
|
#define F2(x, y, z) F1(z, x, y)
|
||||||
|
#define F3(x, y, z) (x ^ y ^ z)
|
||||||
|
#define F4(x, y, z) (y ^ (x | ~z))
|
||||||
|
|
||||||
|
/* This is the central step in the MD5 algorithm. */
|
||||||
|
#define MD5STEP(f, w, x, y, z, data, s) \
|
||||||
|
( w += f(x, y, z) + data, w &= 0xffffffff, w = w<<s | w>>(32-s), w += x )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The core of the MD5 algorithm, this alters an existing MD5 hash to
|
||||||
|
* reflect the addition of 16 longwords of new data. MD5Update blocks
|
||||||
|
* the data and converts bytes into longwords for this routine.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
my_MD5Transform (uint32 buf[4], const unsigned char inraw[64])
|
||||||
|
{
|
||||||
|
register uint32 a, b, c, d;
|
||||||
|
uint32 in[16];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < 16; ++i)
|
||||||
|
in[i] = getu32 (inraw + 4 * i);
|
||||||
|
|
||||||
|
a = buf[0];
|
||||||
|
b = buf[1];
|
||||||
|
c = buf[2];
|
||||||
|
d = buf[3];
|
||||||
|
|
||||||
|
MD5STEP(F1, a, b, c, d, in[ 0]+0xd76aa478, 7);
|
||||||
|
MD5STEP(F1, d, a, b, c, in[ 1]+0xe8c7b756, 12);
|
||||||
|
MD5STEP(F1, c, d, a, b, in[ 2]+0x242070db, 17);
|
||||||
|
MD5STEP(F1, b, c, d, a, in[ 3]+0xc1bdceee, 22);
|
||||||
|
MD5STEP(F1, a, b, c, d, in[ 4]+0xf57c0faf, 7);
|
||||||
|
MD5STEP(F1, d, a, b, c, in[ 5]+0x4787c62a, 12);
|
||||||
|
MD5STEP(F1, c, d, a, b, in[ 6]+0xa8304613, 17);
|
||||||
|
MD5STEP(F1, b, c, d, a, in[ 7]+0xfd469501, 22);
|
||||||
|
MD5STEP(F1, a, b, c, d, in[ 8]+0x698098d8, 7);
|
||||||
|
MD5STEP(F1, d, a, b, c, in[ 9]+0x8b44f7af, 12);
|
||||||
|
MD5STEP(F1, c, d, a, b, in[10]+0xffff5bb1, 17);
|
||||||
|
MD5STEP(F1, b, c, d, a, in[11]+0x895cd7be, 22);
|
||||||
|
MD5STEP(F1, a, b, c, d, in[12]+0x6b901122, 7);
|
||||||
|
MD5STEP(F1, d, a, b, c, in[13]+0xfd987193, 12);
|
||||||
|
MD5STEP(F1, c, d, a, b, in[14]+0xa679438e, 17);
|
||||||
|
MD5STEP(F1, b, c, d, a, in[15]+0x49b40821, 22);
|
||||||
|
|
||||||
|
MD5STEP(F2, a, b, c, d, in[ 1]+0xf61e2562, 5);
|
||||||
|
MD5STEP(F2, d, a, b, c, in[ 6]+0xc040b340, 9);
|
||||||
|
MD5STEP(F2, c, d, a, b, in[11]+0x265e5a51, 14);
|
||||||
|
MD5STEP(F2, b, c, d, a, in[ 0]+0xe9b6c7aa, 20);
|
||||||
|
MD5STEP(F2, a, b, c, d, in[ 5]+0xd62f105d, 5);
|
||||||
|
MD5STEP(F2, d, a, b, c, in[10]+0x02441453, 9);
|
||||||
|
MD5STEP(F2, c, d, a, b, in[15]+0xd8a1e681, 14);
|
||||||
|
MD5STEP(F2, b, c, d, a, in[ 4]+0xe7d3fbc8, 20);
|
||||||
|
MD5STEP(F2, a, b, c, d, in[ 9]+0x21e1cde6, 5);
|
||||||
|
MD5STEP(F2, d, a, b, c, in[14]+0xc33707d6, 9);
|
||||||
|
MD5STEP(F2, c, d, a, b, in[ 3]+0xf4d50d87, 14);
|
||||||
|
MD5STEP(F2, b, c, d, a, in[ 8]+0x455a14ed, 20);
|
||||||
|
MD5STEP(F2, a, b, c, d, in[13]+0xa9e3e905, 5);
|
||||||
|
MD5STEP(F2, d, a, b, c, in[ 2]+0xfcefa3f8, 9);
|
||||||
|
MD5STEP(F2, c, d, a, b, in[ 7]+0x676f02d9, 14);
|
||||||
|
MD5STEP(F2, b, c, d, a, in[12]+0x8d2a4c8a, 20);
|
||||||
|
|
||||||
|
MD5STEP(F3, a, b, c, d, in[ 5]+0xfffa3942, 4);
|
||||||
|
MD5STEP(F3, d, a, b, c, in[ 8]+0x8771f681, 11);
|
||||||
|
MD5STEP(F3, c, d, a, b, in[11]+0x6d9d6122, 16);
|
||||||
|
MD5STEP(F3, b, c, d, a, in[14]+0xfde5380c, 23);
|
||||||
|
MD5STEP(F3, a, b, c, d, in[ 1]+0xa4beea44, 4);
|
||||||
|
MD5STEP(F3, d, a, b, c, in[ 4]+0x4bdecfa9, 11);
|
||||||
|
MD5STEP(F3, c, d, a, b, in[ 7]+0xf6bb4b60, 16);
|
||||||
|
MD5STEP(F3, b, c, d, a, in[10]+0xbebfbc70, 23);
|
||||||
|
MD5STEP(F3, a, b, c, d, in[13]+0x289b7ec6, 4);
|
||||||
|
MD5STEP(F3, d, a, b, c, in[ 0]+0xeaa127fa, 11);
|
||||||
|
MD5STEP(F3, c, d, a, b, in[ 3]+0xd4ef3085, 16);
|
||||||
|
MD5STEP(F3, b, c, d, a, in[ 6]+0x04881d05, 23);
|
||||||
|
MD5STEP(F3, a, b, c, d, in[ 9]+0xd9d4d039, 4);
|
||||||
|
MD5STEP(F3, d, a, b, c, in[12]+0xe6db99e5, 11);
|
||||||
|
MD5STEP(F3, c, d, a, b, in[15]+0x1fa27cf8, 16);
|
||||||
|
MD5STEP(F3, b, c, d, a, in[ 2]+0xc4ac5665, 23);
|
||||||
|
|
||||||
|
MD5STEP(F4, a, b, c, d, in[ 0]+0xf4292244, 6);
|
||||||
|
MD5STEP(F4, d, a, b, c, in[ 7]+0x432aff97, 10);
|
||||||
|
MD5STEP(F4, c, d, a, b, in[14]+0xab9423a7, 15);
|
||||||
|
MD5STEP(F4, b, c, d, a, in[ 5]+0xfc93a039, 21);
|
||||||
|
MD5STEP(F4, a, b, c, d, in[12]+0x655b59c3, 6);
|
||||||
|
MD5STEP(F4, d, a, b, c, in[ 3]+0x8f0ccc92, 10);
|
||||||
|
MD5STEP(F4, c, d, a, b, in[10]+0xffeff47d, 15);
|
||||||
|
MD5STEP(F4, b, c, d, a, in[ 1]+0x85845dd1, 21);
|
||||||
|
MD5STEP(F4, a, b, c, d, in[ 8]+0x6fa87e4f, 6);
|
||||||
|
MD5STEP(F4, d, a, b, c, in[15]+0xfe2ce6e0, 10);
|
||||||
|
MD5STEP(F4, c, d, a, b, in[ 6]+0xa3014314, 15);
|
||||||
|
MD5STEP(F4, b, c, d, a, in[13]+0x4e0811a1, 21);
|
||||||
|
MD5STEP(F4, a, b, c, d, in[ 4]+0xf7537e82, 6);
|
||||||
|
MD5STEP(F4, d, a, b, c, in[11]+0xbd3af235, 10);
|
||||||
|
MD5STEP(F4, c, d, a, b, in[ 2]+0x2ad7d2bb, 15);
|
||||||
|
MD5STEP(F4, b, c, d, a, in[ 9]+0xeb86d391, 21);
|
||||||
|
|
||||||
|
buf[0] += a;
|
||||||
|
buf[1] += b;
|
||||||
|
buf[2] += c;
|
||||||
|
buf[3] += d;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
/*
|
||||||
|
Simple test program. Can use it to manually run the tests from
|
||||||
|
RFC1321 for example.
|
||||||
|
*/
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char **argv)
|
||||||
|
{
|
||||||
|
my_MD5Context context;
|
||||||
|
unsigned char checksum[16];
|
||||||
|
int i;
|
||||||
|
int j;
|
||||||
|
|
||||||
|
if (argc < 2)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "usage: %s string-to-hash\n", argv[0]);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
for (j = 1; j < argc; ++j)
|
||||||
|
{
|
||||||
|
printf ("MD5 (\"%s\") = ", argv[j]);
|
||||||
|
my_MD5Init (&context);
|
||||||
|
my_MD5Update (&context, argv[j], strlen (argv[j]));
|
||||||
|
my_MD5Final (checksum, &context);
|
||||||
|
for (i = 0; i < 16; i++)
|
||||||
|
{
|
||||||
|
printf ("%02x", (unsigned int) checksum[i]);
|
||||||
|
}
|
||||||
|
printf ("\n");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* TEST */
|
61
MySQL/mf_arr_appstr.c
Normal file
61
MySQL/mf_arr_appstr.c
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
/* Copyright (C) 2007 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
#include "mysys_priv.h"
|
||||||
|
#include <m_string.h> /* strcmp() */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Append str to array, or move to the end if it already exists
|
||||||
|
|
||||||
|
@param str String to be appended
|
||||||
|
@param array The array, terminated by a NULL element, all unused elements
|
||||||
|
pre-initialized to NULL
|
||||||
|
@param size Size of the array; array must be terminated by a NULL
|
||||||
|
pointer, so can hold size - 1 elements
|
||||||
|
|
||||||
|
@retval FALSE Success
|
||||||
|
@retval TRUE Failure, array is full
|
||||||
|
*/
|
||||||
|
|
||||||
|
my_bool array_append_string_unique(const char *str,
|
||||||
|
const char **array, size_t size)
|
||||||
|
{
|
||||||
|
const char **p;
|
||||||
|
/* end points at the terminating NULL element */
|
||||||
|
const char **end= array + size - 1;
|
||||||
|
DBUG_ASSERT(*end == NULL);
|
||||||
|
|
||||||
|
for (p= array; *p; ++p)
|
||||||
|
{
|
||||||
|
if (strcmp(*p, str) == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (p >= end)
|
||||||
|
return TRUE; /* Array is full */
|
||||||
|
|
||||||
|
DBUG_ASSERT(*p == NULL || strcmp(*p, str) == 0);
|
||||||
|
|
||||||
|
while (*(p + 1))
|
||||||
|
{
|
||||||
|
*p= *(p + 1);
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
|
||||||
|
DBUG_ASSERT(p < end);
|
||||||
|
*p= str;
|
||||||
|
|
||||||
|
return FALSE; /* Success */
|
||||||
|
}
|
121
MySQL/mf_cache.c
Normal file
121
MySQL/mf_cache.c
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
/* Copyright (C) 2000 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
/* Open a temporary file and cache it with io_cache. Delete it on close */
|
||||||
|
|
||||||
|
#include "mysys_priv.h"
|
||||||
|
#include <m_string.h>
|
||||||
|
#include "my_static.h"
|
||||||
|
#include "mysys_err.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
Remove an open tempfile so that it doesn't survive
|
||||||
|
if we crash; If the operating system doesn't support
|
||||||
|
this, just remember the file name for later removal
|
||||||
|
*/
|
||||||
|
|
||||||
|
static my_bool cache_remove_open_tmp(IO_CACHE *cache __attribute__((unused)),
|
||||||
|
const char *name)
|
||||||
|
{
|
||||||
|
#if O_TEMPORARY == 0
|
||||||
|
#if !defined(CANT_DELETE_OPEN_FILES)
|
||||||
|
/* The following should always succeed */
|
||||||
|
(void) my_delete(name,MYF(MY_WME | ME_NOINPUT));
|
||||||
|
#else
|
||||||
|
int length;
|
||||||
|
if (!(cache->file_name=
|
||||||
|
(char*) my_malloc((length=strlen(name)+1),MYF(MY_WME))))
|
||||||
|
{
|
||||||
|
my_close(cache->file,MYF(0));
|
||||||
|
cache->file = -1;
|
||||||
|
errno=my_errno=ENOMEM;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
memcpy(cache->file_name,name,length);
|
||||||
|
#endif
|
||||||
|
#endif /* O_TEMPORARY == 0 */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Open tempfile cached by IO_CACHE
|
||||||
|
** Should be used when no seeks are done (only reinit_io_buff)
|
||||||
|
** Return 0 if cache is inited ok
|
||||||
|
** The actual file is created when the IO_CACHE buffer gets filled
|
||||||
|
** If dir is not given, use TMPDIR.
|
||||||
|
*/
|
||||||
|
|
||||||
|
my_bool open_cached_file(IO_CACHE *cache, const char* dir, const char *prefix,
|
||||||
|
size_t cache_size, myf cache_myflags)
|
||||||
|
{
|
||||||
|
DBUG_ENTER("open_cached_file");
|
||||||
|
cache->dir= dir ? my_strdup(dir,MYF(cache_myflags & MY_WME)) : (char*) 0;
|
||||||
|
cache->prefix= (prefix ? my_strdup(prefix,MYF(cache_myflags & MY_WME)) :
|
||||||
|
(char*) 0);
|
||||||
|
cache->file_name=0;
|
||||||
|
cache->buffer=0; /* Mark that not open */
|
||||||
|
if (!init_io_cache(cache,-1,cache_size,WRITE_CACHE,0L,0,
|
||||||
|
MYF(cache_myflags | MY_NABP)))
|
||||||
|
{
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
}
|
||||||
|
my_free(cache->dir, MYF(MY_ALLOW_ZERO_PTR));
|
||||||
|
my_free(cache->prefix,MYF(MY_ALLOW_ZERO_PTR));
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create the temporary file */
|
||||||
|
|
||||||
|
my_bool real_open_cached_file(IO_CACHE *cache)
|
||||||
|
{
|
||||||
|
char name_buff[FN_REFLEN];
|
||||||
|
int error=1;
|
||||||
|
DBUG_ENTER("real_open_cached_file");
|
||||||
|
if ((cache->file=create_temp_file(name_buff, cache->dir, cache->prefix,
|
||||||
|
(O_RDWR | O_BINARY | O_TRUNC |
|
||||||
|
O_TEMPORARY | O_SHORT_LIVED),
|
||||||
|
MYF(MY_WME))) >= 0)
|
||||||
|
{
|
||||||
|
error=0;
|
||||||
|
cache_remove_open_tmp(cache, name_buff);
|
||||||
|
}
|
||||||
|
DBUG_RETURN(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void close_cached_file(IO_CACHE *cache)
|
||||||
|
{
|
||||||
|
DBUG_ENTER("close_cached_file");
|
||||||
|
if (my_b_inited(cache))
|
||||||
|
{
|
||||||
|
File file=cache->file;
|
||||||
|
cache->file= -1; /* Don't flush data */
|
||||||
|
(void) end_io_cache(cache);
|
||||||
|
if (file >= 0)
|
||||||
|
{
|
||||||
|
(void) my_close(file,MYF(0));
|
||||||
|
#ifdef CANT_DELETE_OPEN_FILES
|
||||||
|
if (cache->file_name)
|
||||||
|
{
|
||||||
|
(void) my_delete(cache->file_name,MYF(MY_WME | ME_NOINPUT));
|
||||||
|
my_free(cache->file_name,MYF(0));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
my_free(cache->dir,MYF(MY_ALLOW_ZERO_PTR));
|
||||||
|
my_free(cache->prefix,MYF(MY_ALLOW_ZERO_PTR));
|
||||||
|
}
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
165
MySQL/mf_dirname.c
Normal file
165
MySQL/mf_dirname.c
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
/* Copyright (C) 2000 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
#include "mysys_priv.h"
|
||||||
|
#include <m_string.h>
|
||||||
|
|
||||||
|
/* Functions definied in this file */
|
||||||
|
|
||||||
|
size_t dirname_length(const char *name)
|
||||||
|
{
|
||||||
|
register char *pos, *gpos;
|
||||||
|
#ifdef BASKSLASH_MBTAIL
|
||||||
|
CHARSET_INFO *fs= fs_character_set();
|
||||||
|
#endif
|
||||||
|
#ifdef FN_DEVCHAR
|
||||||
|
if ((pos=(char*)strrchr(name,FN_DEVCHAR)) == 0)
|
||||||
|
#endif
|
||||||
|
pos=(char*) name-1;
|
||||||
|
|
||||||
|
gpos= pos++;
|
||||||
|
for ( ; *pos ; pos++) /* Find last FN_LIBCHAR */
|
||||||
|
{
|
||||||
|
#ifdef BASKSLASH_MBTAIL
|
||||||
|
uint l;
|
||||||
|
if (use_mb(fs) && (l= my_ismbchar(fs, pos, pos + 3)))
|
||||||
|
{
|
||||||
|
pos+= l - 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (*pos == FN_LIBCHAR || *pos == '/'
|
||||||
|
#ifdef FN_C_AFTER_DIR
|
||||||
|
|| *pos == FN_C_AFTER_DIR || *pos == FN_C_AFTER_DIR_2
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
gpos=pos;
|
||||||
|
}
|
||||||
|
return (size_t) (gpos+1-(char*) name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Gives directory part of filename. Directory ends with '/'
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
dirname_part()
|
||||||
|
to Store directory name here
|
||||||
|
name Original name
|
||||||
|
to_length Store length of 'to' here
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
# Length of directory part in 'name'
|
||||||
|
*/
|
||||||
|
|
||||||
|
size_t dirname_part(char *to, const char *name, size_t *to_res_length)
|
||||||
|
{
|
||||||
|
size_t length;
|
||||||
|
DBUG_ENTER("dirname_part");
|
||||||
|
DBUG_PRINT("enter",("'%s'",name));
|
||||||
|
|
||||||
|
length=dirname_length(name);
|
||||||
|
*to_res_length= (size_t) (convert_dirname(to, name, name+length) - to);
|
||||||
|
DBUG_RETURN(length);
|
||||||
|
} /* dirname */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Convert directory name to use under this system
|
||||||
|
|
||||||
|
SYNPOSIS
|
||||||
|
convert_dirname()
|
||||||
|
to Store result here. Must be at least of size
|
||||||
|
min(FN_REFLEN, strlen(from) + 1) to make room
|
||||||
|
for adding FN_LIBCHAR at the end.
|
||||||
|
from Original filename. May be == to
|
||||||
|
from_end Pointer at end of filename (normally end \0)
|
||||||
|
|
||||||
|
IMPLEMENTATION
|
||||||
|
If MSDOS converts '/' to '\'
|
||||||
|
If VMS converts '<' to '[' and '>' to ']'
|
||||||
|
Adds a FN_LIBCHAR to end if the result string if there isn't one
|
||||||
|
and the last isn't dev_char.
|
||||||
|
Copies data from 'from' until ASCII(0) for until from == from_end
|
||||||
|
If you want to use the whole 'from' string, just send NullS as the
|
||||||
|
last argument.
|
||||||
|
|
||||||
|
If the result string is larger than FN_REFLEN -1, then it's cut.
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
Returns pointer to end \0 in to
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FN_DEVCHAR
|
||||||
|
#define FN_DEVCHAR '\0' /* For easier code */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
char *convert_dirname(char *to, const char *from, const char *from_end)
|
||||||
|
{
|
||||||
|
char *to_org=to;
|
||||||
|
#ifdef BACKSLASH_MBTAIL
|
||||||
|
CHARSET_INFO *fs= fs_character_set();
|
||||||
|
#endif
|
||||||
|
DBUG_ENTER("convert_dirname");
|
||||||
|
|
||||||
|
/* We use -2 here, becasue we need place for the last FN_LIBCHAR */
|
||||||
|
if (!from_end || (from_end - from) > FN_REFLEN-2)
|
||||||
|
from_end=from+FN_REFLEN -2;
|
||||||
|
|
||||||
|
#if FN_LIBCHAR != '/' || defined(FN_C_BEFORE_DIR_2)
|
||||||
|
{
|
||||||
|
for (; from != from_end && *from ; from++)
|
||||||
|
{
|
||||||
|
if (*from == '/')
|
||||||
|
*to++= FN_LIBCHAR;
|
||||||
|
#ifdef FN_C_BEFORE_DIR_2
|
||||||
|
else if (*from == FN_C_BEFORE_DIR_2)
|
||||||
|
*to++= FN_C_BEFORE_DIR;
|
||||||
|
else if (*from == FN_C_AFTER_DIR_2)
|
||||||
|
*to++= FN_C_AFTER_DIR;
|
||||||
|
#endif
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifdef BACKSLASH_MBTAIL
|
||||||
|
uint l;
|
||||||
|
if (use_mb(fs) && (l= my_ismbchar(fs, from, from + 3)))
|
||||||
|
{
|
||||||
|
memmove(to, from, l);
|
||||||
|
to+= l;
|
||||||
|
from+= l - 1;
|
||||||
|
to_org= to; /* Don't look inside mbchar */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
*to++= *from;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*to=0;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
/* This is ok even if to == from, becasue we need to cut the string */
|
||||||
|
to= strmake(to, from, (size_t) (from_end-from));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Add FN_LIBCHAR to the end of directory path */
|
||||||
|
if (to != to_org && (to[-1] != FN_LIBCHAR && to[-1] != FN_DEVCHAR))
|
||||||
|
{
|
||||||
|
*to++=FN_LIBCHAR;
|
||||||
|
*to=0;
|
||||||
|
}
|
||||||
|
DBUG_RETURN(to); /* Pointer to end of dir */
|
||||||
|
} /* convert_dirname */
|
54
MySQL/mf_fn_ext.c
Normal file
54
MySQL/mf_fn_ext.c
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/* Copyright (C) 2000 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
|
||||||
|
#include "mysys_priv.h"
|
||||||
|
#include <m_string.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
Return a pointer to the extension of the filename.
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
fn_ext()
|
||||||
|
name Name of file
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
The extension is defined as everything after the first extension character
|
||||||
|
(normally '.') after the directory name.
|
||||||
|
|
||||||
|
RETURN VALUES
|
||||||
|
Pointer to to the extension character. If there isn't any extension,
|
||||||
|
points at the end ASCII(0) of the filename.
|
||||||
|
*/
|
||||||
|
|
||||||
|
char *fn_ext(const char *name)
|
||||||
|
{
|
||||||
|
register const char *pos, *gpos;
|
||||||
|
DBUG_ENTER("fn_ext");
|
||||||
|
DBUG_PRINT("mfunkt",("name: '%s'",name));
|
||||||
|
|
||||||
|
#if defined(FN_DEVCHAR) || defined(FN_C_AFTER_DIR) || defined(BASKSLASH_MBTAIL)
|
||||||
|
{
|
||||||
|
char buff[FN_REFLEN];
|
||||||
|
size_t res_length;
|
||||||
|
gpos= name+ dirname_part(buff,(char*) name, &res_length);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (!(gpos= strrchr(name, FN_LIBCHAR)))
|
||||||
|
gpos= name;
|
||||||
|
#endif
|
||||||
|
pos=strchr(gpos,FN_EXTCHAR);
|
||||||
|
DBUG_RETURN((char*) (pos ? pos : strend(gpos)));
|
||||||
|
} /* fn_ext */
|
142
MySQL/mf_format.c
Normal file
142
MySQL/mf_format.c
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
/* Copyright (C) 2000 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
#include "mysys_priv.h"
|
||||||
|
#include <m_string.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
Formats a filename with possible replace of directory of extension
|
||||||
|
Function can handle the case where 'to' == 'name'
|
||||||
|
For a description of the flag values, consult my_sys.h
|
||||||
|
The arguments should be in unix format.
|
||||||
|
*/
|
||||||
|
|
||||||
|
char * fn_format(char * to, const char *name, const char *dir,
|
||||||
|
const char *extension, uint flag)
|
||||||
|
{
|
||||||
|
char dev[FN_REFLEN], buff[FN_REFLEN], *pos, *startpos;
|
||||||
|
const char *ext;
|
||||||
|
reg1 size_t length;
|
||||||
|
size_t dev_length;
|
||||||
|
DBUG_ENTER("fn_format");
|
||||||
|
DBUG_PRINT("enter",("name: %s dir: %s extension: %s flag: %d",
|
||||||
|
name,dir,extension,flag));
|
||||||
|
|
||||||
|
/* Copy and skip directory */
|
||||||
|
name+=(length=dirname_part(dev, (startpos=(char *) name), &dev_length));
|
||||||
|
if (length == 0 || (flag & MY_REPLACE_DIR))
|
||||||
|
{
|
||||||
|
/* Use given directory */
|
||||||
|
convert_dirname(dev,dir,NullS); /* Fix to this OS */
|
||||||
|
}
|
||||||
|
else if ((flag & MY_RELATIVE_PATH) && !test_if_hard_path(dev))
|
||||||
|
{
|
||||||
|
/* Put 'dir' before the given path */
|
||||||
|
strmake(buff,dev,sizeof(buff)-1);
|
||||||
|
pos=convert_dirname(dev,dir,NullS);
|
||||||
|
strmake(pos,buff,sizeof(buff)-1- (int) (pos-dev));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flag & MY_PACK_FILENAME)
|
||||||
|
pack_dirname(dev,dev); /* Put in ./.. and ~/.. */
|
||||||
|
if (flag & MY_UNPACK_FILENAME)
|
||||||
|
(void) unpack_dirname(dev,dev); /* Replace ~/.. with dir */
|
||||||
|
|
||||||
|
if (!(flag & MY_APPEND_EXT) &&
|
||||||
|
(pos= (char*) strchr(name,FN_EXTCHAR)) != NullS)
|
||||||
|
{
|
||||||
|
if ((flag & MY_REPLACE_EXT) == 0) /* If we should keep old ext */
|
||||||
|
{
|
||||||
|
length=strlength(name); /* Use old extension */
|
||||||
|
ext = "";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
length= (size_t) (pos-(char*) name); /* Change extension */
|
||||||
|
ext= extension;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
length=strlength(name); /* No ext, use the now one */
|
||||||
|
ext=extension;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strlen(dev)+length+strlen(ext) >= FN_REFLEN || length >= FN_LEN )
|
||||||
|
{
|
||||||
|
/* To long path, return original or NULL */
|
||||||
|
size_t tmp_length;
|
||||||
|
if (flag & MY_SAFE_PATH)
|
||||||
|
DBUG_RETURN(NullS);
|
||||||
|
tmp_length= strlength(startpos);
|
||||||
|
DBUG_PRINT("error",("dev: '%s' ext: '%s' length: %u",dev,ext,
|
||||||
|
(uint) length));
|
||||||
|
(void) strmake(to,startpos,min(tmp_length,FN_REFLEN-1));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (to == startpos)
|
||||||
|
{
|
||||||
|
bmove(buff,(uchar*) name,length); /* Save name for last copy */
|
||||||
|
name=buff;
|
||||||
|
}
|
||||||
|
pos=strmake(strmov(to,dev),name,length);
|
||||||
|
(void) strmov(pos,ext); /* Don't convert extension */
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
If MY_RETURN_REAL_PATH and MY_RESOLVE_SYMLINK is given, only do
|
||||||
|
realpath if the file is a symbolic link
|
||||||
|
*/
|
||||||
|
if (flag & MY_RETURN_REAL_PATH)
|
||||||
|
(void) my_realpath(to, to, MYF(flag & MY_RESOLVE_SYMLINKS ?
|
||||||
|
MY_RESOLVE_LINK: 0));
|
||||||
|
else if (flag & MY_RESOLVE_SYMLINKS)
|
||||||
|
{
|
||||||
|
strmov(buff,to);
|
||||||
|
(void) my_readlink(to, buff, MYF(0));
|
||||||
|
}
|
||||||
|
DBUG_RETURN(to);
|
||||||
|
} /* fn_format */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
strlength(const string str)
|
||||||
|
Return length of string with end-space:s not counted.
|
||||||
|
*/
|
||||||
|
|
||||||
|
size_t strlength(const char *str)
|
||||||
|
{
|
||||||
|
reg1 const char * pos;
|
||||||
|
reg2 const char * found;
|
||||||
|
DBUG_ENTER("strlength");
|
||||||
|
|
||||||
|
pos= found= str;
|
||||||
|
|
||||||
|
while (*pos)
|
||||||
|
{
|
||||||
|
if (*pos != ' ')
|
||||||
|
{
|
||||||
|
while (*++pos && *pos != ' ') {};
|
||||||
|
if (!*pos)
|
||||||
|
{
|
||||||
|
found=pos; /* String ends here */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
found=pos;
|
||||||
|
while (*++pos == ' ') {};
|
||||||
|
}
|
||||||
|
DBUG_RETURN((size_t) (found - str));
|
||||||
|
} /* strlength */
|
1936
MySQL/mf_iocache.c
Normal file
1936
MySQL/mf_iocache.c
Normal file
File diff suppressed because it is too large
Load Diff
466
MySQL/mf_iocache2.c
Normal file
466
MySQL/mf_iocache2.c
Normal file
@ -0,0 +1,466 @@
|
|||||||
|
/* Copyright (C) 2000 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
/*
|
||||||
|
More functions to be used with IO_CACHE files
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define MAP_TO_USE_RAID
|
||||||
|
#include "mysys_priv.h"
|
||||||
|
#include <m_string.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <m_ctype.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copy contents of an IO_CACHE to a file.
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
my_b_copy_to_file()
|
||||||
|
cache IO_CACHE to copy from
|
||||||
|
file File to copy to
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Copy the contents of the cache to the file. The cache will be
|
||||||
|
re-inited to a read cache and will read from the beginning of the
|
||||||
|
cache.
|
||||||
|
|
||||||
|
If a failure to write fully occurs, the cache is only copied
|
||||||
|
partially.
|
||||||
|
|
||||||
|
TODO
|
||||||
|
Make this function solid by handling partial reads from the cache
|
||||||
|
in a correct manner: it should be atomic.
|
||||||
|
|
||||||
|
RETURN VALUE
|
||||||
|
0 All OK
|
||||||
|
1 An error occured
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
my_b_copy_to_file(IO_CACHE *cache, FILE *file)
|
||||||
|
{
|
||||||
|
size_t bytes_in_cache;
|
||||||
|
DBUG_ENTER("my_b_copy_to_file");
|
||||||
|
|
||||||
|
/* Reinit the cache to read from the beginning of the cache */
|
||||||
|
if (reinit_io_cache(cache, READ_CACHE, 0L, FALSE, FALSE))
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
bytes_in_cache= my_b_bytes_in_cache(cache);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (my_fwrite(file, cache->read_pos, bytes_in_cache,
|
||||||
|
MYF(MY_WME | MY_NABP)) == (size_t) -1)
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
cache->read_pos= cache->read_end;
|
||||||
|
} while ((bytes_in_cache= my_b_fill(cache)));
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
my_off_t my_b_append_tell(IO_CACHE* info)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Prevent optimizer from putting res in a register when debugging
|
||||||
|
we need this to be able to see the value of res when the assert fails
|
||||||
|
*/
|
||||||
|
dbug_volatile my_off_t res;
|
||||||
|
|
||||||
|
/*
|
||||||
|
We need to lock the append buffer mutex to keep flush_io_cache()
|
||||||
|
from messing with the variables that we need in order to provide the
|
||||||
|
answer to the question.
|
||||||
|
*/
|
||||||
|
#ifdef THREAD
|
||||||
|
pthread_mutex_lock(&info->append_buffer_lock);
|
||||||
|
#endif
|
||||||
|
#ifndef DBUG_OFF
|
||||||
|
/*
|
||||||
|
Make sure EOF is where we think it is. Note that we cannot just use
|
||||||
|
my_tell() because we have a reader thread that could have left the
|
||||||
|
file offset in a non-EOF location
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
volatile my_off_t save_pos;
|
||||||
|
save_pos = my_tell(info->file,MYF(0));
|
||||||
|
my_seek(info->file,(my_off_t)0,MY_SEEK_END,MYF(0));
|
||||||
|
/*
|
||||||
|
Save the value of my_tell in res so we can see it when studying coredump
|
||||||
|
*/
|
||||||
|
DBUG_ASSERT(info->end_of_file - (info->append_read_pos-info->write_buffer)
|
||||||
|
== (res=my_tell(info->file,MYF(0))));
|
||||||
|
my_seek(info->file,save_pos,MY_SEEK_SET,MYF(0));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
res = info->end_of_file + (info->write_pos-info->append_read_pos);
|
||||||
|
#ifdef THREAD
|
||||||
|
pthread_mutex_unlock(&info->append_buffer_lock);
|
||||||
|
#endif
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
my_off_t my_b_safe_tell(IO_CACHE *info)
|
||||||
|
{
|
||||||
|
if (unlikely(info->type == SEQ_READ_APPEND))
|
||||||
|
return my_b_append_tell(info);
|
||||||
|
return my_b_tell(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Make next read happen at the given position
|
||||||
|
For write cache, make next write happen at the given position
|
||||||
|
*/
|
||||||
|
|
||||||
|
void my_b_seek(IO_CACHE *info,my_off_t pos)
|
||||||
|
{
|
||||||
|
my_off_t offset;
|
||||||
|
DBUG_ENTER("my_b_seek");
|
||||||
|
DBUG_PRINT("enter",("pos: %lu", (ulong) pos));
|
||||||
|
|
||||||
|
/*
|
||||||
|
TODO:
|
||||||
|
Verify that it is OK to do seek in the non-append
|
||||||
|
area in SEQ_READ_APPEND cache
|
||||||
|
a) see if this always works
|
||||||
|
b) see if there is a better way to make it work
|
||||||
|
*/
|
||||||
|
if (info->type == SEQ_READ_APPEND)
|
||||||
|
VOID(flush_io_cache(info));
|
||||||
|
|
||||||
|
offset=(pos - info->pos_in_file);
|
||||||
|
|
||||||
|
if (info->type == READ_CACHE || info->type == SEQ_READ_APPEND)
|
||||||
|
{
|
||||||
|
/* TODO: explain why this works if pos < info->pos_in_file */
|
||||||
|
if ((ulonglong) offset < (ulonglong) (info->read_end - info->buffer))
|
||||||
|
{
|
||||||
|
/* The read is in the current buffer; Reuse it */
|
||||||
|
info->read_pos = info->buffer + offset;
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Force a new read on next my_b_read */
|
||||||
|
info->read_pos=info->read_end=info->buffer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (info->type == WRITE_CACHE)
|
||||||
|
{
|
||||||
|
/* If write is in current buffer, reuse it */
|
||||||
|
if ((ulonglong) offset <
|
||||||
|
(ulonglong) (info->write_end - info->write_buffer))
|
||||||
|
{
|
||||||
|
info->write_pos = info->write_buffer + offset;
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
|
VOID(flush_io_cache(info));
|
||||||
|
/* Correct buffer end so that we write in increments of IO_SIZE */
|
||||||
|
info->write_end=(info->write_buffer+info->buffer_length-
|
||||||
|
(pos & (IO_SIZE-1)));
|
||||||
|
}
|
||||||
|
info->pos_in_file=pos;
|
||||||
|
info->seek_not_done=1;
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Fill buffer of the cache.
|
||||||
|
|
||||||
|
NOTES
|
||||||
|
This assumes that you have already used all characters in the CACHE,
|
||||||
|
independent of the read_pos value!
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
0 On error or EOF (info->error = -1 on error)
|
||||||
|
# Number of characters
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
size_t my_b_fill(IO_CACHE *info)
|
||||||
|
{
|
||||||
|
my_off_t pos_in_file=(info->pos_in_file+
|
||||||
|
(size_t) (info->read_end - info->buffer));
|
||||||
|
size_t diff_length, length, max_length;
|
||||||
|
|
||||||
|
if (info->seek_not_done)
|
||||||
|
{ /* File touched, do seek */
|
||||||
|
if (my_seek(info->file,pos_in_file,MY_SEEK_SET,MYF(0)) ==
|
||||||
|
MY_FILEPOS_ERROR)
|
||||||
|
{
|
||||||
|
info->error= 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
info->seek_not_done=0;
|
||||||
|
}
|
||||||
|
diff_length=(size_t) (pos_in_file & (IO_SIZE-1));
|
||||||
|
max_length=(info->read_length-diff_length);
|
||||||
|
if (max_length >= (info->end_of_file - pos_in_file))
|
||||||
|
max_length= (size_t) (info->end_of_file - pos_in_file);
|
||||||
|
|
||||||
|
if (!max_length)
|
||||||
|
{
|
||||||
|
info->error= 0;
|
||||||
|
return 0; /* EOF */
|
||||||
|
}
|
||||||
|
if ((length= my_read(info->file,info->buffer,max_length,
|
||||||
|
info->myflags)) == (size_t) -1)
|
||||||
|
{
|
||||||
|
info->error= -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
info->read_pos=info->buffer;
|
||||||
|
info->read_end=info->buffer+length;
|
||||||
|
info->pos_in_file=pos_in_file;
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Read a string ended by '\n' into a buffer of 'max_length' size.
|
||||||
|
Returns number of characters read, 0 on error.
|
||||||
|
last byte is set to '\0'
|
||||||
|
If buffer is full then to[max_length-1] will be set to \0.
|
||||||
|
*/
|
||||||
|
|
||||||
|
size_t my_b_gets(IO_CACHE *info, char *to, size_t max_length)
|
||||||
|
{
|
||||||
|
char *start = to;
|
||||||
|
size_t length;
|
||||||
|
max_length--; /* Save place for end \0 */
|
||||||
|
|
||||||
|
/* Calculate number of characters in buffer */
|
||||||
|
if (!(length= my_b_bytes_in_cache(info)) &&
|
||||||
|
!(length= my_b_fill(info)))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
uchar *pos, *end;
|
||||||
|
if (length > max_length)
|
||||||
|
length=max_length;
|
||||||
|
for (pos=info->read_pos,end=pos+length ; pos < end ;)
|
||||||
|
{
|
||||||
|
if ((*to++ = *pos++) == '\n')
|
||||||
|
{
|
||||||
|
info->read_pos=pos;
|
||||||
|
*to='\0';
|
||||||
|
return (size_t) (to-start);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!(max_length-=length))
|
||||||
|
{
|
||||||
|
/* Found enough charcters; Return found string */
|
||||||
|
info->read_pos=pos;
|
||||||
|
*to='\0';
|
||||||
|
return (size_t) (to-start);
|
||||||
|
}
|
||||||
|
if (!(length=my_b_fill(info)))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
my_off_t my_b_filelength(IO_CACHE *info)
|
||||||
|
{
|
||||||
|
if (info->type == WRITE_CACHE)
|
||||||
|
return my_b_tell(info);
|
||||||
|
|
||||||
|
info->seek_not_done= 1;
|
||||||
|
return my_seek(info->file, 0L, MY_SEEK_END, MYF(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Simple printf version. Supports '%s', '%d', '%u', "%ld" and "%lu"
|
||||||
|
Used for logging in MySQL
|
||||||
|
returns number of written character, or (size_t) -1 on error
|
||||||
|
*/
|
||||||
|
|
||||||
|
size_t my_b_printf(IO_CACHE *info, const char* fmt, ...)
|
||||||
|
{
|
||||||
|
size_t result;
|
||||||
|
va_list args;
|
||||||
|
va_start(args,fmt);
|
||||||
|
result=my_b_vprintf(info, fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t my_b_vprintf(IO_CACHE *info, const char* fmt, va_list args)
|
||||||
|
{
|
||||||
|
size_t out_length= 0;
|
||||||
|
uint minimum_width; /* as yet unimplemented */
|
||||||
|
uint minimum_width_sign;
|
||||||
|
uint precision; /* as yet unimplemented for anything but %b */
|
||||||
|
my_bool is_zero_padded;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Store the location of the beginning of a format directive, for the
|
||||||
|
case where we learn we shouldn't have been parsing a format string
|
||||||
|
at all, and we don't want to lose the flag/precision/width/size
|
||||||
|
information.
|
||||||
|
*/
|
||||||
|
const char* backtrack;
|
||||||
|
|
||||||
|
for (; *fmt != '\0'; fmt++)
|
||||||
|
{
|
||||||
|
/* Copy everything until '%' or end of string */
|
||||||
|
const char *start=fmt;
|
||||||
|
size_t length;
|
||||||
|
|
||||||
|
for (; (*fmt != '\0') && (*fmt != '%'); fmt++) ;
|
||||||
|
|
||||||
|
length= (size_t) (fmt - start);
|
||||||
|
out_length+=length;
|
||||||
|
if (my_b_write(info, (const uchar*) start, length))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
if (*fmt == '\0') /* End of format */
|
||||||
|
return out_length;
|
||||||
|
|
||||||
|
/*
|
||||||
|
By this point, *fmt must be a percent; Keep track of this location and
|
||||||
|
skip over the percent character.
|
||||||
|
*/
|
||||||
|
DBUG_ASSERT(*fmt == '%');
|
||||||
|
backtrack= fmt;
|
||||||
|
fmt++;
|
||||||
|
|
||||||
|
is_zero_padded= FALSE;
|
||||||
|
minimum_width_sign= 1;
|
||||||
|
minimum_width= 0;
|
||||||
|
precision= 0;
|
||||||
|
/* Skip if max size is used (to be compatible with printf) */
|
||||||
|
|
||||||
|
process_flags:
|
||||||
|
switch (*fmt)
|
||||||
|
{
|
||||||
|
case '-':
|
||||||
|
minimum_width_sign= -1; fmt++; goto process_flags;
|
||||||
|
case '0':
|
||||||
|
is_zero_padded= TRUE; fmt++; goto process_flags;
|
||||||
|
case '#':
|
||||||
|
/** @todo Implement "#" conversion flag. */ fmt++; goto process_flags;
|
||||||
|
case ' ':
|
||||||
|
/** @todo Implement " " conversion flag. */ fmt++; goto process_flags;
|
||||||
|
case '+':
|
||||||
|
/** @todo Implement "+" conversion flag. */ fmt++; goto process_flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*fmt == '*')
|
||||||
|
{
|
||||||
|
precision= (int) va_arg(args, int);
|
||||||
|
fmt++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (my_isdigit(&my_charset_latin1, *fmt)) {
|
||||||
|
minimum_width=(minimum_width * 10) + (*fmt - '0');
|
||||||
|
fmt++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
minimum_width*= minimum_width_sign;
|
||||||
|
|
||||||
|
if (*fmt == '.')
|
||||||
|
{
|
||||||
|
fmt++;
|
||||||
|
if (*fmt == '*') {
|
||||||
|
precision= (int) va_arg(args, int);
|
||||||
|
fmt++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (my_isdigit(&my_charset_latin1, *fmt)) {
|
||||||
|
precision=(precision * 10) + (*fmt - '0');
|
||||||
|
fmt++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*fmt == 's') /* String parameter */
|
||||||
|
{
|
||||||
|
reg2 char *par = va_arg(args, char *);
|
||||||
|
size_t length2 = strlen(par);
|
||||||
|
/* TODO: implement precision */
|
||||||
|
out_length+= length2;
|
||||||
|
if (my_b_write(info, (uchar*) par, length2))
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
else if (*fmt == 'b') /* Sized buffer parameter, only precision makes sense */
|
||||||
|
{
|
||||||
|
char *par = va_arg(args, char *);
|
||||||
|
out_length+= precision;
|
||||||
|
if (my_b_write(info, (uchar*) par, precision))
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
else if (*fmt == 'd' || *fmt == 'u') /* Integer parameter */
|
||||||
|
{
|
||||||
|
register int iarg;
|
||||||
|
size_t length2;
|
||||||
|
char buff[17];
|
||||||
|
|
||||||
|
iarg = va_arg(args, int);
|
||||||
|
if (*fmt == 'd')
|
||||||
|
length2= (size_t) (int10_to_str((long) iarg,buff, -10) - buff);
|
||||||
|
else
|
||||||
|
length2= (uint) (int10_to_str((long) (uint) iarg,buff,10)- buff);
|
||||||
|
|
||||||
|
/* minimum width padding */
|
||||||
|
if (minimum_width > length2)
|
||||||
|
{
|
||||||
|
char *buffz;
|
||||||
|
|
||||||
|
buffz= my_alloca(minimum_width - length2);
|
||||||
|
if (is_zero_padded)
|
||||||
|
memset(buffz, '0', minimum_width - length2);
|
||||||
|
else
|
||||||
|
memset(buffz, ' ', minimum_width - length2);
|
||||||
|
my_b_write(info, buffz, minimum_width - length2);
|
||||||
|
my_afree(buffz);
|
||||||
|
}
|
||||||
|
|
||||||
|
out_length+= length2;
|
||||||
|
if (my_b_write(info, (uchar*) buff, length2))
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
else if ((*fmt == 'l' && fmt[1] == 'd') || fmt[1] == 'u')
|
||||||
|
/* long parameter */
|
||||||
|
{
|
||||||
|
register long iarg;
|
||||||
|
size_t length2;
|
||||||
|
char buff[17];
|
||||||
|
|
||||||
|
iarg = va_arg(args, long);
|
||||||
|
if (*++fmt == 'd')
|
||||||
|
length2= (size_t) (int10_to_str(iarg,buff, -10) - buff);
|
||||||
|
else
|
||||||
|
length2= (size_t) (int10_to_str(iarg,buff,10)- buff);
|
||||||
|
out_length+= length2;
|
||||||
|
if (my_b_write(info, (uchar*) buff, length2))
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* %% or unknown code */
|
||||||
|
if (my_b_write(info, (uchar*) backtrack, (size_t) (fmt-backtrack)))
|
||||||
|
goto err;
|
||||||
|
out_length+= fmt-backtrack;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out_length;
|
||||||
|
|
||||||
|
err:
|
||||||
|
return (size_t) -1;
|
||||||
|
}
|
54
MySQL/mf_loadpath.c
Normal file
54
MySQL/mf_loadpath.c
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/* Copyright (C) 2000 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
#include "mysys_priv.h"
|
||||||
|
#include <m_string.h>
|
||||||
|
|
||||||
|
/* Returns full load-path for a file. to may be = path */
|
||||||
|
/* if path is a hard-path return path */
|
||||||
|
/* if path starts with home-dir return path */
|
||||||
|
/* if path starts with current dir or parent-dir unpack path */
|
||||||
|
/* if there is no path, prepend with own_path_prefix if given */
|
||||||
|
/* else unpack path according to current dir */
|
||||||
|
|
||||||
|
char * my_load_path(char * to, const char *path,
|
||||||
|
const char *own_path_prefix)
|
||||||
|
{
|
||||||
|
char buff[FN_REFLEN];
|
||||||
|
int is_cur;
|
||||||
|
DBUG_ENTER("my_load_path");
|
||||||
|
DBUG_PRINT("enter",("path: %s prefix: %s",path,
|
||||||
|
own_path_prefix ? own_path_prefix : ""));
|
||||||
|
|
||||||
|
if ((path[0] == FN_HOMELIB && path[1] == FN_LIBCHAR) ||
|
||||||
|
test_if_hard_path(path))
|
||||||
|
VOID(strmov(buff,path));
|
||||||
|
else if ((is_cur=(path[0] == FN_CURLIB && path[1] == FN_LIBCHAR)) ||
|
||||||
|
(is_prefix(path,FN_PARENTDIR)) ||
|
||||||
|
! own_path_prefix)
|
||||||
|
{
|
||||||
|
if (is_cur)
|
||||||
|
is_cur=2; /* Remove current dir */
|
||||||
|
if (! my_getwd(buff,(uint) (FN_REFLEN-strlen(path)+is_cur),MYF(0)))
|
||||||
|
VOID(strcat(buff,path+is_cur));
|
||||||
|
else
|
||||||
|
VOID(strmov(buff,path)); /* Return org file name */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
VOID(strxmov(buff,own_path_prefix,path,NullS));
|
||||||
|
strmov(to,buff);
|
||||||
|
DBUG_PRINT("exit",("to: %s",to));
|
||||||
|
DBUG_RETURN(to);
|
||||||
|
} /* my_load_path */
|
525
MySQL/mf_pack.c
Normal file
525
MySQL/mf_pack.c
Normal file
@ -0,0 +1,525 @@
|
|||||||
|
/* Copyright (C) 2000 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
#include "mysys_priv.h"
|
||||||
|
#include <m_string.h>
|
||||||
|
#ifdef HAVE_PWD_H
|
||||||
|
#include <pwd.h>
|
||||||
|
#endif
|
||||||
|
#ifdef VMS
|
||||||
|
#include <rms.h>
|
||||||
|
#include <iodef.h>
|
||||||
|
#include <descrip.h>
|
||||||
|
#endif /* VMS */
|
||||||
|
|
||||||
|
static char * NEAR_F expand_tilde(char * *path);
|
||||||
|
|
||||||
|
/* Pack a dirname ; Changes HOME to ~/ and current dev to ./ */
|
||||||
|
/* from is a dirname (from dirname() ?) ending with FN_LIBCHAR */
|
||||||
|
/* to may be == from */
|
||||||
|
|
||||||
|
void pack_dirname(char * to, const char *from)
|
||||||
|
{
|
||||||
|
int cwd_err;
|
||||||
|
size_t d_length,length,UNINIT_VAR(buff_length);
|
||||||
|
char * start;
|
||||||
|
char buff[FN_REFLEN];
|
||||||
|
DBUG_ENTER("pack_dirname");
|
||||||
|
|
||||||
|
(void) intern_filename(to,from); /* Change to intern name */
|
||||||
|
|
||||||
|
#ifdef FN_DEVCHAR
|
||||||
|
if ((start=strrchr(to,FN_DEVCHAR)) != 0) /* Skip device part */
|
||||||
|
start++;
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
start=to;
|
||||||
|
|
||||||
|
if (!(cwd_err= my_getwd(buff,FN_REFLEN,MYF(0))))
|
||||||
|
{
|
||||||
|
buff_length= strlen(buff);
|
||||||
|
d_length= (size_t) (start-to);
|
||||||
|
if ((start == to ||
|
||||||
|
(buff_length == d_length && !bcmp(buff,start,d_length))) &&
|
||||||
|
*start != FN_LIBCHAR && *start)
|
||||||
|
{ /* Put current dir before */
|
||||||
|
bchange((uchar*) to, d_length, (uchar*) buff, buff_length, strlen(to)+1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((d_length= cleanup_dirname(to,to)) != 0)
|
||||||
|
{
|
||||||
|
length=0;
|
||||||
|
if (home_dir)
|
||||||
|
{
|
||||||
|
length= strlen(home_dir);
|
||||||
|
if (home_dir[length-1] == FN_LIBCHAR)
|
||||||
|
length--; /* Don't test last '/' */
|
||||||
|
}
|
||||||
|
if (length > 1 && length < d_length)
|
||||||
|
{ /* test if /xx/yy -> ~/yy */
|
||||||
|
if (bcmp(to,home_dir,length) == 0 && to[length] == FN_LIBCHAR)
|
||||||
|
{
|
||||||
|
to[0]=FN_HOMELIB; /* Filename begins with ~ */
|
||||||
|
(void) strmov_overlapp(to+1,to+length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (! cwd_err)
|
||||||
|
{ /* Test if cwd is ~/... */
|
||||||
|
if (length > 1 && length < buff_length)
|
||||||
|
{
|
||||||
|
if (bcmp(buff,home_dir,length) == 0 && buff[length] == FN_LIBCHAR)
|
||||||
|
{
|
||||||
|
buff[0]=FN_HOMELIB;
|
||||||
|
(void) strmov_overlapp(buff+1,buff+length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (is_prefix(to,buff))
|
||||||
|
{
|
||||||
|
length= strlen(buff);
|
||||||
|
if (to[length])
|
||||||
|
(void) strmov_overlapp(to,to+length); /* Remove everything before */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
to[0]= FN_CURLIB; /* Put ./ instead of cwd */
|
||||||
|
to[1]= FN_LIBCHAR;
|
||||||
|
to[2]= '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DBUG_PRINT("exit",("to: '%s'",to));
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
} /* pack_dirname */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
remove unwanted chars from dirname
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
cleanup_dirname()
|
||||||
|
to Store result here
|
||||||
|
from Dirname to fix. May be same as to
|
||||||
|
|
||||||
|
IMPLEMENTATION
|
||||||
|
"/../" removes prev dir
|
||||||
|
"/~/" removes all before ~
|
||||||
|
//" is same as "/", except on Win32 at start of a file
|
||||||
|
"/./" is removed
|
||||||
|
Unpacks home_dir if "~/.." used
|
||||||
|
Unpacks current dir if if "./.." used
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
# length of new name
|
||||||
|
*/
|
||||||
|
|
||||||
|
size_t cleanup_dirname(register char *to, const char *from)
|
||||||
|
{
|
||||||
|
reg5 size_t length;
|
||||||
|
reg2 char * pos;
|
||||||
|
reg3 char * from_ptr;
|
||||||
|
reg4 char * start;
|
||||||
|
char parent[5], /* for "FN_PARENTDIR" */
|
||||||
|
buff[FN_REFLEN+1],*end_parentdir;
|
||||||
|
#ifdef BACKSLASH_MBTAIL
|
||||||
|
CHARSET_INFO *fs= fs_character_set();
|
||||||
|
#endif
|
||||||
|
DBUG_ENTER("cleanup_dirname");
|
||||||
|
DBUG_PRINT("enter",("from: '%s'",from));
|
||||||
|
|
||||||
|
start=buff;
|
||||||
|
from_ptr=(char *) from;
|
||||||
|
#ifdef FN_DEVCHAR
|
||||||
|
if ((pos=strrchr(from_ptr,FN_DEVCHAR)) != 0)
|
||||||
|
{ /* Skip device part */
|
||||||
|
length=(size_t) (pos-from_ptr)+1;
|
||||||
|
start=strnmov(buff,from_ptr,length); from_ptr+=length;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
parent[0]=FN_LIBCHAR;
|
||||||
|
length=(size_t) (strmov(parent+1,FN_PARENTDIR)-parent);
|
||||||
|
for (pos=start ; (*pos= *from_ptr++) != 0 ; pos++)
|
||||||
|
{
|
||||||
|
#ifdef BACKSLASH_MBTAIL
|
||||||
|
uint l;
|
||||||
|
if (use_mb(fs) && (l= my_ismbchar(fs, from_ptr - 1, from_ptr + 2)))
|
||||||
|
{
|
||||||
|
for (l-- ; l ; *++pos= *from_ptr++, l--);
|
||||||
|
start= pos + 1; /* Don't look inside multi-byte char */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (*pos == '/')
|
||||||
|
*pos = FN_LIBCHAR;
|
||||||
|
if (*pos == FN_LIBCHAR)
|
||||||
|
{
|
||||||
|
if ((size_t) (pos-start) > length && bcmp(pos-length,parent,length) == 0)
|
||||||
|
{ /* If .../../; skip prev */
|
||||||
|
pos-=length;
|
||||||
|
if (pos != start)
|
||||||
|
{ /* not /../ */
|
||||||
|
pos--;
|
||||||
|
if (*pos == FN_HOMELIB && (pos == start || pos[-1] == FN_LIBCHAR))
|
||||||
|
{
|
||||||
|
if (!home_dir)
|
||||||
|
{
|
||||||
|
pos+=length+1; /* Don't unpack ~/.. */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
pos=strmov(buff,home_dir)-1; /* Unpacks ~/.. */
|
||||||
|
if (*pos == FN_LIBCHAR)
|
||||||
|
pos--; /* home ended with '/' */
|
||||||
|
}
|
||||||
|
if (*pos == FN_CURLIB && (pos == start || pos[-1] == FN_LIBCHAR))
|
||||||
|
{
|
||||||
|
if (my_getwd(curr_dir,FN_REFLEN,MYF(0)))
|
||||||
|
{
|
||||||
|
pos+=length+1; /* Don't unpack ./.. */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
pos=strmov(buff,curr_dir)-1; /* Unpacks ./.. */
|
||||||
|
if (*pos == FN_LIBCHAR)
|
||||||
|
pos--; /* home ended with '/' */
|
||||||
|
}
|
||||||
|
end_parentdir=pos;
|
||||||
|
while (pos >= start && *pos != FN_LIBCHAR) /* remove prev dir */
|
||||||
|
pos--;
|
||||||
|
if (pos[1] == FN_HOMELIB || bcmp(pos,parent,length) == 0)
|
||||||
|
{ /* Don't remove ~user/ */
|
||||||
|
pos=strmov(end_parentdir+1,parent);
|
||||||
|
*pos=FN_LIBCHAR;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((size_t) (pos-start) == length-1 &&
|
||||||
|
!bcmp(start,parent+1,length-1))
|
||||||
|
start=pos; /* Starts with "../" */
|
||||||
|
else if (pos-start > 0 && pos[-1] == FN_LIBCHAR)
|
||||||
|
{
|
||||||
|
#ifdef FN_NETWORK_DRIVES
|
||||||
|
if (pos-start != 1)
|
||||||
|
#endif
|
||||||
|
pos--; /* Remove dupplicate '/' */
|
||||||
|
}
|
||||||
|
else if (pos-start > 1 && pos[-1] == FN_CURLIB && pos[-2] == FN_LIBCHAR)
|
||||||
|
pos-=2; /* Skip /./ */
|
||||||
|
else if (pos > buff+1 && pos[-1] == FN_HOMELIB && pos[-2] == FN_LIBCHAR)
|
||||||
|
{ /* Found ..../~/ */
|
||||||
|
buff[0]=FN_HOMELIB;
|
||||||
|
buff[1]=FN_LIBCHAR;
|
||||||
|
start=buff; pos=buff+1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(void) strmov(to,buff);
|
||||||
|
DBUG_PRINT("exit",("to: '%s'",to));
|
||||||
|
DBUG_RETURN((size_t) (pos-buff));
|
||||||
|
} /* cleanup_dirname */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
On system where you don't have symbolic links, the following
|
||||||
|
code will allow you to create a file:
|
||||||
|
directory-name.sym that should contain the real path
|
||||||
|
to the directory. This will be used if the directory name
|
||||||
|
doesn't exists
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
my_bool my_use_symdir=0; /* Set this if you want to use symdirs */
|
||||||
|
|
||||||
|
#ifdef USE_SYMDIR
|
||||||
|
void symdirget(char *dir)
|
||||||
|
{
|
||||||
|
char buff[FN_REFLEN];
|
||||||
|
char *pos=strend(dir);
|
||||||
|
if (dir[0] && pos[-1] != FN_DEVCHAR && my_access(dir, F_OK))
|
||||||
|
{
|
||||||
|
File file;
|
||||||
|
size_t length;
|
||||||
|
char temp= *(--pos); /* May be "/" or "\" */
|
||||||
|
strmov(pos,".sym");
|
||||||
|
file= my_open(dir, O_RDONLY, MYF(0));
|
||||||
|
*pos++=temp; *pos=0; /* Restore old filename */
|
||||||
|
if (file >= 0)
|
||||||
|
{
|
||||||
|
if ((length= my_read(file, buff, sizeof(buff), MYF(0))) > 0)
|
||||||
|
{
|
||||||
|
for (pos= buff + length ;
|
||||||
|
pos > buff && (iscntrl(pos[-1]) || isspace(pos[-1])) ;
|
||||||
|
pos --);
|
||||||
|
|
||||||
|
/* Ensure that the symlink ends with the directory symbol */
|
||||||
|
if (pos == buff || pos[-1] != FN_LIBCHAR)
|
||||||
|
*pos++=FN_LIBCHAR;
|
||||||
|
|
||||||
|
strmake(dir,buff, (size_t) (pos-buff));
|
||||||
|
}
|
||||||
|
my_close(file, MYF(0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* USE_SYMDIR */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Convert a directory name to a format which can be compared as strings
|
||||||
|
|
||||||
|
@param to result buffer, FN_REFLEN chars in length; may be == from
|
||||||
|
@param from 'packed' directory name, in whatever format
|
||||||
|
@returns size of the normalized name
|
||||||
|
|
||||||
|
@details
|
||||||
|
- Ensures that last char is FN_LIBCHAR, unless it is FN_DEVCHAR
|
||||||
|
- Uses cleanup_dirname
|
||||||
|
|
||||||
|
It does *not* expand ~/ (although, see cleanup_dirname). Nor does it do
|
||||||
|
any case folding. All case-insensitive normalization should be done by
|
||||||
|
the caller.
|
||||||
|
*/
|
||||||
|
|
||||||
|
size_t normalize_dirname(char *to, const char *from)
|
||||||
|
{
|
||||||
|
size_t length;
|
||||||
|
char buff[FN_REFLEN];
|
||||||
|
DBUG_ENTER("normalize_dirname");
|
||||||
|
|
||||||
|
/*
|
||||||
|
Despite the name, this actually converts the name to the system's
|
||||||
|
format (TODO: rip out the non-working VMS stuff and name this
|
||||||
|
properly).
|
||||||
|
*/
|
||||||
|
(void) intern_filename(buff, from);
|
||||||
|
length= strlen(buff); /* Fix that '/' is last */
|
||||||
|
if (length &&
|
||||||
|
#ifdef FN_DEVCHAR
|
||||||
|
buff[length - 1] != FN_DEVCHAR &&
|
||||||
|
#endif
|
||||||
|
buff[length - 1] != FN_LIBCHAR && buff[length - 1] != '/')
|
||||||
|
{
|
||||||
|
buff[length]= FN_LIBCHAR;
|
||||||
|
buff[length + 1]= '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
length=cleanup_dirname(to, buff);
|
||||||
|
|
||||||
|
DBUG_RETURN(length);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Fixes a directory name so that can be used by open()
|
||||||
|
|
||||||
|
@param to Result buffer, FN_REFLEN characters. May be == from
|
||||||
|
@param from 'Packed' directory name (may contain ~)
|
||||||
|
|
||||||
|
@details
|
||||||
|
- Uses normalize_dirname()
|
||||||
|
- Expands ~/... to home_dir/...
|
||||||
|
- Resolves MySQL's fake "foo.sym" symbolic directory names (if USE_SYMDIR)
|
||||||
|
- Changes a UNIX filename to system filename (replaces / with \ on windows)
|
||||||
|
|
||||||
|
@returns
|
||||||
|
Length of new directory name (= length of to)
|
||||||
|
*/
|
||||||
|
|
||||||
|
size_t unpack_dirname(char * to, const char *from)
|
||||||
|
{
|
||||||
|
size_t length, h_length;
|
||||||
|
char buff[FN_REFLEN+1+4],*suffix,*tilde_expansion;
|
||||||
|
DBUG_ENTER("unpack_dirname");
|
||||||
|
|
||||||
|
length= normalize_dirname(buff, from);
|
||||||
|
|
||||||
|
if (buff[0] == FN_HOMELIB)
|
||||||
|
{
|
||||||
|
suffix=buff+1; tilde_expansion=expand_tilde(&suffix);
|
||||||
|
if (tilde_expansion)
|
||||||
|
{
|
||||||
|
length-= (size_t) (suffix-buff)-1;
|
||||||
|
if (length+(h_length= strlen(tilde_expansion)) <= FN_REFLEN)
|
||||||
|
{
|
||||||
|
if ((h_length > 0) && (tilde_expansion[h_length-1] == FN_LIBCHAR))
|
||||||
|
h_length--;
|
||||||
|
if (buff+h_length < suffix)
|
||||||
|
bmove(buff+h_length,suffix,length);
|
||||||
|
else
|
||||||
|
bmove_upp((uchar*) buff+h_length+length, (uchar*) suffix+length, length);
|
||||||
|
bmove(buff,tilde_expansion,h_length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifdef USE_SYMDIR
|
||||||
|
if (my_use_symdir)
|
||||||
|
symdirget(buff);
|
||||||
|
#endif
|
||||||
|
DBUG_RETURN(system_filename(to,buff)); /* Fix for open */
|
||||||
|
} /* unpack_dirname */
|
||||||
|
|
||||||
|
|
||||||
|
/* Expand tilde to home or user-directory */
|
||||||
|
/* Path is reset to point at FN_LIBCHAR after ~xxx */
|
||||||
|
|
||||||
|
static char * NEAR_F expand_tilde(char * *path)
|
||||||
|
{
|
||||||
|
if (path[0][0] == FN_LIBCHAR)
|
||||||
|
return home_dir; /* ~/ expanded to home */
|
||||||
|
#ifdef HAVE_GETPWNAM
|
||||||
|
{
|
||||||
|
char *str,save;
|
||||||
|
struct passwd *user_entry;
|
||||||
|
|
||||||
|
if (!(str=strchr(*path,FN_LIBCHAR)))
|
||||||
|
str=strend(*path);
|
||||||
|
save= *str; *str= '\0';
|
||||||
|
user_entry=getpwnam(*path);
|
||||||
|
*str=save;
|
||||||
|
endpwent();
|
||||||
|
if (user_entry)
|
||||||
|
{
|
||||||
|
*path=str;
|
||||||
|
return user_entry->pw_dir;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return (char *) 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Fix filename so it can be used by open, create
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
unpack_filename()
|
||||||
|
to Store result here. Must be at least of size FN_REFLEN.
|
||||||
|
from Filename in unix format (with ~)
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
# length of to
|
||||||
|
|
||||||
|
NOTES
|
||||||
|
to may be == from
|
||||||
|
~ will only be expanded if total length < FN_REFLEN
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
size_t unpack_filename(char * to, const char *from)
|
||||||
|
{
|
||||||
|
size_t length, n_length, buff_length;
|
||||||
|
char buff[FN_REFLEN];
|
||||||
|
DBUG_ENTER("unpack_filename");
|
||||||
|
|
||||||
|
length=dirname_part(buff, from, &buff_length);/* copy & convert dirname */
|
||||||
|
n_length=unpack_dirname(buff,buff);
|
||||||
|
if (n_length+strlen(from+length) < FN_REFLEN)
|
||||||
|
{
|
||||||
|
(void) strmov(buff+n_length,from+length);
|
||||||
|
length= system_filename(to,buff); /* Fix to usably filename */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
length= system_filename(to,from); /* Fix to usably filename */
|
||||||
|
DBUG_RETURN(length);
|
||||||
|
} /* unpack_filename */
|
||||||
|
|
||||||
|
|
||||||
|
/* Convert filename (unix standard) to system standard */
|
||||||
|
/* Used before system command's like open(), create() .. */
|
||||||
|
/* Returns used length of to; total length should be FN_REFLEN */
|
||||||
|
|
||||||
|
size_t system_filename(char * to, const char *from)
|
||||||
|
{
|
||||||
|
#ifndef FN_C_BEFORE_DIR
|
||||||
|
return (size_t) (strmake(to,from,FN_REFLEN-1)-to);
|
||||||
|
#else /* VMS */
|
||||||
|
|
||||||
|
/* change 'dev:lib/xxx' to 'dev:[lib]xxx' */
|
||||||
|
/* change 'dev:xxx' to 'dev:xxx' */
|
||||||
|
/* change './xxx' to 'xxx' */
|
||||||
|
/* change './lib/' or lib/ to '[.lib]' */
|
||||||
|
/* change '/x/y/z to '[x.y]x' */
|
||||||
|
/* change 'dev:/x' to 'dev:[000000]x' */
|
||||||
|
|
||||||
|
int libchar_found;
|
||||||
|
size_t length;
|
||||||
|
char * to_pos,from_pos,pos;
|
||||||
|
char buff[FN_REFLEN];
|
||||||
|
DBUG_ENTER("system_filename");
|
||||||
|
|
||||||
|
libchar_found=0;
|
||||||
|
(void) strmov(buff,from); /* If to == from */
|
||||||
|
from_pos= buff;
|
||||||
|
if ((pos=strrchr(from_pos,FN_DEVCHAR))) /* Skip device part */
|
||||||
|
{
|
||||||
|
pos++;
|
||||||
|
to_pos=strnmov(to,from_pos,(size_t) (pos-from_pos));
|
||||||
|
from_pos=pos;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
to_pos=to;
|
||||||
|
|
||||||
|
if (from_pos[0] == FN_CURLIB && from_pos[1] == FN_LIBCHAR)
|
||||||
|
from_pos+=2; /* Skip './' */
|
||||||
|
if (strchr(from_pos,FN_LIBCHAR))
|
||||||
|
{
|
||||||
|
*(to_pos++) = FN_C_BEFORE_DIR;
|
||||||
|
if (strinstr(from_pos,FN_ROOTDIR) == 1)
|
||||||
|
{
|
||||||
|
from_pos+=strlen(FN_ROOTDIR); /* Actually +1 but... */
|
||||||
|
if (! strchr(from_pos,FN_LIBCHAR))
|
||||||
|
{ /* No dir, use [000000] */
|
||||||
|
to_pos=strmov(to_pos,FN_C_ROOT_DIR);
|
||||||
|
libchar_found++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*(to_pos++)=FN_C_DIR_SEP; /* '.' gives current dir */
|
||||||
|
|
||||||
|
while ((pos=strchr(from_pos,FN_LIBCHAR)))
|
||||||
|
{
|
||||||
|
if (libchar_found++)
|
||||||
|
*(to_pos++)=FN_C_DIR_SEP; /* Add '.' between dirs */
|
||||||
|
if (strinstr(from_pos,FN_PARENTDIR) == 1 &&
|
||||||
|
from_pos+strlen(FN_PARENTDIR) == pos)
|
||||||
|
to_pos=strmov(to_pos,FN_C_PARENT_DIR); /* Found '../' */
|
||||||
|
else
|
||||||
|
to_pos=strnmov(to_pos,from_pos,(size_t) (pos-from_pos));
|
||||||
|
from_pos=pos+1;
|
||||||
|
}
|
||||||
|
*(to_pos++)=FN_C_AFTER_DIR;
|
||||||
|
}
|
||||||
|
length= (size_t) (strmov(to_pos,from_pos)-to);
|
||||||
|
DBUG_PRINT("exit",("name: '%s'",to));
|
||||||
|
DBUG_RETURN(length);
|
||||||
|
#endif
|
||||||
|
} /* system_filename */
|
||||||
|
|
||||||
|
|
||||||
|
/* Fix a filename to intern (UNIX format) */
|
||||||
|
|
||||||
|
char *intern_filename(char *to, const char *from)
|
||||||
|
{
|
||||||
|
size_t length, to_length;
|
||||||
|
char buff[FN_REFLEN];
|
||||||
|
if (from == to)
|
||||||
|
{ /* Dirname may destroy from */
|
||||||
|
strmov(buff,from);
|
||||||
|
from=buff;
|
||||||
|
}
|
||||||
|
length= dirname_part(to, from, &to_length); /* Copy dirname & fix chars */
|
||||||
|
(void) strmov(to + to_length,from+length);
|
||||||
|
return (to);
|
||||||
|
} /* intern_filename */
|
123
MySQL/mf_path.c
Normal file
123
MySQL/mf_path.c
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
/* Copyright (C) 2000 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
#include "mysys_priv.h"
|
||||||
|
#include <m_string.h>
|
||||||
|
|
||||||
|
static char *find_file_in_path(char *to,const char *name);
|
||||||
|
|
||||||
|
/* Finds where program can find it's files.
|
||||||
|
pre_pathname is found by first locking at progname (argv[0]).
|
||||||
|
if progname contains path the path is returned.
|
||||||
|
else if progname is found in path, return it
|
||||||
|
else if progname is given and POSIX environment variable "_" is set
|
||||||
|
then path is taken from "_".
|
||||||
|
If filename doesn't contain a path append MY_BASEDIR_VERSION or
|
||||||
|
MY_BASEDIR if defined, else append "/my/running".
|
||||||
|
own_path_name_part is concatinated to result.
|
||||||
|
my_path puts result in to and returns to */
|
||||||
|
|
||||||
|
char * my_path(char * to, const char *progname,
|
||||||
|
const char *own_pathname_part)
|
||||||
|
{
|
||||||
|
char *start, *end, *prog;
|
||||||
|
size_t to_length;
|
||||||
|
DBUG_ENTER("my_path");
|
||||||
|
|
||||||
|
start=to; /* Return this */
|
||||||
|
if (progname && (dirname_part(to, progname, &to_length) ||
|
||||||
|
find_file_in_path(to,progname) ||
|
||||||
|
((prog=getenv("_")) != 0 &&
|
||||||
|
dirname_part(to, prog, &to_length))))
|
||||||
|
{
|
||||||
|
VOID(intern_filename(to,to));
|
||||||
|
if (!test_if_hard_path(to))
|
||||||
|
{
|
||||||
|
if (!my_getwd(curr_dir,FN_REFLEN,MYF(0)))
|
||||||
|
bchange((uchar*) to, 0, (uchar*) curr_dir, strlen(curr_dir), strlen(to)+1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ((end = getenv("MY_BASEDIR_VERSION")) == 0 &&
|
||||||
|
(end = getenv("MY_BASEDIR")) == 0)
|
||||||
|
{
|
||||||
|
#ifdef DEFAULT_BASEDIR
|
||||||
|
end= (char*) DEFAULT_BASEDIR;
|
||||||
|
#else
|
||||||
|
end= (char*) "/my/";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
VOID(intern_filename(to,end));
|
||||||
|
to=strend(to);
|
||||||
|
if (to != start && to[-1] != FN_LIBCHAR)
|
||||||
|
*to++ = FN_LIBCHAR;
|
||||||
|
VOID(strmov(to,own_pathname_part));
|
||||||
|
}
|
||||||
|
DBUG_PRINT("exit",("to: '%s'",start));
|
||||||
|
DBUG_RETURN(start);
|
||||||
|
} /* my_path */
|
||||||
|
|
||||||
|
|
||||||
|
/* test if file without filename is found in path */
|
||||||
|
/* Returns to if found and to has dirpart if found, else NullS */
|
||||||
|
|
||||||
|
#if defined(__WIN__)
|
||||||
|
#define F_OK 0
|
||||||
|
#define PATH_SEP ';'
|
||||||
|
#define PROGRAM_EXTENSION ".exe"
|
||||||
|
#elif defined(__NETWARE__)
|
||||||
|
#define PATH_SEP ';'
|
||||||
|
#define PROGRAM_EXTENSION ".nlm"
|
||||||
|
#else
|
||||||
|
#define PATH_SEP ':'
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static char *find_file_in_path(char *to, const char *name)
|
||||||
|
{
|
||||||
|
char *path,*pos,dir[2];
|
||||||
|
const char *ext="";
|
||||||
|
|
||||||
|
if (!(path=getenv("PATH")))
|
||||||
|
return NullS;
|
||||||
|
dir[0]=FN_LIBCHAR; dir[1]=0;
|
||||||
|
#ifdef PROGRAM_EXTENSION
|
||||||
|
if (!fn_ext(name)[0])
|
||||||
|
ext=PROGRAM_EXTENSION;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (pos=path ; (pos=strchr(pos,PATH_SEP)) ; path= ++pos)
|
||||||
|
{
|
||||||
|
if (path != pos)
|
||||||
|
{
|
||||||
|
strxmov(strnmov(to,path,(uint) (pos-path)),dir,name,ext,NullS);
|
||||||
|
if (!access(to,F_OK))
|
||||||
|
{
|
||||||
|
to[(uint) (pos-path)+1]=0; /* Return path only */
|
||||||
|
return to;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifdef __WIN__
|
||||||
|
to[0]=FN_CURLIB;
|
||||||
|
strxmov(to+1,dir,name,ext,NullS);
|
||||||
|
if (!access(to,F_OK)) /* Test in current dir */
|
||||||
|
{
|
||||||
|
to[2]=0; /* Leave ".\" */
|
||||||
|
return to;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return NullS; /* File not found */
|
||||||
|
}
|
216
MySQL/mf_qsort.c
Normal file
216
MySQL/mf_qsort.c
Normal file
@ -0,0 +1,216 @@
|
|||||||
|
/* Copyright (C) 2000 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
/*
|
||||||
|
qsort implementation optimized for comparison of pointers
|
||||||
|
Inspired by the qsort implementations by Douglas C. Schmidt,
|
||||||
|
and Bentley & McIlroy's "Engineering a Sort Function".
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "mysys_priv.h"
|
||||||
|
#ifndef SCO
|
||||||
|
#include <m_string.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* We need to use qsort with 2 different compare functions */
|
||||||
|
#ifdef QSORT_EXTRA_CMP_ARGUMENT
|
||||||
|
#define CMP(A,B) ((*cmp)(cmp_argument,(A),(B)))
|
||||||
|
#else
|
||||||
|
#define CMP(A,B) ((*cmp)((A),(B)))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SWAP(A, B, size,swap_ptrs) \
|
||||||
|
do { \
|
||||||
|
if (swap_ptrs) \
|
||||||
|
{ \
|
||||||
|
reg1 char **a = (char**) (A), **b = (char**) (B); \
|
||||||
|
char *tmp = *a; *a++ = *b; *b++ = tmp; \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
reg1 char *a = (A), *b = (B); \
|
||||||
|
reg3 char *end= a+size; \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
char tmp = *a; *a++ = *b; *b++ = tmp; \
|
||||||
|
} while (a < end); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/* Put the median in the middle argument */
|
||||||
|
#define MEDIAN(low, mid, high) \
|
||||||
|
{ \
|
||||||
|
if (CMP(high,low) < 0) \
|
||||||
|
SWAP(high, low, size, ptr_cmp); \
|
||||||
|
if (CMP(mid, low) < 0) \
|
||||||
|
SWAP(mid, low, size, ptr_cmp); \
|
||||||
|
else if (CMP(high, mid) < 0) \
|
||||||
|
SWAP(mid, high, size, ptr_cmp); \
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The following node is used to store ranges to avoid recursive calls */
|
||||||
|
|
||||||
|
typedef struct st_stack
|
||||||
|
{
|
||||||
|
char *low,*high;
|
||||||
|
} stack_node;
|
||||||
|
|
||||||
|
#define PUSH(LOW,HIGH) {stack_ptr->low = LOW; stack_ptr++->high = HIGH;}
|
||||||
|
#define POP(LOW,HIGH) {LOW = (--stack_ptr)->low; HIGH = stack_ptr->high;}
|
||||||
|
|
||||||
|
/* The following stack size is enough for ulong ~0 elements */
|
||||||
|
#define STACK_SIZE (8 * sizeof(unsigned long int))
|
||||||
|
#define THRESHOLD_FOR_INSERT_SORT 10
|
||||||
|
#if defined(QSORT_TYPE_IS_VOID)
|
||||||
|
#define SORT_RETURN return
|
||||||
|
#else
|
||||||
|
#define SORT_RETURN return 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
** 'standard' quicksort with the following extensions:
|
||||||
|
**
|
||||||
|
** Can be compiled with the qsort2_cmp compare function
|
||||||
|
** Store ranges on stack to avoid recursion
|
||||||
|
** Use insert sort on small ranges
|
||||||
|
** Optimize for sorting of pointers (used often by MySQL)
|
||||||
|
** Use median comparison to find partition element
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef QSORT_EXTRA_CMP_ARGUMENT
|
||||||
|
qsort_t my_qsort2(void *base_ptr, size_t count, size_t size, qsort2_cmp cmp,
|
||||||
|
void *cmp_argument)
|
||||||
|
#else
|
||||||
|
qsort_t my_qsort(void *base_ptr, size_t count, size_t size, qsort_cmp cmp)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
char *low, *high, *pivot;
|
||||||
|
stack_node stack[STACK_SIZE], *stack_ptr;
|
||||||
|
my_bool ptr_cmp;
|
||||||
|
/* Handle the simple case first */
|
||||||
|
/* This will also make the rest of the code simpler */
|
||||||
|
if (count <= 1)
|
||||||
|
SORT_RETURN;
|
||||||
|
|
||||||
|
low = (char*) base_ptr;
|
||||||
|
high = low+ size * (count - 1);
|
||||||
|
stack_ptr = stack + 1;
|
||||||
|
#ifdef HAVE_purify
|
||||||
|
/* The first element in the stack will be accessed for the last POP */
|
||||||
|
stack[0].low=stack[0].high=0;
|
||||||
|
#endif
|
||||||
|
pivot = (char *) my_alloca((int) size);
|
||||||
|
ptr_cmp= size == sizeof(char*) && !((low - (char*) 0)& (sizeof(char*)-1));
|
||||||
|
|
||||||
|
/* The following loop sorts elements between high and low */
|
||||||
|
do
|
||||||
|
{
|
||||||
|
char *low_ptr, *high_ptr, *mid;
|
||||||
|
|
||||||
|
count=((size_t) (high - low) / size)+1;
|
||||||
|
/* If count is small, then an insert sort is faster than qsort */
|
||||||
|
if (count < THRESHOLD_FOR_INSERT_SORT)
|
||||||
|
{
|
||||||
|
for (low_ptr = low + size; low_ptr <= high; low_ptr += size)
|
||||||
|
{
|
||||||
|
char *ptr;
|
||||||
|
for (ptr = low_ptr; ptr > low && CMP(ptr - size, ptr) > 0;
|
||||||
|
ptr -= size)
|
||||||
|
SWAP(ptr, ptr - size, size, ptr_cmp);
|
||||||
|
}
|
||||||
|
POP(low, high);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Try to find a good middle element */
|
||||||
|
mid= low + size * (count >> 1);
|
||||||
|
if (count > 40) /* Must be bigger than 24 */
|
||||||
|
{
|
||||||
|
size_t step = size* (count / 8);
|
||||||
|
MEDIAN(low, low + step, low+step*2);
|
||||||
|
MEDIAN(mid - step, mid, mid+step);
|
||||||
|
MEDIAN(high - 2 * step, high-step, high);
|
||||||
|
/* Put best median in 'mid' */
|
||||||
|
MEDIAN(low+step, mid, high-step);
|
||||||
|
low_ptr = low;
|
||||||
|
high_ptr = high;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MEDIAN(low, mid, high);
|
||||||
|
/* The low and high argument are already in sorted against 'pivot' */
|
||||||
|
low_ptr = low + size;
|
||||||
|
high_ptr = high - size;
|
||||||
|
}
|
||||||
|
memcpy(pivot, mid, size);
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
while (CMP(low_ptr, pivot) < 0)
|
||||||
|
low_ptr += size;
|
||||||
|
while (CMP(pivot, high_ptr) < 0)
|
||||||
|
high_ptr -= size;
|
||||||
|
|
||||||
|
if (low_ptr < high_ptr)
|
||||||
|
{
|
||||||
|
SWAP(low_ptr, high_ptr, size, ptr_cmp);
|
||||||
|
low_ptr += size;
|
||||||
|
high_ptr -= size;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (low_ptr == high_ptr)
|
||||||
|
{
|
||||||
|
low_ptr += size;
|
||||||
|
high_ptr -= size;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (low_ptr <= high_ptr);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Prepare for next iteration.
|
||||||
|
Skip partitions of size 1 as these doesn't have to be sorted
|
||||||
|
Push the larger partition and sort the smaller one first.
|
||||||
|
This ensures that the stack is keept small.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ((int) (high_ptr - low) <= 0)
|
||||||
|
{
|
||||||
|
if ((int) (high - low_ptr) <= 0)
|
||||||
|
{
|
||||||
|
POP(low, high); /* Nothing more to sort */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
low = low_ptr; /* Ignore small left part. */
|
||||||
|
}
|
||||||
|
else if ((int) (high - low_ptr) <= 0)
|
||||||
|
high = high_ptr; /* Ignore small right part. */
|
||||||
|
else if ((high_ptr - low) > (high - low_ptr))
|
||||||
|
{
|
||||||
|
PUSH(low, high_ptr); /* Push larger left part */
|
||||||
|
low = low_ptr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PUSH(low_ptr, high); /* Push larger right part */
|
||||||
|
high = high_ptr;
|
||||||
|
}
|
||||||
|
} while (stack_ptr > stack);
|
||||||
|
my_afree(pivot);
|
||||||
|
SORT_RETURN;
|
||||||
|
}
|
189
MySQL/mf_tempfile.c
Normal file
189
MySQL/mf_tempfile.c
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
/* Copyright (C) 2000 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
#include "mysys_priv.h"
|
||||||
|
#include <m_string.h>
|
||||||
|
#include "my_static.h"
|
||||||
|
#include "mysys_err.h"
|
||||||
|
#include <errno.h>
|
||||||
|
#ifdef HAVE_PATHS_H
|
||||||
|
#include <paths.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
@brief
|
||||||
|
Create a temporary file with unique name in a given directory
|
||||||
|
|
||||||
|
@details
|
||||||
|
create_temp_file
|
||||||
|
to pointer to buffer where temporary filename will be stored
|
||||||
|
dir directory where to create the file
|
||||||
|
prefix prefix the filename with this
|
||||||
|
mode Flags to use for my_create/my_open
|
||||||
|
MyFlags Magic flags
|
||||||
|
|
||||||
|
@return
|
||||||
|
File descriptor of opened file if success
|
||||||
|
-1 and sets errno if fails.
|
||||||
|
|
||||||
|
@note
|
||||||
|
The behaviour of this function differs a lot between
|
||||||
|
implementation, it's main use is to generate a file with
|
||||||
|
a name that does not already exist.
|
||||||
|
|
||||||
|
When passing O_TEMPORARY flag in "mode" the file should
|
||||||
|
be automatically deleted
|
||||||
|
|
||||||
|
The implementation using mkstemp should be considered the
|
||||||
|
reference implementation when adding a new or modifying an
|
||||||
|
existing one
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
File create_temp_file(char *to, const char *dir, const char *prefix,
|
||||||
|
int mode __attribute__((unused)),
|
||||||
|
myf MyFlags __attribute__((unused)))
|
||||||
|
{
|
||||||
|
File file= -1;
|
||||||
|
#ifdef __WIN__
|
||||||
|
TCHAR path_buf[MAX_PATH-14];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DBUG_ENTER("create_temp_file");
|
||||||
|
DBUG_PRINT("enter", ("dir: %s, prefix: %s", dir, prefix));
|
||||||
|
#if defined (__WIN__)
|
||||||
|
|
||||||
|
/*
|
||||||
|
Use GetTempPath to determine path for temporary files.
|
||||||
|
This is because the documentation for GetTempFileName
|
||||||
|
has the following to say about this parameter:
|
||||||
|
"If this parameter is NULL, the function fails."
|
||||||
|
*/
|
||||||
|
if (!dir)
|
||||||
|
{
|
||||||
|
if(GetTempPath(sizeof(path_buf), path_buf) > 0)
|
||||||
|
dir = path_buf;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
Use GetTempFileName to generate a unique filename, create
|
||||||
|
the file and release it's handle
|
||||||
|
- uses up to the first three letters from prefix
|
||||||
|
*/
|
||||||
|
if (GetTempFileName(dir, prefix, 0, to) == 0)
|
||||||
|
DBUG_RETURN(-1);
|
||||||
|
|
||||||
|
DBUG_PRINT("info", ("name: %s", to));
|
||||||
|
|
||||||
|
/*
|
||||||
|
Open the file without the "open only if file doesn't already exist"
|
||||||
|
since the file has already been created by GetTempFileName
|
||||||
|
*/
|
||||||
|
if ((file= my_open(to, (mode & ~O_EXCL), MyFlags)) < 0)
|
||||||
|
{
|
||||||
|
/* Open failed, remove the file created by GetTempFileName */
|
||||||
|
int tmp= my_errno;
|
||||||
|
(void) my_delete(to, MYF(0));
|
||||||
|
my_errno= tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(_ZTC__)
|
||||||
|
if (!dir)
|
||||||
|
dir=getenv("TMPDIR");
|
||||||
|
if ((res=tempnam((char*) dir,(char *) prefix)))
|
||||||
|
{
|
||||||
|
strmake(to,res,FN_REFLEN-1);
|
||||||
|
(*free)(res);
|
||||||
|
file=my_create(to, 0, mode | O_EXCL | O_NOFOLLOW, MyFlags);
|
||||||
|
}
|
||||||
|
#elif defined(HAVE_MKSTEMP) && !defined(__NETWARE__)
|
||||||
|
{
|
||||||
|
char prefix_buff[30];
|
||||||
|
uint pfx_len;
|
||||||
|
File org_file;
|
||||||
|
|
||||||
|
pfx_len= (uint) (strmov(strnmov(prefix_buff,
|
||||||
|
prefix ? prefix : "tmp.",
|
||||||
|
sizeof(prefix_buff)-7),"XXXXXX") -
|
||||||
|
prefix_buff);
|
||||||
|
if (!dir && ! (dir =getenv("TMPDIR")))
|
||||||
|
dir=P_tmpdir;
|
||||||
|
if (strlen(dir)+ pfx_len > FN_REFLEN-2)
|
||||||
|
{
|
||||||
|
errno=my_errno= ENAMETOOLONG;
|
||||||
|
DBUG_RETURN(file);
|
||||||
|
}
|
||||||
|
strmov(convert_dirname(to,dir,NullS),prefix_buff);
|
||||||
|
org_file=mkstemp(to);
|
||||||
|
if (mode & O_TEMPORARY)
|
||||||
|
(void) my_delete(to, MYF(MY_WME | ME_NOINPUT));
|
||||||
|
file=my_register_filename(org_file, to, FILE_BY_MKSTEMP,
|
||||||
|
EE_CANTCREATEFILE, MyFlags);
|
||||||
|
/* If we didn't manage to register the name, remove the temp file */
|
||||||
|
if (org_file >= 0 && file < 0)
|
||||||
|
{
|
||||||
|
int tmp=my_errno;
|
||||||
|
close(org_file);
|
||||||
|
(void) my_delete(to, MYF(MY_WME | ME_NOINPUT));
|
||||||
|
my_errno=tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#elif defined(HAVE_TEMPNAM)
|
||||||
|
{
|
||||||
|
#if !defined(__NETWARE__)
|
||||||
|
extern char **environ;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
char *res,**old_env,*temp_env[1];
|
||||||
|
if (dir && !dir[0])
|
||||||
|
{ /* Change empty string to current dir */
|
||||||
|
to[0]= FN_CURLIB;
|
||||||
|
to[1]= 0;
|
||||||
|
dir=to;
|
||||||
|
}
|
||||||
|
#if !defined(__NETWARE__)
|
||||||
|
old_env= (char**) environ;
|
||||||
|
if (dir)
|
||||||
|
{ /* Don't use TMPDIR if dir is given */
|
||||||
|
environ=(const char**) temp_env;
|
||||||
|
temp_env[0]=0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if ((res=tempnam((char*) dir, (char*) prefix)))
|
||||||
|
{
|
||||||
|
strmake(to,res,FN_REFLEN-1);
|
||||||
|
(*free)(res);
|
||||||
|
file=my_create(to,0,
|
||||||
|
(int) (O_RDWR | O_BINARY | O_TRUNC | O_EXCL | O_NOFOLLOW |
|
||||||
|
O_TEMPORARY | O_SHORT_LIVED),
|
||||||
|
MYF(MY_WME));
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DBUG_PRINT("error",("Got error: %d from tempnam",errno));
|
||||||
|
}
|
||||||
|
#if !defined(__NETWARE__)
|
||||||
|
environ=(const char**) old_env;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#error No implementation found for create_temp_file
|
||||||
|
#endif
|
||||||
|
if (file >= 0)
|
||||||
|
thread_safe_increment(my_tmp_file_created,&THR_LOCK_open);
|
||||||
|
DBUG_RETURN(file);
|
||||||
|
}
|
31
MySQL/mf_unixpath.c
Normal file
31
MySQL/mf_unixpath.c
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/* Copyright (C) 2000 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
#include "mysys_priv.h"
|
||||||
|
#include <m_string.h>
|
||||||
|
|
||||||
|
/* convert filename to unix style filename */
|
||||||
|
/* If MSDOS converts '\' to '/' */
|
||||||
|
|
||||||
|
void to_unix_path(char * to __attribute__((unused)))
|
||||||
|
{
|
||||||
|
#if FN_LIBCHAR != '/'
|
||||||
|
{
|
||||||
|
to--;
|
||||||
|
while ((to=strchr(to+1,FN_LIBCHAR)) != 0)
|
||||||
|
*to='/';
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
89
MySQL/mf_wcomp.c
Normal file
89
MySQL/mf_wcomp.c
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
/* Copyright (C) 2000 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
/* Funktions for comparing with wild-cards */
|
||||||
|
|
||||||
|
#include "mysys_priv.h"
|
||||||
|
|
||||||
|
/* Test if a string is "comparable" to a wild-card string */
|
||||||
|
/* returns 0 if the strings are "comparable" */
|
||||||
|
|
||||||
|
char wild_many='*';
|
||||||
|
char wild_one='?';
|
||||||
|
char wild_prefix=0; /* QQ this can potentially cause a SIGSEGV */
|
||||||
|
|
||||||
|
int wild_compare(register const char *str, register const char *wildstr,
|
||||||
|
pbool str_is_pattern)
|
||||||
|
{
|
||||||
|
char cmp;
|
||||||
|
DBUG_ENTER("wild_compare");
|
||||||
|
|
||||||
|
while (*wildstr)
|
||||||
|
{
|
||||||
|
while (*wildstr && *wildstr != wild_many && *wildstr != wild_one)
|
||||||
|
{
|
||||||
|
if (*wildstr == wild_prefix && wildstr[1])
|
||||||
|
{
|
||||||
|
wildstr++;
|
||||||
|
if (str_is_pattern && *str++ != wild_prefix)
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
|
if (*wildstr++ != *str++)
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
|
if (! *wildstr )
|
||||||
|
DBUG_RETURN(*str != 0);
|
||||||
|
if (*wildstr++ == wild_one)
|
||||||
|
{
|
||||||
|
if (! *str || (str_is_pattern && *str == wild_many))
|
||||||
|
DBUG_RETURN(1); /* One char; skip */
|
||||||
|
if (*str++ == wild_prefix && str_is_pattern && *str)
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ /* Found '*' */
|
||||||
|
while (str_is_pattern && *str == wild_many)
|
||||||
|
str++;
|
||||||
|
for (; *wildstr == wild_many || *wildstr == wild_one; wildstr++)
|
||||||
|
if (*wildstr == wild_many)
|
||||||
|
{
|
||||||
|
while (str_is_pattern && *str == wild_many)
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (str_is_pattern && *str == wild_prefix && str[1])
|
||||||
|
str+=2;
|
||||||
|
else if (! *str++)
|
||||||
|
DBUG_RETURN (1);
|
||||||
|
}
|
||||||
|
if (!*wildstr)
|
||||||
|
DBUG_RETURN(0); /* '*' as last char: OK */
|
||||||
|
if ((cmp= *wildstr) == wild_prefix && wildstr[1] && !str_is_pattern)
|
||||||
|
cmp=wildstr[1];
|
||||||
|
for (;;str++)
|
||||||
|
{
|
||||||
|
while (*str && *str != cmp)
|
||||||
|
str++;
|
||||||
|
if (!*str)
|
||||||
|
DBUG_RETURN (1);
|
||||||
|
if (wild_compare(str,wildstr,str_is_pattern) == 0)
|
||||||
|
DBUG_RETURN (0);
|
||||||
|
}
|
||||||
|
/* We will never come here */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DBUG_RETURN (*str != 0);
|
||||||
|
} /* wild_compare */
|
63
MySQL/mulalloc.c
Normal file
63
MySQL/mulalloc.c
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
/* Copyright (C) 2000 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
#include "mysys_priv.h"
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
Malloc many pointers at the same time
|
||||||
|
Only ptr1 can be free'd, and doing this will free all
|
||||||
|
the memory allocated. ptr2, etc all point inside big allocated
|
||||||
|
memory area.
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
my_multi_malloc()
|
||||||
|
myFlags Flags
|
||||||
|
ptr1, length1 Multiple arguments terminated by null ptr
|
||||||
|
ptr2, length2 ...
|
||||||
|
...
|
||||||
|
NULL
|
||||||
|
*/
|
||||||
|
|
||||||
|
void* my_multi_malloc(myf myFlags, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
char **ptr,*start,*res;
|
||||||
|
size_t tot_length,length;
|
||||||
|
DBUG_ENTER("my_multi_malloc");
|
||||||
|
|
||||||
|
va_start(args,myFlags);
|
||||||
|
tot_length=0;
|
||||||
|
while ((ptr=va_arg(args, char **)))
|
||||||
|
{
|
||||||
|
length=va_arg(args,uint);
|
||||||
|
tot_length+=ALIGN_SIZE(length);
|
||||||
|
}
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
if (!(start=(char *) my_malloc(tot_length,myFlags)))
|
||||||
|
DBUG_RETURN(0); /* purecov: inspected */
|
||||||
|
|
||||||
|
va_start(args,myFlags);
|
||||||
|
res=start;
|
||||||
|
while ((ptr=va_arg(args, char **)))
|
||||||
|
{
|
||||||
|
*ptr=res;
|
||||||
|
length=va_arg(args,uint);
|
||||||
|
res+=ALIGN_SIZE(length);
|
||||||
|
}
|
||||||
|
va_end(args);
|
||||||
|
DBUG_RETURN((void*) start);
|
||||||
|
}
|
32
MySQL/my_alarm.c
Normal file
32
MySQL/my_alarm.c
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/* Copyright (C) 2000 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
/* Function to set a varible when we got a alarm */
|
||||||
|
/* Used by my_lock samt functions in m_alarm.h */
|
||||||
|
|
||||||
|
|
||||||
|
#include "mysys_priv.h"
|
||||||
|
#include "my_alarm.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_ALARM
|
||||||
|
|
||||||
|
/* ARGSUSED */
|
||||||
|
sig_handler my_set_alarm_variable(int signo __attribute__((unused)))
|
||||||
|
{
|
||||||
|
my_have_got_alarm=1; /* Tell program that time expired */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* HAVE_ALARM */
|
58
MySQL/my_alarm.h
Normal file
58
MySQL/my_alarm.h
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
/* Copyright (C) 2000 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
/*
|
||||||
|
File to include when we want to use alarm or a loop_counter to display
|
||||||
|
some information when a program is running
|
||||||
|
*/
|
||||||
|
#ifndef _my_alarm_h
|
||||||
|
#define _my_alarm_h
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern int volatile my_have_got_alarm;
|
||||||
|
extern ulong my_time_to_wait_for_lock;
|
||||||
|
|
||||||
|
#if defined(HAVE_ALARM) && !defined(NO_ALARM_LOOP)
|
||||||
|
#include <signal.h>
|
||||||
|
#define ALARM_VARIABLES uint alarm_old=0; \
|
||||||
|
sig_return alarm_signal=0
|
||||||
|
#define ALARM_INIT my_have_got_alarm=0 ; \
|
||||||
|
alarm_old=(uint) alarm(MY_HOW_OFTEN_TO_ALARM); \
|
||||||
|
alarm_signal=signal(SIGALRM,my_set_alarm_variable);
|
||||||
|
#define ALARM_END VOID(signal(SIGALRM,alarm_signal)); \
|
||||||
|
VOID(alarm(alarm_old));
|
||||||
|
#define ALARM_TEST my_have_got_alarm
|
||||||
|
#ifdef DONT_REMEMBER_SIGNAL
|
||||||
|
#define ALARM_REINIT VOID(alarm(MY_HOW_OFTEN_TO_ALARM)); \
|
||||||
|
VOID(signal(SIGALRM,my_set_alarm_variable));\
|
||||||
|
my_have_got_alarm=0;
|
||||||
|
#else
|
||||||
|
#define ALARM_REINIT VOID(alarm((uint) MY_HOW_OFTEN_TO_ALARM)); \
|
||||||
|
my_have_got_alarm=0;
|
||||||
|
#endif /* DONT_REMEMBER_SIGNAL */
|
||||||
|
#else
|
||||||
|
#define ALARM_VARIABLES long alarm_pos=0,alarm_end_pos=MY_HOW_OFTEN_TO_WRITE-1
|
||||||
|
#define ALARM_INIT
|
||||||
|
#define ALARM_END
|
||||||
|
#define ALARM_TEST (alarm_pos++ >= alarm_end_pos)
|
||||||
|
#define ALARM_REINIT alarm_end_pos+=MY_HOW_OFTEN_TO_WRITE
|
||||||
|
#endif /* HAVE_ALARM */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
420
MySQL/my_alloc.c
Normal file
420
MySQL/my_alloc.c
Normal file
@ -0,0 +1,420 @@
|
|||||||
|
/* Copyright (C) 2000 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
/* Routines to handle mallocing of results which will be freed the same time */
|
||||||
|
|
||||||
|
#include <my_global.h>
|
||||||
|
#include <my_sys.h>
|
||||||
|
#include <m_string.h>
|
||||||
|
#undef EXTRA_DEBUG
|
||||||
|
#define EXTRA_DEBUG
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Initialize memory root
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
init_alloc_root()
|
||||||
|
mem_root - memory root to initialize
|
||||||
|
block_size - size of chunks (blocks) used for memory allocation
|
||||||
|
(It is external size of chunk i.e. it should include
|
||||||
|
memory required for internal structures, thus it
|
||||||
|
should be no less than ALLOC_ROOT_MIN_BLOCK_SIZE)
|
||||||
|
pre_alloc_size - if non-0, then size of block that should be
|
||||||
|
pre-allocated during memory root initialization.
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
This function prepares memory root for further use, sets initial size of
|
||||||
|
chunk for memory allocation and pre-allocates first block if specified.
|
||||||
|
Altough error can happen during execution of this function if
|
||||||
|
pre_alloc_size is non-0 it won't be reported. Instead it will be
|
||||||
|
reported as error in first alloc_root() on this memory root.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void init_alloc_root(MEM_ROOT *mem_root, size_t block_size,
|
||||||
|
size_t pre_alloc_size __attribute__((unused)))
|
||||||
|
{
|
||||||
|
DBUG_ENTER("init_alloc_root");
|
||||||
|
DBUG_PRINT("enter",("root: 0x%lx", (long) mem_root));
|
||||||
|
|
||||||
|
mem_root->free= mem_root->used= mem_root->pre_alloc= 0;
|
||||||
|
mem_root->min_malloc= 32;
|
||||||
|
mem_root->block_size= block_size - ALLOC_ROOT_MIN_BLOCK_SIZE;
|
||||||
|
mem_root->error_handler= 0;
|
||||||
|
mem_root->block_num= 4; /* We shift this with >>2 */
|
||||||
|
mem_root->first_block_usage= 0;
|
||||||
|
|
||||||
|
#if !(defined(HAVE_purify) && defined(EXTRA_DEBUG))
|
||||||
|
if (pre_alloc_size)
|
||||||
|
{
|
||||||
|
if ((mem_root->free= mem_root->pre_alloc=
|
||||||
|
(USED_MEM*) my_malloc(pre_alloc_size+ ALIGN_SIZE(sizeof(USED_MEM)),
|
||||||
|
MYF(0))))
|
||||||
|
{
|
||||||
|
mem_root->free->size= pre_alloc_size+ALIGN_SIZE(sizeof(USED_MEM));
|
||||||
|
mem_root->free->left= pre_alloc_size;
|
||||||
|
mem_root->free->next= 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
SYNOPSIS
|
||||||
|
reset_root_defaults()
|
||||||
|
mem_root memory root to change defaults of
|
||||||
|
block_size new value of block size. Must be greater or equal
|
||||||
|
than ALLOC_ROOT_MIN_BLOCK_SIZE (this value is about
|
||||||
|
68 bytes and depends on platform and compilation flags)
|
||||||
|
pre_alloc_size new size of preallocated block. If not zero,
|
||||||
|
must be equal to or greater than block size,
|
||||||
|
otherwise means 'no prealloc'.
|
||||||
|
DESCRIPTION
|
||||||
|
Function aligns and assigns new value to block size; then it tries to
|
||||||
|
reuse one of existing blocks as prealloc block, or malloc new one of
|
||||||
|
requested size. If no blocks can be reused, all unused blocks are freed
|
||||||
|
before allocation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void reset_root_defaults(MEM_ROOT *mem_root, size_t block_size,
|
||||||
|
size_t pre_alloc_size __attribute__((unused)))
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(alloc_root_inited(mem_root));
|
||||||
|
|
||||||
|
mem_root->block_size= block_size - ALLOC_ROOT_MIN_BLOCK_SIZE;
|
||||||
|
#if !(defined(HAVE_purify) && defined(EXTRA_DEBUG))
|
||||||
|
if (pre_alloc_size)
|
||||||
|
{
|
||||||
|
size_t size= pre_alloc_size + ALIGN_SIZE(sizeof(USED_MEM));
|
||||||
|
if (!mem_root->pre_alloc || mem_root->pre_alloc->size != size)
|
||||||
|
{
|
||||||
|
USED_MEM *mem, **prev= &mem_root->free;
|
||||||
|
/*
|
||||||
|
Free unused blocks, so that consequent calls
|
||||||
|
to reset_root_defaults won't eat away memory.
|
||||||
|
*/
|
||||||
|
while (*prev)
|
||||||
|
{
|
||||||
|
mem= *prev;
|
||||||
|
if (mem->size == size)
|
||||||
|
{
|
||||||
|
/* We found a suitable block, no need to do anything else */
|
||||||
|
mem_root->pre_alloc= mem;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (mem->left + ALIGN_SIZE(sizeof(USED_MEM)) == mem->size)
|
||||||
|
{
|
||||||
|
/* remove block from the list and free it */
|
||||||
|
*prev= mem->next;
|
||||||
|
my_free(mem, MYF(0));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
prev= &mem->next;
|
||||||
|
}
|
||||||
|
/* Allocate new prealloc block and add it to the end of free list */
|
||||||
|
if ((mem= (USED_MEM *) my_malloc(size, MYF(0))))
|
||||||
|
{
|
||||||
|
mem->size= size;
|
||||||
|
mem->left= pre_alloc_size;
|
||||||
|
mem->next= *prev;
|
||||||
|
*prev= mem_root->pre_alloc= mem;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mem_root->pre_alloc= 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
mem_root->pre_alloc= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void *alloc_root(MEM_ROOT *mem_root, size_t length)
|
||||||
|
{
|
||||||
|
#if defined(HAVE_purify) && defined(EXTRA_DEBUG)
|
||||||
|
reg1 USED_MEM *next;
|
||||||
|
DBUG_ENTER("alloc_root");
|
||||||
|
DBUG_PRINT("enter",("root: 0x%lx", (long) mem_root));
|
||||||
|
|
||||||
|
DBUG_ASSERT(alloc_root_inited(mem_root));
|
||||||
|
|
||||||
|
length+=ALIGN_SIZE(sizeof(USED_MEM));
|
||||||
|
if (!(next = (USED_MEM*) my_malloc(length,MYF(MY_WME))))
|
||||||
|
{
|
||||||
|
if (mem_root->error_handler)
|
||||||
|
(*mem_root->error_handler)();
|
||||||
|
DBUG_RETURN((uchar*) 0); /* purecov: inspected */
|
||||||
|
}
|
||||||
|
next->next= mem_root->used;
|
||||||
|
next->size= length;
|
||||||
|
mem_root->used= next;
|
||||||
|
DBUG_PRINT("exit",("ptr: 0x%lx", (long) (((char*) next)+
|
||||||
|
ALIGN_SIZE(sizeof(USED_MEM)))));
|
||||||
|
DBUG_RETURN((uchar*) (((char*) next)+ALIGN_SIZE(sizeof(USED_MEM))));
|
||||||
|
#else
|
||||||
|
size_t get_size, block_size;
|
||||||
|
uchar* point;
|
||||||
|
reg1 USED_MEM *next= 0;
|
||||||
|
reg2 USED_MEM **prev;
|
||||||
|
DBUG_ENTER("alloc_root");
|
||||||
|
DBUG_PRINT("enter",("root: 0x%lx", (long) mem_root));
|
||||||
|
DBUG_ASSERT(alloc_root_inited(mem_root));
|
||||||
|
|
||||||
|
length= ALIGN_SIZE(length);
|
||||||
|
if ((*(prev= &mem_root->free)) != NULL)
|
||||||
|
{
|
||||||
|
if ((*prev)->left < length &&
|
||||||
|
mem_root->first_block_usage++ >= ALLOC_MAX_BLOCK_USAGE_BEFORE_DROP &&
|
||||||
|
(*prev)->left < ALLOC_MAX_BLOCK_TO_DROP)
|
||||||
|
{
|
||||||
|
next= *prev;
|
||||||
|
*prev= next->next; /* Remove block from list */
|
||||||
|
next->next= mem_root->used;
|
||||||
|
mem_root->used= next;
|
||||||
|
mem_root->first_block_usage= 0;
|
||||||
|
}
|
||||||
|
for (next= *prev ; next && next->left < length ; next= next->next)
|
||||||
|
prev= &next->next;
|
||||||
|
}
|
||||||
|
if (! next)
|
||||||
|
{ /* Time to alloc new block */
|
||||||
|
block_size= mem_root->block_size * (mem_root->block_num >> 2);
|
||||||
|
get_size= length+ALIGN_SIZE(sizeof(USED_MEM));
|
||||||
|
get_size= max(get_size, block_size);
|
||||||
|
|
||||||
|
if (!(next = (USED_MEM*) my_malloc(get_size,MYF(MY_WME))))
|
||||||
|
{
|
||||||
|
if (mem_root->error_handler)
|
||||||
|
(*mem_root->error_handler)();
|
||||||
|
DBUG_RETURN((void*) 0); /* purecov: inspected */
|
||||||
|
}
|
||||||
|
mem_root->block_num++;
|
||||||
|
next->next= *prev;
|
||||||
|
next->size= get_size;
|
||||||
|
next->left= get_size-ALIGN_SIZE(sizeof(USED_MEM));
|
||||||
|
*prev=next;
|
||||||
|
}
|
||||||
|
|
||||||
|
point= (uchar*) ((char*) next+ (next->size-next->left));
|
||||||
|
/*TODO: next part may be unneded due to mem_root->first_block_usage counter*/
|
||||||
|
if ((next->left-= length) < mem_root->min_malloc)
|
||||||
|
{ /* Full block */
|
||||||
|
*prev= next->next; /* Remove block from list */
|
||||||
|
next->next= mem_root->used;
|
||||||
|
mem_root->used= next;
|
||||||
|
mem_root->first_block_usage= 0;
|
||||||
|
}
|
||||||
|
DBUG_PRINT("exit",("ptr: 0x%lx", (ulong) point));
|
||||||
|
DBUG_RETURN((void*) point);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Allocate many pointers at the same time.
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
ptr1, ptr2, etc all point into big allocated memory area.
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
multi_alloc_root()
|
||||||
|
root Memory root
|
||||||
|
ptr1, length1 Multiple arguments terminated by a NULL pointer
|
||||||
|
ptr2, length2 ...
|
||||||
|
...
|
||||||
|
NULL
|
||||||
|
|
||||||
|
RETURN VALUE
|
||||||
|
A pointer to the beginning of the allocated memory block
|
||||||
|
in case of success or NULL if out of memory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void *multi_alloc_root(MEM_ROOT *root, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
char **ptr, *start, *res;
|
||||||
|
size_t tot_length, length;
|
||||||
|
DBUG_ENTER("multi_alloc_root");
|
||||||
|
|
||||||
|
va_start(args, root);
|
||||||
|
tot_length= 0;
|
||||||
|
while ((ptr= va_arg(args, char **)))
|
||||||
|
{
|
||||||
|
length= va_arg(args, uint);
|
||||||
|
tot_length+= ALIGN_SIZE(length);
|
||||||
|
}
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
if (!(start= (char*) alloc_root(root, tot_length)))
|
||||||
|
DBUG_RETURN(0); /* purecov: inspected */
|
||||||
|
|
||||||
|
va_start(args, root);
|
||||||
|
res= start;
|
||||||
|
while ((ptr= va_arg(args, char **)))
|
||||||
|
{
|
||||||
|
*ptr= res;
|
||||||
|
length= va_arg(args, uint);
|
||||||
|
res+= ALIGN_SIZE(length);
|
||||||
|
}
|
||||||
|
va_end(args);
|
||||||
|
DBUG_RETURN((void*) start);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define TRASH_MEM(X) TRASH(((char*)(X) + ((X)->size-(X)->left)), (X)->left)
|
||||||
|
|
||||||
|
/* Mark all data in blocks free for reusage */
|
||||||
|
|
||||||
|
static inline void mark_blocks_free(MEM_ROOT* root)
|
||||||
|
{
|
||||||
|
reg1 USED_MEM *next;
|
||||||
|
reg2 USED_MEM **last;
|
||||||
|
|
||||||
|
/* iterate through (partially) free blocks, mark them free */
|
||||||
|
last= &root->free;
|
||||||
|
for (next= root->free; next; next= *(last= &next->next))
|
||||||
|
{
|
||||||
|
next->left= next->size - ALIGN_SIZE(sizeof(USED_MEM));
|
||||||
|
TRASH_MEM(next);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Combine the free and the used list */
|
||||||
|
*last= next=root->used;
|
||||||
|
|
||||||
|
/* now go through the used blocks and mark them free */
|
||||||
|
for (; next; next= next->next)
|
||||||
|
{
|
||||||
|
next->left= next->size - ALIGN_SIZE(sizeof(USED_MEM));
|
||||||
|
TRASH_MEM(next);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now everything is set; Indicate that nothing is used anymore */
|
||||||
|
root->used= 0;
|
||||||
|
root->first_block_usage= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Deallocate everything used by alloc_root or just move
|
||||||
|
used blocks to free list if called with MY_USED_TO_FREE
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
free_root()
|
||||||
|
root Memory root
|
||||||
|
MyFlags Flags for what should be freed:
|
||||||
|
|
||||||
|
MY_MARK_BLOCKS_FREED Don't free blocks, just mark them free
|
||||||
|
MY_KEEP_PREALLOC If this is not set, then free also the
|
||||||
|
preallocated block
|
||||||
|
|
||||||
|
NOTES
|
||||||
|
One can call this function either with root block initialised with
|
||||||
|
init_alloc_root() or with a bzero()-ed block.
|
||||||
|
It's also safe to call this multiple times with the same mem_root.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void free_root(MEM_ROOT *root, myf MyFlags)
|
||||||
|
{
|
||||||
|
reg1 USED_MEM *next,*old;
|
||||||
|
DBUG_ENTER("free_root");
|
||||||
|
DBUG_PRINT("enter",("root: 0x%lx flags: %u", (long) root, (uint) MyFlags));
|
||||||
|
|
||||||
|
if (MyFlags & MY_MARK_BLOCKS_FREE)
|
||||||
|
{
|
||||||
|
mark_blocks_free(root);
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
|
if (!(MyFlags & MY_KEEP_PREALLOC))
|
||||||
|
root->pre_alloc=0;
|
||||||
|
|
||||||
|
for (next=root->used; next ;)
|
||||||
|
{
|
||||||
|
old=next; next= next->next ;
|
||||||
|
if (old != root->pre_alloc)
|
||||||
|
my_free(old,MYF(0));
|
||||||
|
}
|
||||||
|
for (next=root->free ; next ;)
|
||||||
|
{
|
||||||
|
old=next; next= next->next;
|
||||||
|
if (old != root->pre_alloc)
|
||||||
|
my_free(old,MYF(0));
|
||||||
|
}
|
||||||
|
root->used=root->free=0;
|
||||||
|
if (root->pre_alloc)
|
||||||
|
{
|
||||||
|
root->free=root->pre_alloc;
|
||||||
|
root->free->left=root->pre_alloc->size-ALIGN_SIZE(sizeof(USED_MEM));
|
||||||
|
TRASH_MEM(root->pre_alloc);
|
||||||
|
root->free->next=0;
|
||||||
|
}
|
||||||
|
root->block_num= 4;
|
||||||
|
root->first_block_usage= 0;
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Find block that contains an object and set the pre_alloc to it
|
||||||
|
*/
|
||||||
|
|
||||||
|
void set_prealloc_root(MEM_ROOT *root, char *ptr)
|
||||||
|
{
|
||||||
|
USED_MEM *next;
|
||||||
|
for (next=root->used; next ; next=next->next)
|
||||||
|
{
|
||||||
|
if ((char*) next <= ptr && (char*) next + next->size > ptr)
|
||||||
|
{
|
||||||
|
root->pre_alloc=next;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (next=root->free ; next ; next=next->next)
|
||||||
|
{
|
||||||
|
if ((char*) next <= ptr && (char*) next + next->size > ptr)
|
||||||
|
{
|
||||||
|
root->pre_alloc=next;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char *strdup_root(MEM_ROOT *root, const char *str)
|
||||||
|
{
|
||||||
|
return strmake_root(root, str, strlen(str));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char *strmake_root(MEM_ROOT *root, const char *str, size_t len)
|
||||||
|
{
|
||||||
|
char *pos;
|
||||||
|
if ((pos=alloc_root(root,len+1)))
|
||||||
|
{
|
||||||
|
memcpy(pos,str,len);
|
||||||
|
pos[len]=0;
|
||||||
|
}
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void *memdup_root(MEM_ROOT *root, const void *str, size_t len)
|
||||||
|
{
|
||||||
|
char *pos;
|
||||||
|
if ((pos=alloc_root(root,len)))
|
||||||
|
memcpy(pos,str,len);
|
||||||
|
return pos;
|
||||||
|
}
|
51
MySQL/my_alloc.h
Normal file
51
MySQL/my_alloc.h
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
/* Copyright (C) 2000 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Data structures for mysys/my_alloc.c (root memory allocator)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _my_alloc_h
|
||||||
|
#define _my_alloc_h
|
||||||
|
|
||||||
|
#define ALLOC_MAX_BLOCK_TO_DROP 4096
|
||||||
|
#define ALLOC_MAX_BLOCK_USAGE_BEFORE_DROP 10
|
||||||
|
|
||||||
|
typedef struct st_used_mem
|
||||||
|
{ /* struct for once_alloc (block) */
|
||||||
|
struct st_used_mem *next; /* Next block in use */
|
||||||
|
unsigned int left; /* memory left in block */
|
||||||
|
unsigned int size; /* size of block */
|
||||||
|
} USED_MEM;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct st_mem_root
|
||||||
|
{
|
||||||
|
USED_MEM *free; /* blocks with free memory in it */
|
||||||
|
USED_MEM *used; /* blocks almost without free memory */
|
||||||
|
USED_MEM *pre_alloc; /* preallocated block */
|
||||||
|
/* if block have less memory it will be put in 'used' list */
|
||||||
|
size_t min_malloc;
|
||||||
|
size_t block_size; /* initial block size */
|
||||||
|
unsigned int block_num; /* allocated blocks counter */
|
||||||
|
/*
|
||||||
|
first free block in queue test counter (if it exceed
|
||||||
|
MAX_BLOCK_USAGE_BEFORE_DROP block will be dropped in 'used' list)
|
||||||
|
*/
|
||||||
|
unsigned int first_block_usage;
|
||||||
|
|
||||||
|
void (*error_handler)(void);
|
||||||
|
} MEM_ROOT;
|
||||||
|
#endif
|
63
MySQL/my_attribute.h
Normal file
63
MySQL/my_attribute.h
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
/* Copyright (C) 2000-2003 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Helper macros used for setting different __attributes__
|
||||||
|
on functions in a portable fashion
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _my_attribute_h
|
||||||
|
#define _my_attribute_h
|
||||||
|
|
||||||
|
/*
|
||||||
|
Disable __attribute__() on gcc < 2.7, g++ < 3.4, and non-gcc compilers.
|
||||||
|
Some forms of __attribute__ are actually supported in earlier versions of
|
||||||
|
g++, but we just disable them all because we only use them to generate
|
||||||
|
compilation warnings.
|
||||||
|
*/
|
||||||
|
#ifndef __attribute__
|
||||||
|
# if !defined(__GNUC__)
|
||||||
|
# define __attribute__(A)
|
||||||
|
# elif GCC_VERSION < 2008
|
||||||
|
# define __attribute__(A)
|
||||||
|
# elif defined(__cplusplus) && GCC_VERSION < 3004
|
||||||
|
# define __attribute__(A)
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
__attribute__((format(...))) is only supported in gcc >= 2.8 and g++ >= 3.4
|
||||||
|
But that's already covered by the __attribute__ tests above, so this is
|
||||||
|
just a convenience macro.
|
||||||
|
*/
|
||||||
|
#ifndef ATTRIBUTE_FORMAT
|
||||||
|
# define ATTRIBUTE_FORMAT(style, m, n) __attribute__((format(style, m, n)))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
__attribute__((format(...))) on a function pointer is not supported
|
||||||
|
until gcc 3.1
|
||||||
|
*/
|
||||||
|
#ifndef ATTRIBUTE_FORMAT_FPTR
|
||||||
|
# if (GCC_VERSION >= 3001)
|
||||||
|
# define ATTRIBUTE_FORMAT_FPTR(style, m, n) ATTRIBUTE_FORMAT(style, m, n)
|
||||||
|
# else
|
||||||
|
# define ATTRIBUTE_FORMAT_FPTR(style, m, n)
|
||||||
|
# endif /* GNUC >= 3.1 */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
566
MySQL/my_base.h
Normal file
566
MySQL/my_base.h
Normal file
@ -0,0 +1,566 @@
|
|||||||
|
/* Copyright (C) 2000 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
/* This file includes constants used with all databases */
|
||||||
|
|
||||||
|
#ifndef _my_base_h
|
||||||
|
#define _my_base_h
|
||||||
|
|
||||||
|
#ifndef stdin /* Included first in handler */
|
||||||
|
#define CHSIZE_USED
|
||||||
|
#include <my_global.h>
|
||||||
|
#include <my_dir.h> /* This includes types */
|
||||||
|
#include <my_sys.h>
|
||||||
|
#include <m_string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#ifndef EOVERFLOW
|
||||||
|
#define EOVERFLOW 84
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(USE_MY_FUNC) && !defined(THREAD)
|
||||||
|
#include <my_nosys.h> /* For faster code, after test */
|
||||||
|
#endif /* USE_MY_FUNC */
|
||||||
|
#endif /* stdin */
|
||||||
|
#include <my_list.h>
|
||||||
|
|
||||||
|
/* The following is bits in the flag parameter to ha_open() */
|
||||||
|
|
||||||
|
#define HA_OPEN_ABORT_IF_LOCKED 0 /* default */
|
||||||
|
#define HA_OPEN_WAIT_IF_LOCKED 1
|
||||||
|
#define HA_OPEN_IGNORE_IF_LOCKED 2
|
||||||
|
#define HA_OPEN_TMP_TABLE 4 /* Table is a temp table */
|
||||||
|
#define HA_OPEN_DELAY_KEY_WRITE 8 /* Don't update index */
|
||||||
|
#define HA_OPEN_ABORT_IF_CRASHED 16
|
||||||
|
#define HA_OPEN_FOR_REPAIR 32 /* open even if crashed */
|
||||||
|
#define HA_OPEN_FROM_SQL_LAYER 64
|
||||||
|
#define HA_OPEN_MMAP 128 /* open memory mapped */
|
||||||
|
#define HA_OPEN_COPY 256 /* Open copy (for repair) */
|
||||||
|
/* Internal temp table, used for temporary results */
|
||||||
|
#define HA_OPEN_INTERNAL_TABLE 512
|
||||||
|
|
||||||
|
/* The following is parameter to ha_rkey() how to use key */
|
||||||
|
|
||||||
|
/*
|
||||||
|
We define a complete-field prefix of a key value as a prefix where
|
||||||
|
the last included field in the prefix contains the full field, not
|
||||||
|
just some bytes from the start of the field. A partial-field prefix
|
||||||
|
is allowed to contain only a few first bytes from the last included
|
||||||
|
field.
|
||||||
|
|
||||||
|
Below HA_READ_KEY_EXACT, ..., HA_READ_BEFORE_KEY can take a
|
||||||
|
complete-field prefix of a key value as the search
|
||||||
|
key. HA_READ_PREFIX and HA_READ_PREFIX_LAST could also take a
|
||||||
|
partial-field prefix, but currently (4.0.10) they are only used with
|
||||||
|
complete-field prefixes. MySQL uses a padding trick to implement
|
||||||
|
LIKE 'abc%' queries.
|
||||||
|
|
||||||
|
NOTE that in InnoDB HA_READ_PREFIX_LAST will NOT work with a
|
||||||
|
partial-field prefix because InnoDB currently strips spaces from the
|
||||||
|
end of varchar fields!
|
||||||
|
*/
|
||||||
|
|
||||||
|
enum ha_rkey_function {
|
||||||
|
HA_READ_KEY_EXACT, /* Find first record else error */
|
||||||
|
HA_READ_KEY_OR_NEXT, /* Record or next record */
|
||||||
|
HA_READ_KEY_OR_PREV, /* Record or previous */
|
||||||
|
HA_READ_AFTER_KEY, /* Find next rec. after key-record */
|
||||||
|
HA_READ_BEFORE_KEY, /* Find next rec. before key-record */
|
||||||
|
HA_READ_PREFIX, /* Key which as same prefix */
|
||||||
|
HA_READ_PREFIX_LAST, /* Last key with the same prefix */
|
||||||
|
HA_READ_PREFIX_LAST_OR_PREV, /* Last or prev key with the same prefix */
|
||||||
|
HA_READ_MBR_CONTAIN,
|
||||||
|
HA_READ_MBR_INTERSECT,
|
||||||
|
HA_READ_MBR_WITHIN,
|
||||||
|
HA_READ_MBR_DISJOINT,
|
||||||
|
HA_READ_MBR_EQUAL
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Key algorithm types */
|
||||||
|
|
||||||
|
enum ha_key_alg {
|
||||||
|
HA_KEY_ALG_UNDEF= 0, /* Not specified (old file) */
|
||||||
|
HA_KEY_ALG_BTREE= 1, /* B-tree, default one */
|
||||||
|
HA_KEY_ALG_RTREE= 2, /* R-tree, for spatial searches */
|
||||||
|
HA_KEY_ALG_HASH= 3, /* HASH keys (HEAP tables) */
|
||||||
|
HA_KEY_ALG_FULLTEXT= 4 /* FULLTEXT (MyISAM tables) */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Storage media types */
|
||||||
|
|
||||||
|
enum ha_storage_media {
|
||||||
|
HA_SM_DEFAULT= 0, /* Not specified (engine default) */
|
||||||
|
HA_SM_DISK= 1, /* DISK storage */
|
||||||
|
HA_SM_MEMORY= 2 /* MAIN MEMORY storage */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* The following is parameter to ha_extra() */
|
||||||
|
|
||||||
|
enum ha_extra_function {
|
||||||
|
HA_EXTRA_NORMAL=0, /* Optimize for space (def) */
|
||||||
|
HA_EXTRA_QUICK=1, /* Optimize for speed */
|
||||||
|
HA_EXTRA_NOT_USED=2,
|
||||||
|
HA_EXTRA_CACHE=3, /* Cache record in HA_rrnd() */
|
||||||
|
HA_EXTRA_NO_CACHE=4, /* End caching of records (def) */
|
||||||
|
HA_EXTRA_NO_READCHECK=5, /* No readcheck on update */
|
||||||
|
HA_EXTRA_READCHECK=6, /* Use readcheck (def) */
|
||||||
|
HA_EXTRA_KEYREAD=7, /* Read only key to database */
|
||||||
|
HA_EXTRA_NO_KEYREAD=8, /* Normal read of records (def) */
|
||||||
|
HA_EXTRA_NO_USER_CHANGE=9, /* No user is allowed to write */
|
||||||
|
HA_EXTRA_KEY_CACHE=10,
|
||||||
|
HA_EXTRA_NO_KEY_CACHE=11,
|
||||||
|
HA_EXTRA_WAIT_LOCK=12, /* Wait until file is avalably (def) */
|
||||||
|
HA_EXTRA_NO_WAIT_LOCK=13, /* If file is locked, return quickly */
|
||||||
|
HA_EXTRA_WRITE_CACHE=14, /* Use write cache in ha_write() */
|
||||||
|
HA_EXTRA_FLUSH_CACHE=15, /* flush write_record_cache */
|
||||||
|
HA_EXTRA_NO_KEYS=16, /* Remove all update of keys */
|
||||||
|
HA_EXTRA_KEYREAD_CHANGE_POS=17, /* Keyread, but change pos */
|
||||||
|
/* xxxxchk -r must be used */
|
||||||
|
HA_EXTRA_REMEMBER_POS=18, /* Remember pos for next/prev */
|
||||||
|
HA_EXTRA_RESTORE_POS=19,
|
||||||
|
HA_EXTRA_REINIT_CACHE=20, /* init cache from current record */
|
||||||
|
HA_EXTRA_FORCE_REOPEN=21, /* Datafile have changed on disk */
|
||||||
|
HA_EXTRA_FLUSH, /* Flush tables to disk */
|
||||||
|
HA_EXTRA_NO_ROWS, /* Don't write rows */
|
||||||
|
HA_EXTRA_RESET_STATE, /* Reset positions */
|
||||||
|
HA_EXTRA_IGNORE_DUP_KEY, /* Dup keys don't rollback everything*/
|
||||||
|
HA_EXTRA_NO_IGNORE_DUP_KEY,
|
||||||
|
HA_EXTRA_PREPARE_FOR_DROP,
|
||||||
|
HA_EXTRA_PREPARE_FOR_UPDATE, /* Remove read cache if problems */
|
||||||
|
HA_EXTRA_PRELOAD_BUFFER_SIZE, /* Set buffer size for preloading */
|
||||||
|
/*
|
||||||
|
On-the-fly switching between unique and non-unique key inserting.
|
||||||
|
*/
|
||||||
|
HA_EXTRA_CHANGE_KEY_TO_UNIQUE,
|
||||||
|
HA_EXTRA_CHANGE_KEY_TO_DUP,
|
||||||
|
/*
|
||||||
|
When using HA_EXTRA_KEYREAD, overwrite only key member fields and keep
|
||||||
|
other fields intact. When this is off (by default) InnoDB will use memcpy
|
||||||
|
to overwrite entire row.
|
||||||
|
*/
|
||||||
|
HA_EXTRA_KEYREAD_PRESERVE_FIELDS,
|
||||||
|
HA_EXTRA_MMAP,
|
||||||
|
/*
|
||||||
|
Ignore if the a tuple is not found, continue processing the
|
||||||
|
transaction and ignore that 'row'. Needed for idempotency
|
||||||
|
handling on the slave
|
||||||
|
|
||||||
|
Currently only used by NDB storage engine. Partition handler ignores flag.
|
||||||
|
*/
|
||||||
|
HA_EXTRA_IGNORE_NO_KEY,
|
||||||
|
HA_EXTRA_NO_IGNORE_NO_KEY,
|
||||||
|
/*
|
||||||
|
Mark the table as a log table. For some handlers (e.g. CSV) this results
|
||||||
|
in a special locking for the table.
|
||||||
|
*/
|
||||||
|
HA_EXTRA_MARK_AS_LOG_TABLE,
|
||||||
|
/*
|
||||||
|
Informs handler that write_row() which tries to insert new row into the
|
||||||
|
table and encounters some already existing row with same primary/unique
|
||||||
|
key can replace old row with new row instead of reporting error (basically
|
||||||
|
it informs handler that we do REPLACE instead of simple INSERT).
|
||||||
|
Off by default.
|
||||||
|
*/
|
||||||
|
HA_EXTRA_WRITE_CAN_REPLACE,
|
||||||
|
HA_EXTRA_WRITE_CANNOT_REPLACE,
|
||||||
|
/*
|
||||||
|
Inform handler that delete_row()/update_row() cannot batch deletes/updates
|
||||||
|
and should perform them immediately. This may be needed when table has
|
||||||
|
AFTER DELETE/UPDATE triggers which access to subject table.
|
||||||
|
These flags are reset by the handler::extra(HA_EXTRA_RESET) call.
|
||||||
|
*/
|
||||||
|
HA_EXTRA_DELETE_CANNOT_BATCH,
|
||||||
|
HA_EXTRA_UPDATE_CANNOT_BATCH,
|
||||||
|
/*
|
||||||
|
Inform handler that an "INSERT...ON DUPLICATE KEY UPDATE" will be
|
||||||
|
executed. This condition is unset by HA_EXTRA_NO_IGNORE_DUP_KEY.
|
||||||
|
*/
|
||||||
|
HA_EXTRA_INSERT_WITH_UPDATE,
|
||||||
|
/* Inform handler that we will do a rename */
|
||||||
|
HA_EXTRA_PREPARE_FOR_RENAME,
|
||||||
|
/*
|
||||||
|
Orders MERGE handler to attach or detach its child tables. Used at
|
||||||
|
begin and end of a statement.
|
||||||
|
*/
|
||||||
|
HA_EXTRA_ATTACH_CHILDREN,
|
||||||
|
HA_EXTRA_DETACH_CHILDREN
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Compatible option, to be deleted in 6.0 */
|
||||||
|
#define HA_EXTRA_PREPARE_FOR_DELETE HA_EXTRA_PREPARE_FOR_DROP
|
||||||
|
|
||||||
|
/* The following is parameter to ha_panic() */
|
||||||
|
|
||||||
|
enum ha_panic_function {
|
||||||
|
HA_PANIC_CLOSE, /* Close all databases */
|
||||||
|
HA_PANIC_WRITE, /* Unlock and write status */
|
||||||
|
HA_PANIC_READ /* Lock and read keyinfo */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* The following is parameter to ha_create(); keytypes */
|
||||||
|
|
||||||
|
enum ha_base_keytype {
|
||||||
|
HA_KEYTYPE_END=0,
|
||||||
|
HA_KEYTYPE_TEXT=1, /* Key is sorted as letters */
|
||||||
|
HA_KEYTYPE_BINARY=2, /* Key is sorted as unsigned chars */
|
||||||
|
HA_KEYTYPE_SHORT_INT=3,
|
||||||
|
HA_KEYTYPE_LONG_INT=4,
|
||||||
|
HA_KEYTYPE_FLOAT=5,
|
||||||
|
HA_KEYTYPE_DOUBLE=6,
|
||||||
|
HA_KEYTYPE_NUM=7, /* Not packed num with pre-space */
|
||||||
|
HA_KEYTYPE_USHORT_INT=8,
|
||||||
|
HA_KEYTYPE_ULONG_INT=9,
|
||||||
|
HA_KEYTYPE_LONGLONG=10,
|
||||||
|
HA_KEYTYPE_ULONGLONG=11,
|
||||||
|
HA_KEYTYPE_INT24=12,
|
||||||
|
HA_KEYTYPE_UINT24=13,
|
||||||
|
HA_KEYTYPE_INT8=14,
|
||||||
|
/* Varchar (0-255 bytes) with length packed with 1 byte */
|
||||||
|
HA_KEYTYPE_VARTEXT1=15, /* Key is sorted as letters */
|
||||||
|
HA_KEYTYPE_VARBINARY1=16, /* Key is sorted as unsigned chars */
|
||||||
|
/* Varchar (0-65535 bytes) with length packed with 2 bytes */
|
||||||
|
HA_KEYTYPE_VARTEXT2=17, /* Key is sorted as letters */
|
||||||
|
HA_KEYTYPE_VARBINARY2=18, /* Key is sorted as unsigned chars */
|
||||||
|
HA_KEYTYPE_BIT=19
|
||||||
|
};
|
||||||
|
|
||||||
|
#define HA_MAX_KEYTYPE 31 /* Must be log2-1 */
|
||||||
|
|
||||||
|
/* These flags kan be OR:ed to key-flag */
|
||||||
|
|
||||||
|
#define HA_NOSAME 1 /* Set if not dupplicated records */
|
||||||
|
#define HA_PACK_KEY 2 /* Pack string key to previous key */
|
||||||
|
#define HA_AUTO_KEY 16
|
||||||
|
#define HA_BINARY_PACK_KEY 32 /* Packing of all keys to prev key */
|
||||||
|
#define HA_FULLTEXT 128 /* For full-text search */
|
||||||
|
#define HA_UNIQUE_CHECK 256 /* Check the key for uniqueness */
|
||||||
|
#define HA_SPATIAL 1024 /* For spatial search */
|
||||||
|
#define HA_NULL_ARE_EQUAL 2048 /* NULL in key are cmp as equal */
|
||||||
|
#define HA_GENERATED_KEY 8192 /* Automaticly generated key */
|
||||||
|
|
||||||
|
/* The combination of the above can be used for key type comparison. */
|
||||||
|
#define HA_KEYFLAG_MASK (HA_NOSAME | HA_PACK_KEY | HA_AUTO_KEY | \
|
||||||
|
HA_BINARY_PACK_KEY | HA_FULLTEXT | HA_UNIQUE_CHECK | \
|
||||||
|
HA_SPATIAL | HA_NULL_ARE_EQUAL | HA_GENERATED_KEY)
|
||||||
|
|
||||||
|
#define HA_KEY_HAS_PART_KEY_SEG 65536 /* Key contains partial segments */
|
||||||
|
|
||||||
|
/* Automatic bits in key-flag */
|
||||||
|
|
||||||
|
#define HA_SPACE_PACK_USED 4 /* Test for if SPACE_PACK used */
|
||||||
|
#define HA_VAR_LENGTH_KEY 8
|
||||||
|
#define HA_NULL_PART_KEY 64
|
||||||
|
#define HA_USES_PARSER 16384 /* Fulltext index uses [pre]parser */
|
||||||
|
#define HA_USES_BLOCK_SIZE ((uint) 32768)
|
||||||
|
#define HA_SORT_ALLOWS_SAME 512 /* Intern bit when sorting records */
|
||||||
|
#if MYSQL_VERSION_ID < 0x50200
|
||||||
|
/*
|
||||||
|
Key has a part that can have end space. If this is an unique key
|
||||||
|
we have to handle it differently from other unique keys as we can find
|
||||||
|
many matching rows for one key (because end space are not compared)
|
||||||
|
*/
|
||||||
|
#define HA_END_SPACE_KEY 0 /* was: 4096 */
|
||||||
|
#else
|
||||||
|
#error HA_END_SPACE_KEY is obsolete, please remove it
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* These flags can be added to key-seg-flag */
|
||||||
|
|
||||||
|
#define HA_SPACE_PACK 1 /* Pack space in key-seg */
|
||||||
|
#define HA_PART_KEY_SEG 4 /* Used by MySQL for part-key-cols */
|
||||||
|
#define HA_VAR_LENGTH_PART 8
|
||||||
|
#define HA_NULL_PART 16
|
||||||
|
#define HA_BLOB_PART 32
|
||||||
|
#define HA_SWAP_KEY 64
|
||||||
|
#define HA_REVERSE_SORT 128 /* Sort key in reverse order */
|
||||||
|
#define HA_NO_SORT 256 /* do not bother sorting on this keyseg */
|
||||||
|
/*
|
||||||
|
End space in unique/varchar are considered equal. (Like 'a' and 'a ')
|
||||||
|
Only needed for internal temporary tables.
|
||||||
|
*/
|
||||||
|
#define HA_END_SPACE_ARE_EQUAL 512
|
||||||
|
#define HA_BIT_PART 1024
|
||||||
|
|
||||||
|
/* optionbits for database */
|
||||||
|
#define HA_OPTION_PACK_RECORD 1
|
||||||
|
#define HA_OPTION_PACK_KEYS 2
|
||||||
|
#define HA_OPTION_COMPRESS_RECORD 4
|
||||||
|
#define HA_OPTION_LONG_BLOB_PTR 8 /* new ISAM format */
|
||||||
|
#define HA_OPTION_TMP_TABLE 16
|
||||||
|
#define HA_OPTION_CHECKSUM 32
|
||||||
|
#define HA_OPTION_DELAY_KEY_WRITE 64
|
||||||
|
#define HA_OPTION_NO_PACK_KEYS 128 /* Reserved for MySQL */
|
||||||
|
#define HA_OPTION_CREATE_FROM_ENGINE 256
|
||||||
|
#define HA_OPTION_RELIES_ON_SQL_LAYER 512
|
||||||
|
#define HA_OPTION_NULL_FIELDS 1024
|
||||||
|
#define HA_OPTION_PAGE_CHECKSUM 2048
|
||||||
|
#define HA_OPTION_TEMP_COMPRESS_RECORD ((uint) 16384) /* set by isamchk */
|
||||||
|
#define HA_OPTION_READ_ONLY_DATA ((uint) 32768) /* Set by isamchk */
|
||||||
|
|
||||||
|
/* Bits in flag to create() */
|
||||||
|
|
||||||
|
#define HA_DONT_TOUCH_DATA 1 /* Don't empty datafile (isamchk) */
|
||||||
|
#define HA_PACK_RECORD 2 /* Request packed record format */
|
||||||
|
#define HA_CREATE_TMP_TABLE 4
|
||||||
|
#define HA_CREATE_CHECKSUM 8
|
||||||
|
#define HA_CREATE_KEEP_FILES 16 /* don't overwrite .MYD and MYI */
|
||||||
|
#define HA_CREATE_PAGE_CHECKSUM 32
|
||||||
|
#define HA_CREATE_DELAY_KEY_WRITE 64
|
||||||
|
#define HA_CREATE_RELIES_ON_SQL_LAYER 128
|
||||||
|
|
||||||
|
/*
|
||||||
|
The following flags (OR-ed) are passed to handler::info() method.
|
||||||
|
The method copies misc handler information out of the storage engine
|
||||||
|
to data structures accessible from MySQL
|
||||||
|
|
||||||
|
Same flags are also passed down to mi_status, myrg_status, etc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* this one is not used */
|
||||||
|
#define HA_STATUS_POS 1
|
||||||
|
/*
|
||||||
|
assuming the table keeps shared actual copy of the 'info' and
|
||||||
|
local, possibly outdated copy, the following flag means that
|
||||||
|
it should not try to get the actual data (locking the shared structure)
|
||||||
|
slightly outdated version will suffice
|
||||||
|
*/
|
||||||
|
#define HA_STATUS_NO_LOCK 2
|
||||||
|
/* update the time of the last modification (in handler::update_time) */
|
||||||
|
#define HA_STATUS_TIME 4
|
||||||
|
/*
|
||||||
|
update the 'constant' part of the info:
|
||||||
|
handler::max_data_file_length, max_index_file_length, create_time
|
||||||
|
sortkey, ref_length, block_size, data_file_name, index_file_name.
|
||||||
|
handler::table->s->keys_in_use, keys_for_keyread, rec_per_key
|
||||||
|
*/
|
||||||
|
#define HA_STATUS_CONST 8
|
||||||
|
/*
|
||||||
|
update the 'variable' part of the info:
|
||||||
|
handler::records, deleted, data_file_length, index_file_length,
|
||||||
|
delete_length, check_time, mean_rec_length
|
||||||
|
*/
|
||||||
|
#define HA_STATUS_VARIABLE 16
|
||||||
|
/*
|
||||||
|
get the information about the key that caused last duplicate value error
|
||||||
|
update handler::errkey and handler::dupp_ref
|
||||||
|
see handler::get_dup_key()
|
||||||
|
*/
|
||||||
|
#define HA_STATUS_ERRKEY 32
|
||||||
|
/*
|
||||||
|
update handler::auto_increment_value
|
||||||
|
*/
|
||||||
|
#define HA_STATUS_AUTO 64
|
||||||
|
|
||||||
|
/*
|
||||||
|
Errorcodes given by handler functions
|
||||||
|
|
||||||
|
opt_sum_query() assumes these codes are > 1
|
||||||
|
Do not add error numbers before HA_ERR_FIRST.
|
||||||
|
If necessary to add lower numbers, change HA_ERR_FIRST accordingly.
|
||||||
|
*/
|
||||||
|
#define HA_ERR_FIRST 120 /* Copy of first error nr.*/
|
||||||
|
|
||||||
|
#define HA_ERR_KEY_NOT_FOUND 120 /* Didn't find key on read or update */
|
||||||
|
#define HA_ERR_FOUND_DUPP_KEY 121 /* Dupplicate key on write */
|
||||||
|
#define HA_ERR_INTERNAL_ERROR 122 /* Internal error */
|
||||||
|
#define HA_ERR_RECORD_CHANGED 123 /* Uppdate with is recoverable */
|
||||||
|
#define HA_ERR_WRONG_INDEX 124 /* Wrong index given to function */
|
||||||
|
#define HA_ERR_CRASHED 126 /* Indexfile is crashed */
|
||||||
|
#define HA_ERR_WRONG_IN_RECORD 127 /* Record-file is crashed */
|
||||||
|
#define HA_ERR_OUT_OF_MEM 128 /* Record-file is crashed */
|
||||||
|
#define HA_ERR_NOT_A_TABLE 130 /* not a MYI file - no signature */
|
||||||
|
#define HA_ERR_WRONG_COMMAND 131 /* Command not supported */
|
||||||
|
#define HA_ERR_OLD_FILE 132 /* old databasfile */
|
||||||
|
#define HA_ERR_NO_ACTIVE_RECORD 133 /* No record read in update() */
|
||||||
|
#define HA_ERR_RECORD_DELETED 134 /* A record is not there */
|
||||||
|
#define HA_ERR_RECORD_FILE_FULL 135 /* No more room in file */
|
||||||
|
#define HA_ERR_INDEX_FILE_FULL 136 /* No more room in file */
|
||||||
|
#define HA_ERR_END_OF_FILE 137 /* end in next/prev/first/last */
|
||||||
|
#define HA_ERR_UNSUPPORTED 138 /* unsupported extension used */
|
||||||
|
#define HA_ERR_TO_BIG_ROW 139 /* Too big row */
|
||||||
|
#define HA_WRONG_CREATE_OPTION 140 /* Wrong create option */
|
||||||
|
#define HA_ERR_FOUND_DUPP_UNIQUE 141 /* Dupplicate unique on write */
|
||||||
|
#define HA_ERR_UNKNOWN_CHARSET 142 /* Can't open charset */
|
||||||
|
#define HA_ERR_WRONG_MRG_TABLE_DEF 143 /* conflicting tables in MERGE */
|
||||||
|
#define HA_ERR_CRASHED_ON_REPAIR 144 /* Last (automatic?) repair failed */
|
||||||
|
#define HA_ERR_CRASHED_ON_USAGE 145 /* Table must be repaired */
|
||||||
|
#define HA_ERR_LOCK_WAIT_TIMEOUT 146
|
||||||
|
#define HA_ERR_LOCK_TABLE_FULL 147
|
||||||
|
#define HA_ERR_READ_ONLY_TRANSACTION 148 /* Updates not allowed */
|
||||||
|
#define HA_ERR_LOCK_DEADLOCK 149
|
||||||
|
#define HA_ERR_CANNOT_ADD_FOREIGN 150 /* Cannot add a foreign key constr. */
|
||||||
|
#define HA_ERR_NO_REFERENCED_ROW 151 /* Cannot add a child row */
|
||||||
|
#define HA_ERR_ROW_IS_REFERENCED 152 /* Cannot delete a parent row */
|
||||||
|
#define HA_ERR_NO_SAVEPOINT 153 /* No savepoint with that name */
|
||||||
|
#define HA_ERR_NON_UNIQUE_BLOCK_SIZE 154 /* Non unique key block size */
|
||||||
|
#define HA_ERR_NO_SUCH_TABLE 155 /* The table does not exist in engine */
|
||||||
|
#define HA_ERR_TABLE_EXIST 156 /* The table existed in storage engine */
|
||||||
|
#define HA_ERR_NO_CONNECTION 157 /* Could not connect to storage engine */
|
||||||
|
/* NULLs are not supported in spatial index */
|
||||||
|
#define HA_ERR_NULL_IN_SPATIAL 158
|
||||||
|
#define HA_ERR_TABLE_DEF_CHANGED 159 /* The table changed in storage engine */
|
||||||
|
/* There's no partition in table for given value */
|
||||||
|
#define HA_ERR_NO_PARTITION_FOUND 160
|
||||||
|
#define HA_ERR_RBR_LOGGING_FAILED 161 /* Row-based binlogging of row failed */
|
||||||
|
#define HA_ERR_DROP_INDEX_FK 162 /* Index needed in foreign key constr */
|
||||||
|
/*
|
||||||
|
Upholding foreign key constraints would lead to a duplicate key error
|
||||||
|
in some other table.
|
||||||
|
*/
|
||||||
|
#define HA_ERR_FOREIGN_DUPLICATE_KEY 163
|
||||||
|
/* The table changed in storage engine */
|
||||||
|
#define HA_ERR_TABLE_NEEDS_UPGRADE 164
|
||||||
|
#define HA_ERR_TABLE_READONLY 165 /* The table is not writable */
|
||||||
|
|
||||||
|
#define HA_ERR_AUTOINC_READ_FAILED 166 /* Failed to get next autoinc value */
|
||||||
|
#define HA_ERR_AUTOINC_ERANGE 167 /* Failed to set row autoinc value */
|
||||||
|
#define HA_ERR_GENERIC 168 /* Generic error */
|
||||||
|
/* row not actually updated: new values same as the old values */
|
||||||
|
#define HA_ERR_RECORD_IS_THE_SAME 169
|
||||||
|
/* It is not possible to log this statement */
|
||||||
|
#define HA_ERR_LOGGING_IMPOSSIBLE 170 /* It is not possible to log this
|
||||||
|
statement */
|
||||||
|
#define HA_ERR_CORRUPT_EVENT 171 /* The event was corrupt, leading to
|
||||||
|
illegal data being read */
|
||||||
|
#define HA_ERR_NEW_FILE 172 /* New file format */
|
||||||
|
#define HA_ERR_ROWS_EVENT_APPLY 173 /* The event could not be processed
|
||||||
|
no other hanlder error happened */
|
||||||
|
#define HA_ERR_INITIALIZATION 174 /* Error during initialization */
|
||||||
|
#define HA_ERR_FILE_TOO_SHORT 175 /* File too short */
|
||||||
|
#define HA_ERR_WRONG_CRC 176 /* Wrong CRC on page */
|
||||||
|
#define HA_ERR_TOO_MANY_CONCURRENT_TRXS 177 /*Too many active concurrent transactions */
|
||||||
|
#define HA_ERR_LAST 177 /* Copy of last error nr */
|
||||||
|
|
||||||
|
/* Number of different errors */
|
||||||
|
#define HA_ERR_ERRORS (HA_ERR_LAST - HA_ERR_FIRST + 1)
|
||||||
|
|
||||||
|
/* Other constants */
|
||||||
|
|
||||||
|
#define HA_NAMELEN 64 /* Max length of saved filename */
|
||||||
|
#define NO_SUCH_KEY (~(uint)0) /* used as a key no. */
|
||||||
|
|
||||||
|
typedef ulong key_part_map;
|
||||||
|
#define HA_WHOLE_KEY (~(key_part_map)0)
|
||||||
|
|
||||||
|
/* Intern constants in databases */
|
||||||
|
|
||||||
|
/* bits in _search */
|
||||||
|
#define SEARCH_FIND 1
|
||||||
|
#define SEARCH_NO_FIND 2
|
||||||
|
#define SEARCH_SAME 4
|
||||||
|
#define SEARCH_BIGGER 8
|
||||||
|
#define SEARCH_SMALLER 16
|
||||||
|
#define SEARCH_SAVE_BUFF 32
|
||||||
|
#define SEARCH_UPDATE 64
|
||||||
|
#define SEARCH_PREFIX 128
|
||||||
|
#define SEARCH_LAST 256
|
||||||
|
#define MBR_CONTAIN 512
|
||||||
|
#define MBR_INTERSECT 1024
|
||||||
|
#define MBR_WITHIN 2048
|
||||||
|
#define MBR_DISJOINT 4096
|
||||||
|
#define MBR_EQUAL 8192
|
||||||
|
#define MBR_DATA 16384
|
||||||
|
#define SEARCH_NULL_ARE_EQUAL 32768 /* NULL in keys are equal */
|
||||||
|
#define SEARCH_NULL_ARE_NOT_EQUAL 65536 /* NULL in keys are not equal */
|
||||||
|
|
||||||
|
/* bits in opt_flag */
|
||||||
|
#define QUICK_USED 1
|
||||||
|
#define READ_CACHE_USED 2
|
||||||
|
#define READ_CHECK_USED 4
|
||||||
|
#define KEY_READ_USED 8
|
||||||
|
#define WRITE_CACHE_USED 16
|
||||||
|
#define OPT_NO_ROWS 32
|
||||||
|
|
||||||
|
/* bits in update */
|
||||||
|
#define HA_STATE_CHANGED 1 /* Database has changed */
|
||||||
|
#define HA_STATE_AKTIV 2 /* Has a current record */
|
||||||
|
#define HA_STATE_WRITTEN 4 /* Record is written */
|
||||||
|
#define HA_STATE_DELETED 8
|
||||||
|
#define HA_STATE_NEXT_FOUND 16 /* Next found record (record before) */
|
||||||
|
#define HA_STATE_PREV_FOUND 32 /* Prev found record (record after) */
|
||||||
|
#define HA_STATE_NO_KEY 64 /* Last read didn't find record */
|
||||||
|
#define HA_STATE_KEY_CHANGED 128
|
||||||
|
#define HA_STATE_WRITE_AT_END 256 /* set in _ps_find_writepos */
|
||||||
|
#define HA_STATE_BUFF_SAVED 512 /* If current keybuff is info->buff */
|
||||||
|
#define HA_STATE_ROW_CHANGED 1024 /* To invalide ROW cache */
|
||||||
|
#define HA_STATE_EXTEND_BLOCK 2048
|
||||||
|
#define HA_STATE_RNEXT_SAME 4096 /* rnext_same occupied lastkey2 */
|
||||||
|
|
||||||
|
/* myisampack expects no more than 32 field types. */
|
||||||
|
enum en_fieldtype {
|
||||||
|
FIELD_LAST=-1,FIELD_NORMAL,FIELD_SKIP_ENDSPACE,FIELD_SKIP_PRESPACE,
|
||||||
|
FIELD_SKIP_ZERO,FIELD_BLOB,FIELD_CONSTANT,FIELD_INTERVALL,FIELD_ZERO,
|
||||||
|
FIELD_VARCHAR,FIELD_CHECK,
|
||||||
|
FIELD_enum_val_count
|
||||||
|
};
|
||||||
|
|
||||||
|
enum data_file_type {
|
||||||
|
STATIC_RECORD, DYNAMIC_RECORD, COMPRESSED_RECORD, BLOCK_RECORD
|
||||||
|
};
|
||||||
|
|
||||||
|
/* For key ranges */
|
||||||
|
|
||||||
|
#define NO_MIN_RANGE 1
|
||||||
|
#define NO_MAX_RANGE 2
|
||||||
|
#define NEAR_MIN 4
|
||||||
|
#define NEAR_MAX 8
|
||||||
|
#define UNIQUE_RANGE 16
|
||||||
|
#define EQ_RANGE 32
|
||||||
|
#define NULL_RANGE 64
|
||||||
|
#define GEOM_FLAG 128
|
||||||
|
#define SKIP_RANGE 256
|
||||||
|
|
||||||
|
typedef struct st_key_range
|
||||||
|
{
|
||||||
|
const uchar *key;
|
||||||
|
uint length;
|
||||||
|
key_part_map keypart_map;
|
||||||
|
enum ha_rkey_function flag;
|
||||||
|
} key_range;
|
||||||
|
|
||||||
|
typedef struct st_key_multi_range
|
||||||
|
{
|
||||||
|
key_range start_key;
|
||||||
|
key_range end_key;
|
||||||
|
char *ptr; /* Free to use by caller (ptr to row etc) */
|
||||||
|
uint range_flag; /* key range flags see above */
|
||||||
|
} KEY_MULTI_RANGE;
|
||||||
|
|
||||||
|
|
||||||
|
/* For number of records */
|
||||||
|
#ifdef BIG_TABLES
|
||||||
|
#define rows2double(A) ulonglong2double(A)
|
||||||
|
typedef my_off_t ha_rows;
|
||||||
|
#else
|
||||||
|
#define rows2double(A) (double) (A)
|
||||||
|
typedef ulong ha_rows;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define HA_POS_ERROR (~ (ha_rows) 0)
|
||||||
|
#define HA_OFFSET_ERROR (~ (my_off_t) 0)
|
||||||
|
|
||||||
|
#if SYSTEM_SIZEOF_OFF_T == 4
|
||||||
|
#define MAX_FILE_SIZE INT_MAX32
|
||||||
|
#else
|
||||||
|
#define MAX_FILE_SIZE LONGLONG_MAX
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define HA_VARCHAR_PACKLENGTH(field_length) ((field_length) < 256 ? 1 :2)
|
||||||
|
|
||||||
|
/* invalidator function reference for Query Cache */
|
||||||
|
typedef void (* invalidator_by_filename)(const char * filename);
|
||||||
|
|
||||||
|
#endif /* _my_base_h */
|
114
MySQL/my_chsize.c
Normal file
114
MySQL/my_chsize.c
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
/* Copyright (C) 2000 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
#include "mysys_priv.h"
|
||||||
|
#include "mysys_err.h"
|
||||||
|
#include "m_string.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
Change size of file.
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
my_chsize()
|
||||||
|
fd File descriptor
|
||||||
|
new_length New file size
|
||||||
|
filler If we don't have truncate, fill up all bytes after
|
||||||
|
new_length with this character
|
||||||
|
MyFlags Flags
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
my_chsize() truncates file if shorter else fill with the filler character.
|
||||||
|
The function also changes the file pointer. Usually it points to the end
|
||||||
|
of the file after execution.
|
||||||
|
|
||||||
|
RETURN VALUE
|
||||||
|
0 Ok
|
||||||
|
1 Error
|
||||||
|
*/
|
||||||
|
int my_chsize(File fd, my_off_t newlength, int filler, myf MyFlags)
|
||||||
|
{
|
||||||
|
my_off_t oldsize;
|
||||||
|
uchar buff[IO_SIZE];
|
||||||
|
DBUG_ENTER("my_chsize");
|
||||||
|
DBUG_PRINT("my",("fd: %d length: %lu MyFlags: %d",fd,(ulong) newlength,
|
||||||
|
MyFlags));
|
||||||
|
|
||||||
|
if ((oldsize= my_seek(fd, 0L, MY_SEEK_END, MYF(MY_WME+MY_FAE))) == newlength)
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
|
||||||
|
DBUG_PRINT("info",("old_size: %ld", (ulong) oldsize));
|
||||||
|
|
||||||
|
if (oldsize > newlength)
|
||||||
|
{
|
||||||
|
#if defined(HAVE_SETFILEPOINTER)
|
||||||
|
/* This is for the moment only true on windows */
|
||||||
|
long is_success;
|
||||||
|
HANDLE win_file= (HANDLE) _get_osfhandle(fd);
|
||||||
|
long length_low, length_high;
|
||||||
|
length_low= (long) (ulong) newlength;
|
||||||
|
length_high= (long) ((ulonglong) newlength >> 32);
|
||||||
|
is_success= SetFilePointer(win_file, length_low, &length_high, FILE_BEGIN);
|
||||||
|
if (is_success == -1 && (my_errno= GetLastError()) != NO_ERROR)
|
||||||
|
goto err;
|
||||||
|
if (SetEndOfFile(win_file))
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
my_errno= GetLastError();
|
||||||
|
goto err;
|
||||||
|
#elif defined(HAVE_FTRUNCATE)
|
||||||
|
if (ftruncate(fd, (off_t) newlength))
|
||||||
|
{
|
||||||
|
my_errno= errno;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
#elif defined(HAVE_CHSIZE)
|
||||||
|
if (chsize(fd, (off_t) newlength))
|
||||||
|
{
|
||||||
|
my_errno=errno;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
#else
|
||||||
|
/*
|
||||||
|
Fill space between requested length and true length with 'filler'
|
||||||
|
We should never come here on any modern machine
|
||||||
|
*/
|
||||||
|
if (my_seek(fd, newlength, MY_SEEK_SET, MYF(MY_WME+MY_FAE))
|
||||||
|
== MY_FILEPOS_ERROR)
|
||||||
|
{
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
swap_variables(my_off_t, newlength, oldsize);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Full file with 'filler' until it's as big as requested */
|
||||||
|
bfill(buff, IO_SIZE, filler);
|
||||||
|
while (newlength-oldsize > IO_SIZE)
|
||||||
|
{
|
||||||
|
if (my_write(fd, buff, IO_SIZE, MYF(MY_NABP)))
|
||||||
|
goto err;
|
||||||
|
oldsize+= IO_SIZE;
|
||||||
|
}
|
||||||
|
if (my_write(fd,buff,(size_t) (newlength-oldsize), MYF(MY_NABP)))
|
||||||
|
goto err;
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
|
||||||
|
err:
|
||||||
|
DBUG_PRINT("error", ("errno: %d", errno));
|
||||||
|
if (MyFlags & MY_WME)
|
||||||
|
my_error(EE_CANT_CHSIZE, MYF(ME_BELL+ME_WAITTANG), my_errno);
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
} /* my_chsize */
|
264
MySQL/my_compress.c
Normal file
264
MySQL/my_compress.c
Normal file
@ -0,0 +1,264 @@
|
|||||||
|
/* Copyright (C) 2000 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
/* Written by Sinisa Milivojevic <sinisa@mysql.com> */
|
||||||
|
|
||||||
|
#include <my_global.h>
|
||||||
|
#ifdef HAVE_COMPRESS
|
||||||
|
#include <my_sys.h>
|
||||||
|
#ifndef SCO
|
||||||
|
#include <m_string.h>
|
||||||
|
#endif
|
||||||
|
#include <zlib.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
This replaces the packet with a compressed packet
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
my_compress()
|
||||||
|
packet Data to compress. This is is replaced with the compressed data.
|
||||||
|
len Length of data to compress at 'packet'
|
||||||
|
complen out: 0 if packet was not compressed
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
1 error. 'len' is not changed'
|
||||||
|
0 ok. In this case 'len' contains the size of the compressed packet
|
||||||
|
*/
|
||||||
|
|
||||||
|
my_bool my_compress(uchar *packet, size_t *len, size_t *complen)
|
||||||
|
{
|
||||||
|
DBUG_ENTER("my_compress");
|
||||||
|
if (*len < MIN_COMPRESS_LENGTH)
|
||||||
|
{
|
||||||
|
*complen=0;
|
||||||
|
DBUG_PRINT("note",("Packet too short: Not compressed"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uchar *compbuf=my_compress_alloc(packet,len,complen);
|
||||||
|
if (!compbuf)
|
||||||
|
DBUG_RETURN(*complen ? 0 : 1);
|
||||||
|
memcpy(packet,compbuf,*len);
|
||||||
|
my_free(compbuf,MYF(MY_WME));
|
||||||
|
}
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uchar *my_compress_alloc(const uchar *packet, size_t *len, size_t *complen)
|
||||||
|
{
|
||||||
|
uchar *compbuf;
|
||||||
|
uLongf tmp_complen;
|
||||||
|
int res;
|
||||||
|
*complen= *len * 120 / 100 + 12;
|
||||||
|
|
||||||
|
if (!(compbuf= (uchar *) my_malloc(*complen, MYF(MY_WME))))
|
||||||
|
return 0; /* Not enough memory */
|
||||||
|
|
||||||
|
tmp_complen= (uint) *complen;
|
||||||
|
res= compress((Bytef*) compbuf, &tmp_complen, (Bytef*) packet, (uLong) *len);
|
||||||
|
*complen= tmp_complen;
|
||||||
|
|
||||||
|
if (res != Z_OK)
|
||||||
|
{
|
||||||
|
my_free(compbuf, MYF(MY_WME));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*complen >= *len)
|
||||||
|
{
|
||||||
|
*complen= 0;
|
||||||
|
my_free(compbuf, MYF(MY_WME));
|
||||||
|
DBUG_PRINT("note",("Packet got longer on compression; Not compressed"));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* Store length of compressed packet in *len */
|
||||||
|
swap_variables(size_t, *len, *complen);
|
||||||
|
return compbuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Uncompress packet
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
my_uncompress()
|
||||||
|
packet Compressed data. This is is replaced with the orignal data.
|
||||||
|
len Length of compressed data
|
||||||
|
complen Length of the packet buffer (must be enough for the original
|
||||||
|
data)
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
1 error
|
||||||
|
0 ok. In this case 'complen' contains the updated size of the
|
||||||
|
real data.
|
||||||
|
*/
|
||||||
|
|
||||||
|
my_bool my_uncompress(uchar *packet, size_t len, size_t *complen)
|
||||||
|
{
|
||||||
|
uLongf tmp_complen;
|
||||||
|
DBUG_ENTER("my_uncompress");
|
||||||
|
|
||||||
|
if (*complen) /* If compressed */
|
||||||
|
{
|
||||||
|
uchar *compbuf= (uchar *) my_malloc(*complen,MYF(MY_WME));
|
||||||
|
int error;
|
||||||
|
if (!compbuf)
|
||||||
|
DBUG_RETURN(1); /* Not enough memory */
|
||||||
|
|
||||||
|
tmp_complen= (uint) *complen;
|
||||||
|
error= uncompress((Bytef*) compbuf, &tmp_complen, (Bytef*) packet,
|
||||||
|
(uLong) len);
|
||||||
|
*complen= tmp_complen;
|
||||||
|
if (error != Z_OK)
|
||||||
|
{ /* Probably wrong packet */
|
||||||
|
DBUG_PRINT("error",("Can't uncompress packet, error: %d",error));
|
||||||
|
my_free(compbuf, MYF(MY_WME));
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
|
memcpy(packet, compbuf, *complen);
|
||||||
|
my_free(compbuf, MYF(MY_WME));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*complen= len;
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Internal representation of the frm blob is:
|
||||||
|
|
||||||
|
ver 4 bytes
|
||||||
|
orglen 4 bytes
|
||||||
|
complen 4 bytes
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define BLOB_HEADER 12
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
packfrm is a method used to compress the frm file for storage in a
|
||||||
|
handler. This method was developed for the NDB handler and has been moved
|
||||||
|
here to serve also other uses.
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
packfrm()
|
||||||
|
data Data reference to frm file data.
|
||||||
|
len Length of frm file data
|
||||||
|
out:pack_data Reference to the pointer to the packed frm data
|
||||||
|
out:pack_len Length of packed frm file data
|
||||||
|
|
||||||
|
NOTES
|
||||||
|
data is replaced with compressed content
|
||||||
|
|
||||||
|
RETURN VALUES
|
||||||
|
0 Success
|
||||||
|
>0 Failure
|
||||||
|
*/
|
||||||
|
|
||||||
|
int packfrm(uchar *data, size_t len,
|
||||||
|
uchar **pack_data, size_t *pack_len)
|
||||||
|
{
|
||||||
|
int error;
|
||||||
|
size_t org_len, comp_len, blob_len;
|
||||||
|
uchar *blob;
|
||||||
|
DBUG_ENTER("packfrm");
|
||||||
|
DBUG_PRINT("enter", ("data: 0x%lx len: %lu", (long) data, (ulong) len));
|
||||||
|
|
||||||
|
error= 1;
|
||||||
|
org_len= len;
|
||||||
|
if (my_compress((uchar*)data, &org_len, &comp_len))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
DBUG_PRINT("info", ("org_len: %lu comp_len: %lu", (ulong) org_len,
|
||||||
|
(ulong) comp_len));
|
||||||
|
DBUG_DUMP("compressed", data, org_len);
|
||||||
|
|
||||||
|
error= 2;
|
||||||
|
blob_len= BLOB_HEADER + org_len;
|
||||||
|
if (!(blob= (uchar*) my_malloc(blob_len,MYF(MY_WME))))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
/* Store compressed blob in machine independent format */
|
||||||
|
int4store(blob, 1);
|
||||||
|
int4store(blob+4, (uint32) len);
|
||||||
|
int4store(blob+8, (uint32) org_len); /* compressed length */
|
||||||
|
|
||||||
|
/* Copy frm data into blob, already in machine independent format */
|
||||||
|
memcpy(blob+BLOB_HEADER, data, org_len);
|
||||||
|
|
||||||
|
*pack_data= blob;
|
||||||
|
*pack_len= blob_len;
|
||||||
|
error= 0;
|
||||||
|
|
||||||
|
DBUG_PRINT("exit", ("pack_data: 0x%lx pack_len: %lu",
|
||||||
|
(long) *pack_data, (ulong) *pack_len));
|
||||||
|
err:
|
||||||
|
DBUG_RETURN(error);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
unpackfrm is a method used to decompress the frm file received from a
|
||||||
|
handler. This method was developed for the NDB handler and has been moved
|
||||||
|
here to serve also other uses for other clustered storage engines.
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
unpackfrm()
|
||||||
|
pack_data Data reference to packed frm file data
|
||||||
|
out:unpack_data Reference to the pointer to the unpacked frm data
|
||||||
|
out:unpack_len Length of unpacked frm file data
|
||||||
|
|
||||||
|
RETURN VALUES¨
|
||||||
|
0 Success
|
||||||
|
>0 Failure
|
||||||
|
*/
|
||||||
|
|
||||||
|
int unpackfrm(uchar **unpack_data, size_t *unpack_len,
|
||||||
|
const uchar *pack_data)
|
||||||
|
{
|
||||||
|
uchar *data;
|
||||||
|
size_t complen, orglen;
|
||||||
|
ulong ver;
|
||||||
|
DBUG_ENTER("unpackfrm");
|
||||||
|
DBUG_PRINT("enter", ("pack_data: 0x%lx", (long) pack_data));
|
||||||
|
|
||||||
|
ver= uint4korr(pack_data);
|
||||||
|
orglen= uint4korr(pack_data+4);
|
||||||
|
complen= uint4korr(pack_data+8);
|
||||||
|
|
||||||
|
DBUG_PRINT("blob",("ver: %lu complen: %lu orglen: %lu",
|
||||||
|
ver, (ulong) complen, (ulong) orglen));
|
||||||
|
DBUG_DUMP("blob->data", pack_data + BLOB_HEADER, complen);
|
||||||
|
|
||||||
|
if (ver != 1)
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
if (!(data= my_malloc(max(orglen, complen), MYF(MY_WME))))
|
||||||
|
DBUG_RETURN(2);
|
||||||
|
memcpy(data, pack_data + BLOB_HEADER, complen);
|
||||||
|
|
||||||
|
if (my_uncompress(data, complen, &orglen))
|
||||||
|
{
|
||||||
|
my_free(data, MYF(0));
|
||||||
|
DBUG_RETURN(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
*unpack_data= data;
|
||||||
|
*unpack_len= orglen;
|
||||||
|
|
||||||
|
DBUG_PRINT("exit", ("frmdata: 0x%lx len: %lu", (long) *unpack_data,
|
||||||
|
(ulong) *unpack_len));
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
}
|
||||||
|
#endif /* HAVE_COMPRESS */
|
1350
MySQL/my_config.h
Normal file
1350
MySQL/my_config.h
Normal file
File diff suppressed because it is too large
Load Diff
79
MySQL/my_create.c
Normal file
79
MySQL/my_create.c
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
/* Copyright (C) 2000 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
#include "mysys_priv.h"
|
||||||
|
#include <my_dir.h>
|
||||||
|
#include "mysys_err.h"
|
||||||
|
#include <errno.h>
|
||||||
|
#include <my_sys.h>
|
||||||
|
#if defined(__WIN__)
|
||||||
|
#include <share.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Create a new file
|
||||||
|
** Arguments:
|
||||||
|
** Path-name of file
|
||||||
|
** Read | write on file (umask value)
|
||||||
|
** Read & Write on open file
|
||||||
|
** Special flags
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
File my_create(const char *FileName, int CreateFlags, int access_flags,
|
||||||
|
myf MyFlags)
|
||||||
|
{
|
||||||
|
int fd, rc;
|
||||||
|
DBUG_ENTER("my_create");
|
||||||
|
DBUG_PRINT("my",("Name: '%s' CreateFlags: %d AccessFlags: %d MyFlags: %d",
|
||||||
|
FileName, CreateFlags, access_flags, MyFlags));
|
||||||
|
|
||||||
|
#if !defined(NO_OPEN_3)
|
||||||
|
fd = open((char *) FileName, access_flags | O_CREAT,
|
||||||
|
CreateFlags ? CreateFlags : my_umask);
|
||||||
|
#elif defined(VMS)
|
||||||
|
fd = open((char *) FileName, access_flags | O_CREAT, 0,
|
||||||
|
"ctx=stm","ctx=bin");
|
||||||
|
#elif defined(__WIN__)
|
||||||
|
fd= my_sopen((char *) FileName, access_flags | O_CREAT | O_BINARY,
|
||||||
|
SH_DENYNO, MY_S_IREAD | MY_S_IWRITE);
|
||||||
|
#else
|
||||||
|
fd = open(FileName, access_flags);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if ((MyFlags & MY_SYNC_DIR) && (fd >=0) &&
|
||||||
|
my_sync_dir_by_file(FileName, MyFlags))
|
||||||
|
{
|
||||||
|
my_close(fd, MyFlags);
|
||||||
|
fd= -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc= my_register_filename(fd, FileName, FILE_BY_CREATE,
|
||||||
|
EE_CANTCREATEFILE, MyFlags);
|
||||||
|
/*
|
||||||
|
my_register_filename() may fail on some platforms even if the call to
|
||||||
|
*open() above succeeds. In this case, don't leave the stale file because
|
||||||
|
callers assume the file to not exist if my_create() fails, so they don't
|
||||||
|
do any cleanups.
|
||||||
|
*/
|
||||||
|
if (unlikely(fd >= 0 && rc < 0))
|
||||||
|
{
|
||||||
|
int tmp= my_errno;
|
||||||
|
my_delete(FileName, MyFlags);
|
||||||
|
my_errno= tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
DBUG_RETURN(rc);
|
||||||
|
} /* my_create */
|
159
MySQL/my_dbug.h
Normal file
159
MySQL/my_dbug.h
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
/* Copyright (C) 2000 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
#ifndef _dbug_h
|
||||||
|
#define _dbug_h
|
||||||
|
|
||||||
|
#if defined(__cplusplus) && !defined(DBUG_OFF)
|
||||||
|
class Dbug_violation_helper
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline Dbug_violation_helper() :
|
||||||
|
_entered(TRUE)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
inline ~Dbug_violation_helper()
|
||||||
|
{
|
||||||
|
assert(!_entered);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void leave()
|
||||||
|
{
|
||||||
|
_entered= FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool _entered;
|
||||||
|
};
|
||||||
|
#endif /* C++ */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
#if !defined(DBUG_OFF) && !defined(_lint)
|
||||||
|
struct _db_code_state_;
|
||||||
|
extern int _db_keyword_(struct _db_code_state_ *cs, const char *keyword);
|
||||||
|
extern int _db_strict_keyword_(const char *keyword);
|
||||||
|
extern int _db_explain_(struct _db_code_state_ *cs, char *buf, size_t len);
|
||||||
|
extern int _db_explain_init_(char *buf, size_t len);
|
||||||
|
extern void _db_setjmp_(void);
|
||||||
|
extern void _db_longjmp_(void);
|
||||||
|
extern void _db_process_(const char *name);
|
||||||
|
extern void _db_push_(const char *control);
|
||||||
|
extern void _db_pop_(void);
|
||||||
|
extern void _db_set_(struct _db_code_state_ *cs, const char *control);
|
||||||
|
extern void _db_set_init_(const char *control);
|
||||||
|
extern void _db_enter_(const char *_func_,const char *_file_,uint _line_,
|
||||||
|
const char **_sfunc_,const char **_sfile_,
|
||||||
|
uint *_slevel_, char ***);
|
||||||
|
extern void _db_return_(uint _line_,const char **_sfunc_,const char **_sfile_,
|
||||||
|
uint *_slevel_);
|
||||||
|
extern void _db_pargs_(uint _line_,const char *keyword);
|
||||||
|
extern void _db_doprnt_ _VARARGS((const char *format,...))
|
||||||
|
ATTRIBUTE_FORMAT(printf, 1, 2);
|
||||||
|
extern void _db_dump_(uint _line_,const char *keyword,
|
||||||
|
const unsigned char *memory, size_t length);
|
||||||
|
extern void _db_end_(void);
|
||||||
|
extern void _db_lock_file_(void);
|
||||||
|
extern void _db_unlock_file_(void);
|
||||||
|
extern FILE *_db_fp_(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
|
||||||
|
#define DBUG_ENTER(a) \
|
||||||
|
const char *_db_func_, *_db_file_; \
|
||||||
|
uint _db_level_; \
|
||||||
|
char **_db_framep_; \
|
||||||
|
Dbug_violation_helper dbug_violation_helper; \
|
||||||
|
_db_enter_ (a, __FILE__, __LINE__, &_db_func_, &_db_file_, \
|
||||||
|
&_db_level_, &_db_framep_)
|
||||||
|
#define DBUG_VIOLATION_HELPER_LEAVE dbug_violation_helper.leave()
|
||||||
|
|
||||||
|
#else /* C */
|
||||||
|
|
||||||
|
#define DBUG_ENTER(a) \
|
||||||
|
const char *_db_func_, *_db_file_; \
|
||||||
|
uint _db_level_; \
|
||||||
|
char **_db_framep_; \
|
||||||
|
_db_enter_ (a, __FILE__, __LINE__, &_db_func_, &_db_file_, \
|
||||||
|
&_db_level_, &_db_framep_)
|
||||||
|
#define DBUG_VIOLATION_HELPER_LEAVE do { } while(0)
|
||||||
|
|
||||||
|
#endif /* C++ */
|
||||||
|
|
||||||
|
#define DBUG_LEAVE \
|
||||||
|
DBUG_VIOLATION_HELPER_LEAVE; \
|
||||||
|
_db_return_ (__LINE__, &_db_func_, &_db_file_, &_db_level_)
|
||||||
|
#define DBUG_RETURN(a1) do {DBUG_LEAVE; return(a1);} while(0)
|
||||||
|
#define DBUG_VOID_RETURN do {DBUG_LEAVE; return;} while(0)
|
||||||
|
#define DBUG_EXECUTE(keyword,a1) \
|
||||||
|
do {if (_db_keyword_(0, (keyword))) { a1 }} while(0)
|
||||||
|
#define DBUG_EXECUTE_IF(keyword,a1) \
|
||||||
|
do {if (_db_strict_keyword_ (keyword)) { a1 } } while(0)
|
||||||
|
#define DBUG_EVALUATE(keyword,a1,a2) \
|
||||||
|
(_db_keyword_(0,(keyword)) ? (a1) : (a2))
|
||||||
|
#define DBUG_EVALUATE_IF(keyword,a1,a2) \
|
||||||
|
(_db_strict_keyword_((keyword)) ? (a1) : (a2))
|
||||||
|
#define DBUG_PRINT(keyword,arglist) \
|
||||||
|
do {_db_pargs_(__LINE__,keyword); _db_doprnt_ arglist;} while(0)
|
||||||
|
#define DBUG_PUSH(a1) _db_push_ (a1)
|
||||||
|
#define DBUG_POP() _db_pop_ ()
|
||||||
|
#define DBUG_SET(a1) _db_set_ (0, (a1))
|
||||||
|
#define DBUG_SET_INITIAL(a1) _db_set_init_ (a1)
|
||||||
|
#define DBUG_PROCESS(a1) _db_process_(a1)
|
||||||
|
#define DBUG_FILE _db_fp_()
|
||||||
|
#define DBUG_SETJMP(a1) (_db_setjmp_ (), setjmp (a1))
|
||||||
|
#define DBUG_LONGJMP(a1,a2) (_db_longjmp_ (), longjmp (a1, a2))
|
||||||
|
#define DBUG_DUMP(keyword,a1,a2) _db_dump_(__LINE__,keyword,a1,a2)
|
||||||
|
#define DBUG_END() _db_end_ ()
|
||||||
|
#define DBUG_LOCK_FILE _db_lock_file_()
|
||||||
|
#define DBUG_UNLOCK_FILE _db_unlock_file_()
|
||||||
|
#define DBUG_ASSERT(A) assert(A)
|
||||||
|
#define DBUG_EXPLAIN(buf,len) _db_explain_(0, (buf),(len))
|
||||||
|
#define DBUG_EXPLAIN_INITIAL(buf,len) _db_explain_init_((buf),(len))
|
||||||
|
#define IF_DBUG(A) A
|
||||||
|
#else /* No debugger */
|
||||||
|
|
||||||
|
#define DBUG_ENTER(a1)
|
||||||
|
#define DBUG_LEAVE
|
||||||
|
#define DBUG_VIOLATION_HELPER_LEAVE
|
||||||
|
#define DBUG_RETURN(a1) do { return(a1); } while(0)
|
||||||
|
#define DBUG_VOID_RETURN do { return; } while(0)
|
||||||
|
#define DBUG_EXECUTE(keyword,a1) do { } while(0)
|
||||||
|
#define DBUG_EXECUTE_IF(keyword,a1) do { } while(0)
|
||||||
|
#define DBUG_EVALUATE(keyword,a1,a2) (a2)
|
||||||
|
#define DBUG_EVALUATE_IF(keyword,a1,a2) (a2)
|
||||||
|
#define DBUG_PRINT(keyword,arglist) do { } while(0)
|
||||||
|
#define DBUG_PUSH(a1)
|
||||||
|
#define DBUG_SET(a1) do { } while(0)
|
||||||
|
#define DBUG_SET_INITIAL(a1) do { } while(0)
|
||||||
|
#define DBUG_POP()
|
||||||
|
#define DBUG_PROCESS(a1)
|
||||||
|
#define DBUG_SETJMP(a1) setjmp(a1)
|
||||||
|
#define DBUG_LONGJMP(a1) longjmp(a1)
|
||||||
|
#define DBUG_DUMP(keyword,a1,a2) do { } while(0)
|
||||||
|
#define DBUG_END()
|
||||||
|
#define DBUG_ASSERT(A) do { } while(0)
|
||||||
|
#define DBUG_LOCK_FILE
|
||||||
|
#define DBUG_FILE (stderr)
|
||||||
|
#define DBUG_UNLOCK_FILE
|
||||||
|
#define DBUG_EXPLAIN(buf,len)
|
||||||
|
#define DBUG_EXPLAIN_INITIAL(buf,len)
|
||||||
|
#define IF_DBUG(A)
|
||||||
|
#endif
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
92
MySQL/my_delete.c
Normal file
92
MySQL/my_delete.c
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
/* Copyright (C) 2000 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
#include "mysys_priv.h"
|
||||||
|
#include "mysys_err.h"
|
||||||
|
#include <my_sys.h>
|
||||||
|
|
||||||
|
int my_delete(const char *name, myf MyFlags)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
DBUG_ENTER("my_delete");
|
||||||
|
DBUG_PRINT("my",("name %s MyFlags %d", name, MyFlags));
|
||||||
|
|
||||||
|
if ((err = unlink(name)) == -1)
|
||||||
|
{
|
||||||
|
my_errno=errno;
|
||||||
|
if (MyFlags & (MY_FAE+MY_WME))
|
||||||
|
my_error(EE_DELETE,MYF(ME_BELL+ME_WAITTANG+(MyFlags & ME_NOINPUT)),
|
||||||
|
name,errno);
|
||||||
|
}
|
||||||
|
else if ((MyFlags & MY_SYNC_DIR) &&
|
||||||
|
my_sync_dir_by_file(name, MyFlags))
|
||||||
|
err= -1;
|
||||||
|
DBUG_RETURN(err);
|
||||||
|
} /* my_delete */
|
||||||
|
|
||||||
|
#if defined(__WIN__) && defined(__NT__)
|
||||||
|
/*
|
||||||
|
Delete file which is possibly not closed.
|
||||||
|
|
||||||
|
This function is intended to be used exclusively as a temporal solution
|
||||||
|
for Win NT in case when it is needed to delete a not closed file (note
|
||||||
|
that the file must be opened everywhere with FILE_SHARE_DELETE mode).
|
||||||
|
Deleting not-closed files can not be supported on Win 98|ME (and because
|
||||||
|
of that is considered harmful).
|
||||||
|
|
||||||
|
The function deletes the file with its preliminary renaming. This is
|
||||||
|
because when not-closed share-delete file is deleted it still lives on
|
||||||
|
a disk until it will not be closed everwhere. This may conflict with an
|
||||||
|
attempt to create a new file with the same name. The deleted file is
|
||||||
|
renamed to <name>.<num>.deleted where <name> - the initial name of the
|
||||||
|
file, <num> - a hexadecimal number chosen to make the temporal name to
|
||||||
|
be unique.
|
||||||
|
*/
|
||||||
|
int nt_share_delete(const char *name, myf MyFlags)
|
||||||
|
{
|
||||||
|
char buf[MAX_PATH + 20];
|
||||||
|
ulong cnt;
|
||||||
|
DBUG_ENTER("nt_share_delete");
|
||||||
|
DBUG_PRINT("my",("name %s MyFlags %d", name, MyFlags));
|
||||||
|
|
||||||
|
for (cnt= GetTickCount(); cnt; cnt--)
|
||||||
|
{
|
||||||
|
sprintf(buf, "%s.%08X.deleted", name, cnt);
|
||||||
|
if (MoveFile(name, buf))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if ((errno= GetLastError()) == ERROR_ALREADY_EXISTS)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* This happened during tests with MERGE tables. */
|
||||||
|
if (errno == ERROR_ACCESS_DENIED)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
DBUG_PRINT("warning", ("Failed to rename %s to %s, errno: %d",
|
||||||
|
name, buf, errno));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DeleteFile(buf))
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
|
||||||
|
my_errno= GetLastError();
|
||||||
|
if (MyFlags & (MY_FAE+MY_WME))
|
||||||
|
my_error(EE_DELETE, MYF(ME_BELL + ME_WAITTANG + (MyFlags & ME_NOINPUT)),
|
||||||
|
name, my_errno);
|
||||||
|
|
||||||
|
DBUG_RETURN(-1);
|
||||||
|
}
|
||||||
|
#endif
|
105
MySQL/my_dir.h
Normal file
105
MySQL/my_dir.h
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
/* Copyright (C) 2000 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
#ifndef _my_dir_h
|
||||||
|
#define _my_dir_h
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MY_DIR_H
|
||||||
|
#define MY_DIR_H
|
||||||
|
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
/* Defines for my_dir and my_stat */
|
||||||
|
|
||||||
|
#define MY_S_IFMT S_IFMT /* type of file */
|
||||||
|
#define MY_S_IFDIR S_IFDIR /* directory */
|
||||||
|
#define MY_S_IFCHR S_IFCHR /* character special */
|
||||||
|
#define MY_S_IFBLK S_IFBLK /* block special */
|
||||||
|
#define MY_S_IFREG S_IFREG /* regular */
|
||||||
|
#define MY_S_IFIFO S_IFIFO /* fifo */
|
||||||
|
#define MY_S_ISUID S_ISUID /* set user id on execution */
|
||||||
|
#define MY_S_ISGID S_ISGID /* set group id on execution */
|
||||||
|
#define MY_S_ISVTX S_ISVTX /* save swapped text even after use */
|
||||||
|
#define MY_S_IREAD S_IREAD /* read permission, owner */
|
||||||
|
#define MY_S_IWRITE S_IWRITE /* write permission, owner */
|
||||||
|
#define MY_S_IEXEC S_IEXEC /* execute/search permission, owner */
|
||||||
|
|
||||||
|
#define MY_S_ISDIR(m) (((m) & MY_S_IFMT) == MY_S_IFDIR)
|
||||||
|
#define MY_S_ISCHR(m) (((m) & MY_S_IFMT) == MY_S_IFCHR)
|
||||||
|
#define MY_S_ISBLK(m) (((m) & MY_S_IFMT) == MY_S_IFBLK)
|
||||||
|
#define MY_S_ISREG(m) (((m) & MY_S_IFMT) == MY_S_IFREG)
|
||||||
|
#define MY_S_ISFIFO(m) (((m) & MY_S_IFMT) == MY_S_IFIFO)
|
||||||
|
|
||||||
|
#define MY_DONT_SORT 512 /* my_lib; Don't sort files */
|
||||||
|
#define MY_WANT_STAT 1024 /* my_lib; stat files */
|
||||||
|
|
||||||
|
/* typedefs for my_dir & my_stat */
|
||||||
|
|
||||||
|
#ifdef USE_MY_STAT_STRUCT
|
||||||
|
|
||||||
|
typedef struct my_stat
|
||||||
|
{
|
||||||
|
dev_t st_dev; /* major & minor device numbers */
|
||||||
|
ino_t st_ino; /* inode number */
|
||||||
|
ushort st_mode; /* file permissons (& suid sgid .. bits) */
|
||||||
|
short st_nlink; /* number of links to file */
|
||||||
|
ushort st_uid; /* user id */
|
||||||
|
ushort st_gid; /* group id */
|
||||||
|
dev_t st_rdev; /* more major & minor device numbers (???) */
|
||||||
|
off_t st_size; /* size of file */
|
||||||
|
time_t st_atime; /* time for last read */
|
||||||
|
time_t st_mtime; /* time for last contens modify */
|
||||||
|
time_t st_ctime; /* time for last inode or contents modify */
|
||||||
|
} MY_STAT;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define MY_STAT struct stat /* Orginal struct have what we need */
|
||||||
|
|
||||||
|
#endif /* USE_MY_STAT_STRUCT */
|
||||||
|
|
||||||
|
/* Struct describing one file returned from my_dir */
|
||||||
|
typedef struct fileinfo
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
MY_STAT *mystat;
|
||||||
|
} FILEINFO;
|
||||||
|
|
||||||
|
typedef struct st_my_dir /* Struct returned from my_dir */
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
These members are just copies of parts of DYNAMIC_ARRAY structure,
|
||||||
|
which is allocated right after the end of MY_DIR structure (MEM_ROOT
|
||||||
|
for storing names is also resides there). We've left them here because
|
||||||
|
we don't want to change code that uses my_dir.
|
||||||
|
*/
|
||||||
|
struct fileinfo *dir_entry;
|
||||||
|
uint number_off_files;
|
||||||
|
} MY_DIR;
|
||||||
|
|
||||||
|
extern MY_DIR *my_dir(const char *path,myf MyFlags);
|
||||||
|
extern void my_dirend(MY_DIR *buffer);
|
||||||
|
extern MY_STAT *my_stat(const char *path, MY_STAT *stat_area, myf my_flags);
|
||||||
|
extern int my_fstat(int filenr, MY_STAT *stat_area, myf MyFlags);
|
||||||
|
|
||||||
|
#endif /* MY_DIR_H */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
37
MySQL/my_div.c
Normal file
37
MySQL/my_div.c
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/* Copyright (C) 2000 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
#include "mysys_priv.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
Get filename of file
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
my_filename()
|
||||||
|
fd File descriptor
|
||||||
|
*/
|
||||||
|
|
||||||
|
char * my_filename(File fd)
|
||||||
|
{
|
||||||
|
DBUG_ENTER("my_filename");
|
||||||
|
if ((uint) fd >= (uint) my_file_limit)
|
||||||
|
DBUG_RETURN((char*) "UNKNOWN");
|
||||||
|
if (fd >= 0 && my_file_info[fd].type != UNOPEN)
|
||||||
|
{
|
||||||
|
DBUG_RETURN(my_file_info[fd].name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
DBUG_RETURN((char*) "UNOPENED"); /* Debug message */
|
||||||
|
}
|
267
MySQL/my_error.c
Normal file
267
MySQL/my_error.c
Normal file
@ -0,0 +1,267 @@
|
|||||||
|
/* Copyright (C) 2000 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
#include "mysys_priv.h"
|
||||||
|
#include "mysys_err.h"
|
||||||
|
#include <m_string.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <m_ctype.h>
|
||||||
|
|
||||||
|
/* Max length of a error message. Should be kept in sync with MYSQL_ERRMSG_SIZE. */
|
||||||
|
#define ERRMSGSIZE (512)
|
||||||
|
|
||||||
|
|
||||||
|
/* Define some external variables for error handling */
|
||||||
|
|
||||||
|
/*
|
||||||
|
WARNING!
|
||||||
|
my_error family functions have to be used according following rules:
|
||||||
|
- if message have not parameters use my_message(ER_CODE, ER(ER_CODE), MYF(N))
|
||||||
|
- if message registered use my_error(ER_CODE, MYF(N), ...).
|
||||||
|
- With some special text of errror message use:
|
||||||
|
my_printf_error(ER_CODE, format, MYF(N), ...)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Message texts are registered into a linked list of 'my_err_head' structs.
|
||||||
|
Each struct contains (1.) an array of pointers to C character strings with
|
||||||
|
'\0' termination, (2.) the error number for the first message in the array
|
||||||
|
(array index 0) and (3.) the error number for the last message in the array
|
||||||
|
(array index (last - first)).
|
||||||
|
The array may contain gaps with NULL pointers and pointers to empty strings.
|
||||||
|
Both kinds of gaps will be translated to "Unknown error %d.", if my_error()
|
||||||
|
is called with a respective error number.
|
||||||
|
The list of header structs is sorted in increasing order of error numbers.
|
||||||
|
Negative error numbers are allowed. Overlap of error numbers is not allowed.
|
||||||
|
Not registered error numbers will be translated to "Unknown error %d.".
|
||||||
|
*/
|
||||||
|
static struct my_err_head
|
||||||
|
{
|
||||||
|
struct my_err_head *meh_next; /* chain link */
|
||||||
|
const char **meh_errmsgs; /* error messages array */
|
||||||
|
int meh_first; /* error number matching array slot 0 */
|
||||||
|
int meh_last; /* error number matching last slot */
|
||||||
|
} my_errmsgs_globerrs = {NULL, globerrs, EE_ERROR_FIRST, EE_ERROR_LAST};
|
||||||
|
|
||||||
|
static struct my_err_head *my_errmsgs_list= &my_errmsgs_globerrs;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Error message to user
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
my_error()
|
||||||
|
nr Errno
|
||||||
|
MyFlags Flags
|
||||||
|
... variable list
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
What (*error_handler_hook)() returns:
|
||||||
|
0 OK
|
||||||
|
*/
|
||||||
|
|
||||||
|
int my_error(int nr, myf MyFlags, ...)
|
||||||
|
{
|
||||||
|
const char *format;
|
||||||
|
struct my_err_head *meh_p;
|
||||||
|
va_list args;
|
||||||
|
char ebuff[ERRMSGSIZE];
|
||||||
|
DBUG_ENTER("my_error");
|
||||||
|
DBUG_PRINT("my", ("nr: %d MyFlags: %d errno: %d", nr, MyFlags, errno));
|
||||||
|
|
||||||
|
/* Search for the error messages array, which could contain the message. */
|
||||||
|
for (meh_p= my_errmsgs_list; meh_p; meh_p= meh_p->meh_next)
|
||||||
|
if (nr <= meh_p->meh_last)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* get the error message string. Default, if NULL or empty string (""). */
|
||||||
|
if (! (format= (meh_p && (nr >= meh_p->meh_first)) ?
|
||||||
|
meh_p->meh_errmsgs[nr - meh_p->meh_first] : NULL) || ! *format)
|
||||||
|
(void) my_snprintf (ebuff, sizeof(ebuff), "Unknown error %d", nr);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
va_start(args,MyFlags);
|
||||||
|
(void) my_vsnprintf (ebuff, sizeof(ebuff), format, args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
DBUG_RETURN((*error_handler_hook)(nr, ebuff, MyFlags));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Error as printf
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
my_printf_error()
|
||||||
|
error Errno
|
||||||
|
format Format string
|
||||||
|
MyFlags Flags
|
||||||
|
... variable list
|
||||||
|
*/
|
||||||
|
|
||||||
|
int my_printf_error(uint error, const char *format, myf MyFlags, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
char ebuff[ERRMSGSIZE];
|
||||||
|
DBUG_ENTER("my_printf_error");
|
||||||
|
DBUG_PRINT("my", ("nr: %d MyFlags: %d errno: %d Format: %s",
|
||||||
|
error, MyFlags, errno, format));
|
||||||
|
|
||||||
|
va_start(args,MyFlags);
|
||||||
|
(void) my_vsnprintf (ebuff, sizeof(ebuff), format, args);
|
||||||
|
va_end(args);
|
||||||
|
DBUG_RETURN((*error_handler_hook)(error, ebuff, MyFlags));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Give message using error_handler_hook
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
my_message()
|
||||||
|
error Errno
|
||||||
|
str Error message
|
||||||
|
MyFlags Flags
|
||||||
|
*/
|
||||||
|
|
||||||
|
int my_message(uint error, const char *str, register myf MyFlags)
|
||||||
|
{
|
||||||
|
return (*error_handler_hook)(error, str, MyFlags);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Register error messages for use with my_error().
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
my_error_register()
|
||||||
|
errmsgs array of pointers to error messages
|
||||||
|
first error number of first message in the array
|
||||||
|
last error number of last message in the array
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
The pointer array is expected to contain addresses to NUL-terminated
|
||||||
|
C character strings. The array contains (last - first + 1) pointers.
|
||||||
|
NULL pointers and empty strings ("") are allowed. These will be mapped to
|
||||||
|
"Unknown error" when my_error() is called with a matching error number.
|
||||||
|
This function registers the error numbers 'first' to 'last'.
|
||||||
|
No overlapping with previously registered error numbers is allowed.
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
0 OK
|
||||||
|
!= 0 Error
|
||||||
|
*/
|
||||||
|
|
||||||
|
int my_error_register(const char **errmsgs, int first, int last)
|
||||||
|
{
|
||||||
|
struct my_err_head *meh_p;
|
||||||
|
struct my_err_head **search_meh_pp;
|
||||||
|
|
||||||
|
/* Allocate a new header structure. */
|
||||||
|
if (! (meh_p= (struct my_err_head*) my_malloc(sizeof(struct my_err_head),
|
||||||
|
MYF(MY_WME))))
|
||||||
|
return 1;
|
||||||
|
meh_p->meh_errmsgs= errmsgs;
|
||||||
|
meh_p->meh_first= first;
|
||||||
|
meh_p->meh_last= last;
|
||||||
|
|
||||||
|
/* Search for the right position in the list. */
|
||||||
|
for (search_meh_pp= &my_errmsgs_list;
|
||||||
|
*search_meh_pp;
|
||||||
|
search_meh_pp= &(*search_meh_pp)->meh_next)
|
||||||
|
{
|
||||||
|
if ((*search_meh_pp)->meh_last > first)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Error numbers must be unique. No overlapping is allowed. */
|
||||||
|
if (*search_meh_pp && ((*search_meh_pp)->meh_first <= last))
|
||||||
|
{
|
||||||
|
my_free((uchar*)meh_p, MYF(0));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Insert header into the chain. */
|
||||||
|
meh_p->meh_next= *search_meh_pp;
|
||||||
|
*search_meh_pp= meh_p;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Unregister formerly registered error messages.
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
my_error_unregister()
|
||||||
|
first error number of first message
|
||||||
|
last error number of last message
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
This function unregisters the error numbers 'first' to 'last'.
|
||||||
|
These must have been previously registered by my_error_register().
|
||||||
|
'first' and 'last' must exactly match the registration.
|
||||||
|
If a matching registration is present, the header is removed from the
|
||||||
|
list and the pointer to the error messages pointers array is returned.
|
||||||
|
Otherwise, NULL is returned.
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
non-NULL OK, returns address of error messages pointers array.
|
||||||
|
NULL Error, no such number range registered.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const char **my_error_unregister(int first, int last)
|
||||||
|
{
|
||||||
|
struct my_err_head *meh_p;
|
||||||
|
struct my_err_head **search_meh_pp;
|
||||||
|
const char **errmsgs;
|
||||||
|
|
||||||
|
/* Search for the registration in the list. */
|
||||||
|
for (search_meh_pp= &my_errmsgs_list;
|
||||||
|
*search_meh_pp;
|
||||||
|
search_meh_pp= &(*search_meh_pp)->meh_next)
|
||||||
|
{
|
||||||
|
if (((*search_meh_pp)->meh_first == first) &&
|
||||||
|
((*search_meh_pp)->meh_last == last))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (! *search_meh_pp)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* Remove header from the chain. */
|
||||||
|
meh_p= *search_meh_pp;
|
||||||
|
*search_meh_pp= meh_p->meh_next;
|
||||||
|
|
||||||
|
/* Save the return value and free the header. */
|
||||||
|
errmsgs= meh_p->meh_errmsgs;
|
||||||
|
my_free((uchar*) meh_p, MYF(0));
|
||||||
|
|
||||||
|
return errmsgs;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void my_error_unregister_all(void)
|
||||||
|
{
|
||||||
|
struct my_err_head *cursor, *saved_next;
|
||||||
|
|
||||||
|
for (cursor= my_errmsgs_globerrs.meh_next; cursor != NULL; cursor= saved_next)
|
||||||
|
{
|
||||||
|
/* We need this ptr, but we're about to free its container, so save it. */
|
||||||
|
saved_next= cursor->meh_next;
|
||||||
|
|
||||||
|
my_free((uchar*) cursor, MYF(0));
|
||||||
|
}
|
||||||
|
my_errmsgs_globerrs.meh_next= NULL; /* Freed in first iteration above. */
|
||||||
|
|
||||||
|
my_errmsgs_list= &my_errmsgs_globerrs;
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user