root/src/common/utils.c @ 10

Revision 1, 5.6 kB (checked in by jinshiro, 17 years ago)
Line 
1// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
2// For more information, see LICENCE in the main folder
3
4#include "../common/cbasetypes.h"
5#include "../common/mmo.h"
6#include "../common/malloc.h"
7#include "../common/showmsg.h"
8#include "utils.h"
9
10#include <stdio.h>
11#include <stdarg.h>
12#include <stdlib.h>
13#include <string.h>
14#include <math.h> // floor()
15
16#ifdef WIN32
17        #include <windows.h>
18#else
19        #include <unistd.h>
20        #include <dirent.h>
21        #include <sys/stat.h>
22#endif
23
24// generate a hex dump of the first 'length' bytes of 'buffer'
25void dump(FILE* fp, const unsigned char* buffer, int length)
26{
27        int i, j;
28
29        fprintf(fp, "         Hex                                                  ASCII\n");
30        fprintf(fp, "         -----------------------------------------------      ----------------");
31
32        for (i = 0; i < length; i += 16)
33        {
34                fprintf(fp, "\n%p ", &buffer[i]);
35                for (j = i; j < i + 16; ++j)
36                {
37                        if (j < length)
38                                fprintf(fp, "%02hX ", buffer[j]);
39                        else
40                                fprintf(fp, "   ");
41                }
42
43                fprintf(fp, "  |  ");
44
45                for (j = i; j < i + 16; ++j)
46                {
47                        if (j < length) {
48                                if (buffer[j] > 31 && buffer[j] < 127)
49                                        fprintf(fp, "%c", buffer[j]);
50                                else
51                                        fprintf(fp, ".");
52                        } else
53                                fprintf(fp, " ");
54                }
55        }
56        fprintf(fp, "\n");
57}
58
59
60#ifdef WIN32
61
62static char* checkpath(char *path, const char *srcpath)
63{       // just make sure the char*path is not const
64        char *p=path;
65        if(NULL!=path && NULL!=srcpath)
66        while(*srcpath) {
67                if (*srcpath=='/') {
68                        *p++ = '\\';
69                        srcpath++;
70                }
71                else
72                        *p++ = *srcpath++;
73        }
74        *p = *srcpath; //EOS
75        return path;
76}
77
78void findfile(const char *p, const char *pat, void (func)(const char*))
79{       
80        WIN32_FIND_DATA FindFileData;
81        HANDLE hFind;
82        char tmppath[MAX_PATH+1];
83       
84        const char *path    = (==NULL)? "." : p;
85        const char *pattern = (pat==NULL)? "" : pat;
86       
87        checkpath(tmppath,path);
88        if( PATHSEP != tmppath[strlen(tmppath)-1])
89                strcat(tmppath, "\\*");
90        else
91                strcat(tmppath, "*");
92       
93        hFind = FindFirstFile(tmppath, &FindFileData);
94        if (hFind != INVALID_HANDLE_VALUE)
95        {
96                do
97                {
98                        if (strcmp(FindFileData.cFileName, ".") == 0)
99                                continue;
100                        if (strcmp(FindFileData.cFileName, "..") == 0)
101                                continue;
102
103                        sprintf(tmppath,"%s%c%s",path,PATHSEP,FindFileData.cFileName);
104
105                        if (FindFileData.cFileName && strstr(FindFileData.cFileName, pattern)) {
106                                func( tmppath );
107                        }
108
109
110                        if( FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
111                        {
112                                findfile(tmppath, pat, func);
113                        }
114                }while (FindNextFile(hFind, &FindFileData) != 0);
115                FindClose(hFind);
116        }
117        return;
118}
119#else
120
121#define MAX_DIR_PATH 2048
122
123static char* checkpath(char *path, const char*srcpath)
124{       // just make sure the char*path is not const
125        char *p=path;
126        if(NULL!=path && NULL!=srcpath)
127        while(*srcpath) {
128                if (*srcpath=='\\') {
129                        *p++ = '/';
130                        srcpath++;
131                }
132                else
133                        *p++ = *srcpath++;
134        }
135        *p = *srcpath; //EOS
136        return path;
137}
138
139void findfile(const char *p, const char *pat, void (func)(const char*))
140{       
141        DIR* dir;                                       // pointer to the scanned directory.
142        struct dirent* entry;           // pointer to one directory entry.
143        struct stat dir_stat;       // used by stat().
144        char tmppath[MAX_DIR_PATH+1];
145        char path[MAX_DIR_PATH+1]= ".";
146        const char *pattern = (pat==NULL)? "" : pat;
147        if(p!=NULL) strcpy(path,p);
148
149        // open the directory for reading
150        dir = opendir( checkpath(path, path) );
151        if (!dir) {
152                ShowError("Cannot read directory '%s'\n", path);
153                return;
154        }
155
156        // scan the directory, traversing each sub-directory
157        // matching the pattern for each file name.
158        while ((entry = readdir(dir))) {
159                // skip the "." and ".." entries.
160                if (strcmp(entry->d_name, ".") == 0)
161                        continue;
162                if (strcmp(entry->d_name, "..") == 0)
163                        continue;
164
165                sprintf(tmppath,"%s%c%s",path, PATHSEP, entry->d_name);
166
167                // check if the pattern matchs.
168                if (entry->d_name && strstr(entry->d_name, pattern)) {
169                        func( tmppath );
170                }
171                // check if it is a directory.
172                if (stat(tmppath, &dir_stat) == -1) {
173                        ShowError("stat error %s\n': ", tmppath);
174                        continue;
175                }
176                // is this a directory?
177                if (S_ISDIR(dir_stat.st_mode)) {
178                        // decent recursivly
179                        findfile(tmppath, pat, func);
180                }
181        }//end while
182}
183#endif
184
185uint8 GetByte(uint32 val, int idx)
186{
187        switch( idx )
188        {
189        case 0: return (uint8)( (val & 0x000000FF)         );
190        case 1: return (uint8)( (val & 0x0000FF00) >> 0x08 );
191        case 2: return (uint8)( (val & 0x00FF0000) >> 0x10 );
192        case 3: return (uint8)( (val & 0xFF000000) >> 0x18 );
193        default:
194#if defined(DEBUG)
195                ShowDebug("GetByte: invalid index (idx=%d)\n", idx);
196#endif
197                return 0;
198        }
199}
200
201uint16 GetWord(uint32 val, int idx)
202{
203        switch( idx )
204        {
205        case 0: return (uint16)( (val & 0x0000FFFF)         );
206        case 1: return (uint16)( (val & 0xFFFF0000) >> 0x10 );
207        default:
208#if defined(DEBUG)
209                ShowDebug("GetWord: invalid index (idx=%d)\n", idx);
210#endif
211                return 0;
212        }
213}
214uint16 MakeWord(uint8 byte0, uint8 byte1)
215{
216        return byte0 | (byte1 << 0x08);
217}
218
219uint32 MakeDWord(uint16 word0, uint16 word1)
220{
221        return
222                ( (uint32)(word0        ) )|
223                ( (uint32)(word1 << 0x10) );
224}
225
226
227/// calculates the value of A / B, in percent (rounded down)
228unsigned int get_percentage(const unsigned int A, const unsigned int B)
229{
230        double result;
231
232        if( B == 0 )
233        {
234                ShowError("get_percentage(): divison by zero! (A=%u,B=%u)\n", A, B);
235                return -1;
236        }
237
238        result = 100 * ((double)A / (double)B);
239
240        if( result > UINT_MAX )
241        {
242                ShowError("get_percentage(): result percentage too high! (A=%u,B=%u,result=%g)\n", A, B, result);
243                return UINT_MAX;
244        }
245
246        return (unsigned int)floor(result);
247}
Note: See TracBrowser for help on using the browser.