| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658 |
- /*----------------------------------------------------------------------------*\
- =================================
- Y Sever Includes - Misc Functions
- =================================
- Description:
- Misc functions used throughout.
- Legal:
- Version: MPL 1.1
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is the YSI utils include.
-
- The Initial Developer of the Original Code is Alex "Y_Less" Cole.
- Portions created by the Initial Developer are Copyright (C) 2011
- the Initial Developer. All Rights Reserved.
-
- Contributors:
- ZeeX, koolk, JoeBullet/Google63, g_aSlice/Slice
-
- Thanks:
- JoeBullet/Google63 - Handy arbitrary ASM jump code using SCTRL.
- ZeeX - Very productive conversations.
- koolk - IsPlayerinAreaEx code.
- TheAlpha - Danish translation.
- breadfish - German translation.
- Fireburn - Dutch translation.
- yom - French translation.
- 50p - Polish translation.
- Zamaroht - Spanish translation.
- Dracoblue, sintax, mabako, Xtreme, other coders - Producing other modes
- for me to strive to better.
- Pixels^ - Running XScripters where the idea was born.
- Matite - Pestering me to release it and using it.
-
- Very special thanks to:
- Thiadmer - PAWN, whose limits continue to amaze me!
- Kye/Kalcor - SA:MP.
- SA:MP Team past, present and future - SA:MP.
-
- Version:
- 0.1.3
- Changelog:
- 22/12/11:
- Changed "ceildiv" to only evaluate arguments once.
- 05/12/11:
- Added NO_VALUE to test if macros have no value.
- 08/09/10:
- Added strcpy and StripNL.
- 08/08/10:
- Scrapped almost everything. Only VERY usefult things go in now.
- Functions:
- Stock:
- StripNL - Strips the newline characters from the end of a string.
- Inline:
- iseven - Checks if a number is even.
- isodd - Checks if a number is odd.
- isnull - Checks if a string is NULL ("\1\0").
- strcpy - Copy one string to another.
- Variables:
- Global:
- TRUE - True hack for infinate loops.
- FALSE - False hack for one-time loops.
- NULL - 1 long string for passing via Call(Remote|Local)Function.
- \*----------------------------------------------------------------------------*/
- #include "internal\y_version"
- #include "y_debug"
- #include "y_amx"
- //#tryinclude <sscanf>
- /*// "File,Float," must remain last always.
- #if defined CUSTOM_TAG_TYPES
- #define File,Float, Float,File,CUSTOM_TAG_TYPES
- #else
- #define File,Float, Float,File
- #endif*/
- // Add new tags to the START of this list.
- #include "internal\y_globaltags"
- // VERY VERY VERY IMPORTANT!!! y_inline uses "130" instead of "YSI_MAX_STRING"
- // for two lines (one is "520" for "130 * 4").
- #define YSI_MAX_STRING (130)
- #define FUNCTION_LENGTH (32)
- #define NO_VALUE(%0) ((2*%0-1+1)==-1)
- #if !defined TRUE
- new stock
- bool:TRUE = true;
- #endif
- #if !defined FALSE
- new stock
- bool:FALSE = false;
- #endif
- #if !defined NULL
- new stock
- NULL[2] = {1, 0};
- #endif
- // Define "volatile" as nothing.
- #if !defined volatile
- #define volatile
- #endif
- #define YSIM_MASTER #M
- #define YSIM_RETURN #R
- #define YSIM_CALLER #C
- #define YSIM_TEXT_D #T
- #define YSIM_TEXT_L #L
- #define YSIM_TEXT_S #Y
- #define YSIM_TEXT_P #Z
- #define YSIM_ORDERS #O
- #define YSIM_HFIRST #H
- #define YSIM_OPDRET #D
- #define YSIM_TXTFND #X
- #define YSIM_TXTIND #I
- #define YSIM_TXTLEN #E
- #define YSIM_LOG_IN #U
- #if !defined YSIM_STRING
- #define YSIM_STRING (42)
- #endif
- #define FLOAT_INFINITY (Float:0x7F800000)
- #define FLOAT_NEG_INFINITY (Float:0xFF800000)
- #define FLOAT_NEGATIVE_INFINITY (Float:0xFF800000)
- #define FLOAT_NAN (Float:0x7FFFFFFF)
- #define FLOAT_NOT_A_NUMBER (Float:0x7FFFFFFF)
- #define FLOAT_QNAN (Float:0x7FFFFFFF)
- #define FLOAT_QUIET_NAN (Float:0x7FFFFFFF)
- #define FLOAT_QUIET_NOT_A_NUMBER (Float:0x7FFFFFFF)
- #define FLOAT_SNAN (Float:0x7FBFFFFF)
- #define FLOAT_SIGNALING_NAN (Float:0x7FBFFFFF)
- #define FLOAT_SIGNALING_NOT_A_NUMBER (Float:0x7FBFFFFF)
- //#pragma unused TRUE, FALSE, NULL
- #define ceildiv(%0,%1) \
- (((%0)-1)/(%1)+1)
- #define floordiv(%0,%1) \
- ((%0)/(%1))
- /*----------------------------------------------------------------------------*\
- Function:
- isnull
- Params:
- str - String to check if is null.
- Return:
- -
- Notes:
- -
- \*----------------------------------------------------------------------------*/
- #if !defined isnull
- #define isnull(%1) \
- ((%1[0] == 0) || (%1[0] == 1 && %1[1] == 0))
- #endif
- /*----------------------------------------------------------------------------*\
- Function:
- isodd
- Params:
- value - Value to check if is odd.
- Return:
- -
- Notes:
- -
- \*----------------------------------------------------------------------------*/
- #define isodd(%1) \
- ((%1) & 1)
- /*----------------------------------------------------------------------------*\
- Function:
- iseven
- Params:
- value - Value to check if is even.
- Return:
- -
- Notes:
- -
- \*----------------------------------------------------------------------------*/
- #define iseven(%1) \
- (!isodd(%1))
- /*----------------------------------------------------------------------------*\
- Function:
- strcpy
- Params:
- dest - Destination string.
- src - Source string.
- len - (Implicit) maximum length of the destination.
- Return:
- -
- Notes:
- -
- \*----------------------------------------------------------------------------*/
- #define strcpy(%0,%1) \
- strcat((%0[0] = '\0', %0), %1)
- // memcpy(%0,%1,0,strlen(%1)*4+4,%2)
- /*----------------------------------------------------------------------------*\
- Function:
- StripNL
- Params:
- str[] - The string to remove the newline characters from
- Return:
- -
- Notes:
- Updated from old versions, should be more efficient
- \*----------------------------------------------------------------------------*/
- stock StripNL(str[])
- {
- P:3("StripNL called: \"%s\"", str);
- new
- i = strlen(str);
- while (i-- && str[i] <= ' ') str[i] = '\0';
- }
- /*----------------------------------------------------------------------------*\
- Function:
- endofline
- Params:
- line[] - String to check.
- pos - Postion to start from.
- Return:
- -
- Notes:
- Checks if the current point in a line is the end of non-whitespace data.
- \*----------------------------------------------------------------------------*/
- stock endofline(line[], pos)
- {
- P:3("endofline called: \"%s\", %i", line, pos);
- if (pos < 0 || pos > strlen(line)) return 0;
- while (line[pos]) if (line[pos++] > ' ') return 0;
- return 1;
- }
- /*----------------------------------------------------------------------------*\
- Function:
- chrfind
- Params:
- needle - The character to find.
- haystack[] - The string to find it in.
- start - The offset to start from.
- Return:
- Fail - -1, Success - pos
- Notes:
- -
- \*----------------------------------------------------------------------------*/
- stock chrfind(needle, haystack[], start = 0)
- {
- P:3("chrfind called: %c, \"%s\", %i", needle, haystack, start);
- if (start < 0)
- {
- start = 0;
- }
- else if (start > strlen(haystack)) return -1;
- while (haystack[start]) if (haystack[start++] == needle) return start - 1;
- return -1;
- }
- //#define chrfind(%0'%1'%2,%3) str
- stock chrfindp(needle, haystack[], start = 0)
- {
- P:3("chrfind called: %c, \"%s\", %i", needle, haystack, start);
- if (start < 0)
- {
- start = 0;
- }
- while (haystack{start}) if (haystack{start++} == needle) return start - 1;
- return -1;
- }
- /*----------------------------------------------------------------------------*\
- Function:
- bernstein
- Params:
- string[] - the string to hash.
- Return:
- the bernstein hash of the input string
- Notes:
- This is a 32bit hash system so is not very secure, however we're only
- using this as a string enumerator to uniquely identify strings easilly
- and allow for a binary search of strings based on the hash of their name.
- crc32, then jenkins were originally used however this is far faster, if a
- little collision prone, but we're checking the strings manually anyway.
- This doesn't matter as it would be done regardless of hash method, so this
- doesn't need to be accounted for. Speed is all that matters with at
- least a bit of non collision (the number of strings we're dealing with,
- this should have none-few collisions).
-
- I modified it slightly from the original code pasted by aru, to code
- closer to the code http://www.burtleburtle.net/bob/hash/doobs.html and
- to work with PAWN (and shaved 0.2µs off the time for one call :D).
-
- Uber reduced version (just for fun):
- b(s[]){new h=-1,i,j;while((j=s[i++]))h=h*33+j;return h;}
-
- Update: Contrary to what I said above this is also used to identify colour
- strings for the updated text system involving file based styling and this
- is not checked for collisions as it's unimportant. But this doesn't affect
- the function at all, I just mentioned it here for "interest".
- \*----------------------------------------------------------------------------*/
- stock bernstein(string[])
- {
- P:3("bernstein called: \"%s\"", string);
- new
- hash = -1,
- i,
- j;
- while ((j = string[i++]))
- {
- hash = hash * 33 + j;
- //printf("Hash stage %d: %d", i - 1, hash);
- }
- return hash;
- }
- /*----------------------------------------------------------------------------*\
- Function:
- ishex
- Params:
- str[] - String to check.
- Return:
- -
- Notes:
- -
- \*----------------------------------------------------------------------------*/
- stock ishex(str[])
- {
- P:3("ishex called: \"%s\"", str);
- new
- i,
- cur;
- if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) i = 2;
- while (str[i])
- {
- cur = str[i++];
- if (!(('0' <= cur <= '9') || ('A' <= cur <= 'F') || ('a' <= cur <= 'f'))) return 0;
- //if ((cur < '0') || ('9' < cur < 'A') || ('F' < cur < 'a') || (cur > 'f')) return 0;
- }
- return 1;
- }
- /*----------------------------------------------------------------------------*\
- Function:
- unpack
- Params:
- str[] - String to unpack
- Return:
- unpacked string
- Notes:
- Mainly used for debugging.
- \*----------------------------------------------------------------------------*/
- stock unpack(const str[])
- {
- P:3("unpack called: \"%s\"", str);
- new
- ret[YSI_MAX_STRING] = {0};
- if (strlen(str) <= YSI_MAX_STRING)
- {
- strunpack(ret, str);
- }
- return ret;
- }
- /*----------------------------------------------------------------------------*\
- Function:
- GetIP
- Params:
- playerid - Player to get IP of.
- Return:
- IP as a 32bit int.
- Notes:
- -
- \*----------------------------------------------------------------------------*/
- stock GetIP(playerid)
- {
- new
- ip[16];
- GetPlayerIp(playerid, ip, sizeof (ip));
- new
- ipv = strval(ip) << 24,
- pos = 0;
- while (pos < 15 && ip[pos++] != '.') {}
- ipv += strval(ip[pos]) << 16;
- while (pos < 15 && ip[pos++] != '.') {}
- ipv += strval(ip[pos]) << 8;
- while (pos < 15 && ip[pos++] != '.') {}
- ipv += strval(ip[pos]);
- return ipv;
- }
- /*----------------------------------------------------------------------------*\
- Function:
- getstring
- Params:
- addr - Address of the string on the heap.
- Return:
- string
- Notes:
- Is passed the result of getarg, which will be the address of a string (in
- theory) and uses that for DMA to get the string.
- \*----------------------------------------------------------------------------*/
- stock getstring(addr)
- {
- new
- ret[YSI_MAX_STRING];
- va_getstring(ret, addr);
- return ret;
- }
- stock getstringarg(addr)
- {
- new
- ret[YSI_MAX_STRING];
- va_getstring(ret, addr);
- return ret;
- }
- /*----------------------------------------------------------------------------*\
- Function:
- isnumeric
- Params:
- str[] - String to check
- Return:
- -
- Notes:
- Checks if a given string is numeric.
- \*----------------------------------------------------------------------------*/
- stock isnumeric(str[])
- {
- P:3("isnumeric called: \"%s\"", str);
- new
- ch,
- i;
- while ((ch = str[i++])) if (!('0' <= ch <= '9')) return 0;
- return 1;
- }
- #if !defined _inc_sscanf || 1
- /*------------------------------------------------------------------------*-
- Function:
- hexstr
- Params:
- string[] - String to convert to a number.
- Return:
- value of the passed hex string.
- Notes:
- -
- -*------------------------------------------------------------------------*/
-
- stock hexstr(string[])
- {
- new
- ret,
- val,
- i;
- if (string[0] == '0' && string[1] | 0x20 == 'x') i = 2;
- while (string[i])
- {
- ret <<= 4;
- val = string[i++] - '0';
- if (val > 0x09) val -= 0x07;
- if (val > 0x0F) val -= 0x20;
- if (val < 0x01) continue;
- if (val < 0x10) ret += val;
- }
- return ret;
- }
-
- /*------------------------------------------------------------------------*-
- Function:
- boolstr
- Params:
- string[] - String to try convert to a boolean.
- Return:
- bool: passed boolean.
- Notes:
- This can take a number of ways of representing booleans - 0, false and
- nothing there. Anything not one of those things (false is not case
- sensitive) is assumed true.
- -*------------------------------------------------------------------------*/
-
- stock bool:boolstr(string[])
- {
- if (!string[0] || string[0] == '0' || !strcmp(string, "false", true)) return false;
- return true;
- }
-
- /*------------------------------------------------------------------------*-
- Function:
- binstr
- Params:
- string[] - String to try convert to a boolean.
- Return:
- bool: passed boolean.
- Notes:
- This takes a value in 0110101 (boolean) format and returns it as a
- regular value.
- -*------------------------------------------------------------------------*/
-
- stock binstr(string[])
- {
- new
- pos = 0;
- switch (string[0])
- {
- case '0':
- {
- if (string[1] | 0x20 == 'b')
- {
- pos = 2;
- }
- }
- case '1':
- {
- }
- default:
- {
- return 0;
- }
- }
- new
- value = 0;
- for ( ; ; )
- {
- switch (string[pos++])
- {
- case '0':
- {
- value <<= 1;
- }
- case '1':
- {
- value = (value << 1) | 1;
- }
- default:
- {
- break;
- }
- }
- }
- return value;
- }
- #endif
- stock memset(dest[], size = sizeof (dest), val = 0, blocksize = 8)
- {
- new
- i;
- if (size < 0 || blocksize < 0)
- {
- return 0;
- }
- if (size <= blocksize)
- {
- while (i != size)
- {
- dest[i++] = val;
- }
- }
- else
- {
- //printf("%d %d %d", i, blocksize, size);
- // Set up the initial set area.
- while (i != blocksize)
- {
- dest[i++] = val;
- }
- //printf("%d %d %d", i, blocksize, size);
- size -= blocksize;
- // Copy this blank area over the rest of the array.
- while (i < size)
- {
- memcpy(dest[i], dest, 0, blocksize * 4, blocksize);
- i += blocksize;
- }
- //printf("%d %d %d", i, blocksize, size);
- size += blocksize;
- // Do any small remaining bits.
- while (i != size)
- {
- dest[i++] = val;
- }
- //printf("%d %d %d", i, blocksize, size);
- }
- return 1;
- }
- #if !defined ReturnPlayerName
- stock ReturnPlayerName(playerid)
- {
- new
- str[MAX_PLAYER_NAME];
- GetPlayerName(playerid, str, sizeof (str));
- return str;
- }
- #endif
- stock ftouch(const filename[])
- {
- if (fexist(filename))
- {
- return 0;
- }
- else
- {
- new
- File:f = fopen(filename, io_write);
- if (f)
- {
- fclose(f);
- return 1;
- }
- else
- {
- return -1;
- }
- }
- }
- #include "y_va"
|