00001
00002
00003
00004
00005
00006
00007
00008
00009
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include <stdlib.h>
00030 #include <stdio.h>
00031 #include <stdarg.h>
00032 #include <string.h>
00033 #include <ctype.h>
00034 #include <errno.h>
00035
00036 #include "stratagus.h"
00037 #include "util.h"
00038
00039 #ifdef USE_WIN32
00040 #define WIN32_LEAN_AND_MEAN
00041 #undef NOUSER
00042 #include <windows.h>
00043 #elif defined(HAVE_X)
00044 #include <X11/Xlib.h>
00045 #include <X11/Xatom.h>
00046 #endif
00047
00048
00049
00050
00051
00052 unsigned SyncRandSeed;
00053
00057 void InitSyncRand(void)
00058 {
00059 SyncRandSeed = 0x87654321;
00060 }
00061
00068 int SyncRand(void)
00069 {
00070 int val;
00071
00072 val = SyncRandSeed >> 16;
00073
00074 SyncRandSeed = SyncRandSeed * (0x12345678 * 4 + 1) + 1;
00075
00076 return val;
00077 }
00078
00084 int SyncRand(int max)
00085 {
00086 return SyncRand() % max;
00087 }
00088
00089
00090
00091
00092
00093
00104 long isqrt(long num)
00105 {
00106 long squaredbit;
00107 long remainder;
00108 long root;
00109
00110 if (num < 1) {
00111 return 0;
00112 }
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123 squaredbit = (long)((((unsigned long)~0L) >> 1) & ~(((unsigned long)~0L) >> 2));
00124
00125
00126 remainder = num;
00127 root = 0;
00128 while (squaredbit > 0) {
00129 if (remainder >= (squaredbit | root)) {
00130 remainder -= (squaredbit | root);
00131 root >>= 1;
00132 root |= squaredbit;
00133 } else {
00134 root >>= 1;
00135 }
00136 squaredbit >>= 2;
00137 }
00138
00139 return root;
00140 }
00141
00142
00143
00144
00145
00146
00147 #if !defined(_MSC_VER) || _MSC_VER < 1400
00148 unsigned int strcpy_s(char *dst, size_t dstsize, const char *src)
00149 {
00150 if (dst == NULL || src == NULL) {
00151 return EINVAL;
00152 }
00153 if (strlen(src) >= dstsize) {
00154 return ERANGE;
00155 }
00156 strcpy(dst, src);
00157 return 0;
00158 }
00159
00160 #ifndef HAVE_STRNLEN
00161 size_t strnlen(const char *str, size_t strsize)
00162 {
00163 size_t len = 0;
00164 while (len < strsize) {
00165 if (*str == '\0') {
00166 break;
00167 }
00168 ++str;
00169 ++len;
00170 }
00171 return len;
00172 }
00173 #endif
00174
00175 unsigned int strncpy_s(char *dst, size_t dstsize, const char *src, size_t count)
00176 {
00177 if (dst == NULL || src == NULL || dstsize == 0) {
00178 return EINVAL;
00179 }
00180
00181 size_t mincount;
00182 if (count == _TRUNCATE) {
00183 mincount = strnlen(src, dstsize);
00184 } else {
00185 mincount = strnlen(src, count);
00186 }
00187 if (mincount >= dstsize) {
00188 if (count != _TRUNCATE) {
00189 dst[0] = '\0';
00190 return EINVAL;
00191 } else {
00192 mincount = dstsize - 1;
00193 }
00194 }
00195 for (size_t i = 0; i < mincount; ++i) {
00196 *dst++ = *src++;
00197 }
00198 *dst = '\0';
00199 return 0;
00200 }
00201
00202 unsigned int strcat_s(char *dst, size_t dstsize, const char *src)
00203 {
00204 if (dst == NULL || src == NULL) {
00205 return EINVAL;
00206 }
00207 char *enddst = dst;
00208 size_t count = dstsize;
00209 while (count > 0 && *enddst != '\0') {
00210 ++enddst;
00211 count--;
00212 }
00213 if (count == 0) {
00214 return EINVAL;
00215 }
00216 if (strlen(src) >= count ) {
00217 return ERANGE;
00218 }
00219 strcpy(enddst, src);
00220 return 0;
00221 }
00222
00223 int sprintf_s(char *dest, size_t destSize, const char *format, ...)
00224 {
00225 va_list args;
00226 int ret;
00227
00228 if (dest == NULL || format == NULL) {
00229 errno = EINVAL;
00230 return -1;
00231 }
00232
00233 va_start(args, format);
00234 ret = vsnprintf(dest, destSize, format, args);
00235 va_end(args);
00236
00237 if (ret < 0 || (size_t)ret >= destSize) {
00238 dest[0] = '\0';
00239 errno = EINVAL;
00240 ret = -1;
00241 }
00242
00243 return ret;
00244 }
00245 #endif
00246
00255 char *strdcat(const char *l, const char *r)
00256 {
00257 int len = strlen(l) + strlen(r) + 1;
00258 char *res = new char[len];
00259
00260 if (res) {
00261 strcpy_s(res, len, l);
00262 strcat_s(res, len, r);
00263 }
00264 return res;
00265 }
00266
00276 char *strdcat3(const char *l, const char *m, const char *r)
00277 {
00278 int len = strlen(l) + strlen(m) + strlen(r) + 1;
00279 char *res = new char[len];
00280
00281 if (res) {
00282 strcpy_s(res, len, l);
00283 strcat_s(res, len, m);
00284 strcat_s(res, len, r);
00285 }
00286 return res;
00287 }
00288
00289 #if !defined(HAVE_STRCASESTR)
00290
00298 char *strcasestr(const char *a, const char *b)
00299 {
00300 int x;
00301
00302 if (!a || !*a || !b || !*b || strlen(a) < strlen(b)) {
00303 return NULL;
00304 }
00305
00306 x = 0;
00307 while (*a) {
00308 if (a[x] && (tolower(a[x]) == tolower(b[x]))) {
00309 ++x;
00310 } else if (b[x]) {
00311 ++a;
00312 x = 0;
00313 } else {
00314 return (char *)a;
00315 }
00316 }
00317
00318 return NULL;
00319 }
00320 #endif // !HAVE_STRCASESTR
00321
00322
00323
00324
00325
00326
00336 #if defined(_MSC_VER)
00337
00338 #include <io.h>
00339 #include <string.h>
00340
00341 int opterr = 1;
00342 int optind = 1;
00343 int optopt;
00344 char *optarg;
00345
00346 static void getopt_err(char *argv0, char *str, char opt)
00347 {
00348 if (opterr) {
00349 char errbuf[2];
00350 char *x;
00351
00352 errbuf[0] = opt;
00353 errbuf[1] = '\n';
00354
00355 while ((x = strchr(argv0, '/'))) {
00356 argv0 = x + 1;
00357 }
00358
00359 write(2, argv0, strlen(argv0));
00360 write(2, str, strlen(str));
00361 write(2, errbuf, 2);
00362 }
00363 }
00364
00365 int getopt(int argc, char *const *argv, const char *opts)
00366 {
00367 static int sp = 1;
00368 register int c;
00369 register const char *cp;
00370
00371 optarg = NULL;
00372
00373 if (sp == 1) {
00374 if (optind >= argc || argv[optind][0] != '-' || argv[optind][1] == '\0') {
00375 return EOF;
00376 } else if (!strcmp(argv[optind], "--")) {
00377 optind++;
00378 return EOF;
00379 }
00380 }
00381 optopt = c = argv[optind][sp];
00382 if (c == ':' || (cp = strchr(opts, c)) == NULL) {
00383 getopt_err(argv[0], ": illegal option -", (char)c);
00384 cp = "xx";
00385 c = '?';
00386 }
00387 if (*++cp == ':') {
00388 if (argv[optind][++sp] != '\0') {
00389 optarg = &argv[optind++][sp];
00390 } else if (++optind < argc) {
00391 optarg = argv[optind++];
00392 } else {
00393 getopt_err(argv[0], ": option requires an argument -", (char)c);
00394 c = (*opts == ':') ? ':' : '?';
00395 }
00396 sp = 1;
00397 } else if (argv[optind][++sp] == '\0') {
00398 optind++;
00399 sp = 1;
00400 }
00401 return c;
00402 }
00403
00404 #endif
00405
00406
00407
00408
00409
00410
00414 int GetClipboard(std::string &str)
00415 {
00416 #if defined(USE_WIN32) || defined(HAVE_X)
00417 int i;
00418 unsigned char *clipboard;
00419 #ifdef USE_WIN32
00420 HGLOBAL handle;
00421 #elif defined(HAVE_X)
00422 Display *display;
00423 Window window;
00424 Atom rettype;
00425 unsigned long nitem;
00426 unsigned long dummy;
00427 int retform;
00428 XEvent event;
00429 #endif
00430
00431 #ifdef USE_WIN32
00432 if (!IsClipboardFormatAvailable(CF_TEXT) || !OpenClipboard(NULL)) {
00433 return -1;
00434 }
00435 handle = GetClipboardData(CF_TEXT);
00436 if (!handle) {
00437 CloseClipboard();
00438 return -1;
00439 }
00440 clipboard = (unsigned char *)GlobalLock(handle);
00441 if (!clipboard) {
00442 CloseClipboard();
00443 return -1;
00444 }
00445 #elif defined(HAVE_X)
00446 if (!(display = XOpenDisplay(NULL))) {
00447 return -1;
00448 }
00449
00450
00451 if (!(window = XCreateSimpleWindow(display,
00452 DefaultRootWindow(display), 0, 0, 1, 1, 0, 0, 0))) {
00453 XCloseDisplay(display);
00454 return -1;
00455 }
00456
00457 XConvertSelection(display, XA_PRIMARY, XA_STRING, XA_STRING,
00458 window, CurrentTime);
00459
00460 XNextEvent(display, &event);
00461
00462 if (event.type != SelectionNotify ||
00463 event.xselection.property != XA_STRING) {
00464 return -1;
00465 }
00466
00467 XGetWindowProperty(display, window, XA_STRING, 0, 1024, False,
00468 XA_STRING, &rettype, &retform, &nitem, &dummy, &clipboard);
00469
00470 XDestroyWindow(display, window);
00471 XCloseDisplay(display);
00472
00473 if (rettype != XA_STRING || retform != 8) {
00474 if (clipboard != NULL) {
00475 XFree(clipboard);
00476 }
00477 clipboard = NULL;
00478 }
00479
00480 if (clipboard == NULL) {
00481 return -1;
00482 }
00483 #endif
00484
00485 for (i = 0; clipboard[i] != '\0'; ++i) {
00486 if (clipboard[i] < 32 || clipboard[i] > 126) {
00487 return -1;
00488 }
00489 }
00490 str = (char *)clipboard;
00491 #ifdef USE_WIN32
00492 GlobalUnlock(handle);
00493 CloseClipboard();
00494 #elif defined(HAVE_X)
00495 if (clipboard != NULL) {
00496 XFree(clipboard);
00497 }
00498 #endif
00499 return 0;
00500 #else
00501 return -1;
00502 #endif
00503 }
00504
00505
00506
00507
00508
00509
00510 int UTF8GetPrev(const std::string &text, int curpos)
00511 {
00512 --curpos;
00513 if (curpos < 0) {
00514 return curpos;
00515 }
00516 while (curpos >= 0) {
00517 if ((text[curpos] & 0xC0) != 0x80) {
00518 return curpos;
00519 }
00520 --curpos;
00521 }
00522 if (curpos < 0) {
00523 fprintf(stderr, "Invalid UTF8.\n");
00524 }
00525 return 0;
00526 }
00527
00528 int UTF8GetNext(const std::string &text, int curpos)
00529 {
00530 if (curpos == (int)text.size()) {
00531 return curpos + 1;
00532 }
00533 char c = text[curpos];
00534 if (!(c & 0x80)) {
00535 return curpos + 1;
00536 }
00537 if ((c & 0xE0) == 0xC0) {
00538 return curpos + 2;
00539 }
00540 if ((c & 0xF0) == 0xE0) {
00541 return curpos + 3;
00542 }
00543 fprintf(stderr, "Invalid UTF8.\n");
00544 return text.size();
00545 }
00546