1 // Copyright (c) Athena Dev Teams - Licensed under GNU GPL
2 // For more information, see LICENCE in the main folder
4 #include "cbasetypes.h"
11 #include <math.h> // floor()
25 /// Dumps given buffer into file pointed to by a handle.
26 void WriteDump(FILE* fp, const void* buffer, size_t length)
29 char hex[48+1], ascii[16+1];
31 fprintf(fp, "--- 00-01-02-03-04-05-06-07-08-09-0A-0B-0C-0D-0E-0F 0123456789ABCDEF\n");
34 for( i = 0; i < length; i++ )
36 char c = RBUFB(buffer,i);
38 ascii[i%16] = ISCNTRL(c) ? '.' : c;
39 sprintf(hex+(i%16)*3, "%02X ", RBUFB(buffer,i));
43 fprintf(fp, "%03X %s %s\n", (unsigned int)(i/16), hex, ascii);
50 fprintf(fp, "%03X %-48s %-16s\n", (unsigned int)(i/16), hex, ascii);
55 /// Dumps given buffer on the console.
56 void ShowDump(const void* buffer, size_t length)
59 char hex[48+1], ascii[16+1];
61 ShowDebug("--- 00-01-02-03-04-05-06-07-08-09-0A-0B-0C-0D-0E-0F 0123456789ABCDEF\n");
64 for( i = 0; i < length; i++ )
66 char c = RBUFB(buffer,i);
68 ascii[i%16] = ISCNTRL(c) ? '.' : c;
69 sprintf(hex+(i%16)*3, "%02X ", RBUFB(buffer,i));
73 ShowDebug("%03X %s %s\n", i/16, hex, ascii);
80 ShowDebug("%03X %-48s %-16s\n", i/16, hex, ascii);
87 static char* checkpath(char *path, const char *srcpath)
88 { // just make sure the char*path is not const
90 if(NULL!=path && NULL!=srcpath)
103 void findfile(const char *p, const char *pat, void (func)(const char*))
105 WIN32_FIND_DATAA FindFileData;
107 char tmppath[MAX_PATH+1];
109 const char *path = (p ==NULL)? "." : p;
110 const char *pattern = (pat==NULL)? "" : pat;
112 checkpath(tmppath,path);
113 if( PATHSEP != tmppath[strlen(tmppath)-1])
114 strcat(tmppath, "\\*");
116 strcat(tmppath, "*");
118 hFind = FindFirstFileA(tmppath, &FindFileData);
119 if (hFind != INVALID_HANDLE_VALUE)
123 if (strcmp(FindFileData.cFileName, ".") == 0)
125 if (strcmp(FindFileData.cFileName, "..") == 0)
128 sprintf(tmppath,"%s%c%s",path,PATHSEP,FindFileData.cFileName);
130 if (FindFileData.cFileName && strstr(FindFileData.cFileName, pattern)) {
135 if( FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
137 findfile(tmppath, pat, func);
139 }while (FindNextFileA(hFind, &FindFileData) != 0);
146 * Check if the path is a directory or file
147 * @param filepath: Location of file
151 * 3 = File but doesn't exist
153 int check_filepath(const char* filepath)
157 if (Attribute = GetFileAttributes(filepath)) {
158 if ((Attribute&INVALID_FILE_ATTRIBUTES) && GetLastError() == ERROR_FILE_NOT_FOUND) {
161 } else if (Attribute&FILE_ATTRIBUTE_DIRECTORY)
172 #define MAX_DIR_PATH 2048
175 * Check if the path is a directory or file
176 * @param filepath: Location of file
180 * 3 = Neither a file or directory
182 int check_filepath(const char* filepath)
186 if (stat(filepath, &s) == 0) {
187 if (s.st_mode&S_IFDIR)
189 else if (s.st_mode&S_IFREG)
198 static char* checkpath(char *path, const char*srcpath)
199 { // just make sure the char*path is not const
201 if(NULL!=path && NULL!=srcpath)
203 if (*srcpath=='\\') {
214 void findfile(const char *p, const char *pat, void (func)(const char*))
216 DIR* dir; // pointer to the scanned directory.
217 struct dirent* entry; // pointer to one directory entry.
218 struct stat dir_stat; // used by stat().
219 char tmppath[MAX_DIR_PATH+1];
220 char path[MAX_DIR_PATH+1]= ".";
221 const char *pattern = (pat==NULL)? "" : pat;
222 if(p!=NULL) strcpy(path,p);
224 // open the directory for reading
225 dir = opendir( checkpath(path, path) );
227 ShowError("Cannot read directory '%s'\n", path);
231 // scan the directory, traversing each sub-directory
232 // matching the pattern for each file name.
233 while ((entry = readdir(dir))) {
234 // skip the "." and ".." entries.
235 if (strcmp(entry->d_name, ".") == 0)
237 if (strcmp(entry->d_name, "..") == 0)
240 sprintf(tmppath,"%s%c%s",path, PATHSEP, entry->d_name);
242 // check if the pattern matchs.
243 if (entry->d_name && strstr(entry->d_name, pattern)) {
246 // check if it is a directory.
247 if (stat(tmppath, &dir_stat) == -1) {
248 ShowError("stat error %s\n': ", tmppath);
251 // is this a directory?
252 if (S_ISDIR(dir_stat.st_mode)) {
254 findfile(tmppath, pat, func);
262 bool exists(const char* filename)
264 return !access(filename, F_OK);
267 uint8 GetByte(uint32 val, int idx)
271 case 0: return (uint8)( (val & 0x000000FF) );
272 case 1: return (uint8)( (val & 0x0000FF00) >> 0x08 );
273 case 2: return (uint8)( (val & 0x00FF0000) >> 0x10 );
274 case 3: return (uint8)( (val & 0xFF000000) >> 0x18 );
277 ShowDebug("GetByte: invalid index (idx=%d)\n", idx);
283 uint16 GetWord(uint32 val, int idx)
287 case 0: return (uint16)( (val & 0x0000FFFF) );
288 case 1: return (uint16)( (val & 0xFFFF0000) >> 0x10 );
291 ShowDebug("GetWord: invalid index (idx=%d)\n", idx);
296 uint16 MakeWord(uint8 byte0, uint8 byte1)
298 return byte0 | (byte1 << 0x08);
301 uint32 MakeDWord(uint16 word0, uint16 word1)
304 ( (uint32)(word0 ) )|
305 ( (uint32)(word1 << 0x10) );
308 /*************************************
309 * Big-endian compatibility functions *
310 *************************************/
312 // Converts an int16 from current machine order to little-endian
313 int16 MakeShortLE(int16 val)
315 unsigned char buf[2];
316 buf[0] = (unsigned char)( (val & 0x00FF) );
317 buf[1] = (unsigned char)( (val & 0xFF00) >> 0x08 );
318 return *((int16*)buf);
321 // Converts an int32 from current machine order to little-endian
322 int32 MakeLongLE(int32 val)
324 unsigned char buf[4];
325 buf[0] = (unsigned char)( (val & 0x000000FF) );
326 buf[1] = (unsigned char)( (val & 0x0000FF00) >> 0x08 );
327 buf[2] = (unsigned char)( (val & 0x00FF0000) >> 0x10 );
328 buf[3] = (unsigned char)( (val & 0xFF000000) >> 0x18 );
329 return *((int32*)buf);
332 // Reads an uint16 in little-endian from the buffer
333 uint16 GetUShort(const unsigned char* buf)
335 return ( ((uint16)(buf[0])) )
336 |( ((uint16)(buf[1])) << 0x08 );
339 // Reads an uint32 in little-endian from the buffer
340 uint32 GetULong(const unsigned char* buf)
342 return ( ((uint32)(buf[0])) )
343 |( ((uint32)(buf[1])) << 0x08 )
344 |( ((uint32)(buf[2])) << 0x10 )
345 |( ((uint32)(buf[3])) << 0x18 );
348 // Reads an int32 in little-endian from the buffer
349 int32 GetLong(const unsigned char* buf)
351 return (int32)GetULong(buf);
354 // Reads a float (32 bits) from the buffer
355 float GetFloat(const unsigned char* buf)
357 uint32 val = GetULong(buf);
358 return *((float*)(void*)&val);
361 /// calculates the value of A / B, in percent (rounded down)
362 unsigned int get_percentage(const unsigned int A, const unsigned int B)
368 ShowError("get_percentage(): divison by zero! (A=%u,B=%u)\n", A, B);
372 result = 100 * ((double)A / (double)B);
374 if( result > UINT_MAX )
376 ShowError("get_percentage(): result percentage too high! (A=%u,B=%u,result=%g)\n", A, B, result);
380 return (unsigned int)floor(result);
384 * Calculates the Levenshtein distance of two strings.
385 * @author http://en.wikibooks.org/wiki/Algorithm_Implementation/Strings/Levenshtein_distance#C
387 int levenshtein(const char *s1, const char *s2) {
388 unsigned int s1len, s2len, x, y, lastdiag, olddiag, i;
389 unsigned int *column;
392 column = malloc((s1len+1) * sizeof(unsigned int));
393 for (y = 1; y <= s1len; y++)
395 for (x = 1; x <= s2len; x++) {
397 for (y = 1, lastdiag = x-1; y <= s1len; y++) {
399 column[y] = min(min(column[y] + 1, column[y-1] + 1), lastdiag + (s1[y-1] == s2[x-1] ? 0 : 1));