potion  0.2
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
contrib.c
Go to the documentation of this file.
1 
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <stdint.h>
7 #include "config.h"
8 
9 #define ONEMASK ((size_t)(-1) / 0xFF)
10 
16 size_t
17 potion_cp_strlen_utf8(const char * _s)
18 {
19  const char * s;
20  size_t count = 0;
21  size_t u;
22  unsigned char b;
23 
24  /* Handle any initial misaligned bytes. */
25  for (s = _s; (uintptr_t)(s) & (sizeof(size_t) - 1); s++) {
26  b = *s;
27  if (b == '\0') goto done;
28  count += (b >> 7) & ((~b) >> 6); /* NOT the first byte of a character? */
29  }
30  /* Handle complete blocks, vectorizable */
31  for (; ; s += sizeof(size_t)) {
32  __builtin_prefetch(&s[256], 0, 0);
33  u = *(size_t *)(s); /* Grab 4 or 8 bytes of UTF-8 data. */
34  if ((u - ONEMASK) & (~u) & (ONEMASK * 0x80)) break; /* exit on \0 */
35  /* count bytes which are NOT the first byte of a character.
36  TODO: could use a lookup table */
37  u = ((u & (ONEMASK * 0x80)) >> 7) & ((~u) >> 6);
38  count += (u * ONEMASK) >> ((sizeof(size_t) - 1) * 8);
39  }
40  /* any left-over bytes. */
41  for (; ; s++) {
42  b = *s;
43  if (b == '\0') break;
44  /* Is this byte NOT the first byte of a character? */
45  count += (b >> 7) & ((~b) >> 6); /* NOT the first byte of a character? */
46  }
47 done:
48  return ((s - _s) - count);
49 }
50 
51 #ifdef __MINGW32__
52 #include <windows.h>
53 #include <sys/unistd.h>
54 #define PN_ALIGN(o, x) (((((o) - 1) / (x)) + 1) * (x))
55 
56 void *potion_mmap(size_t length, const char exec)
57 {
58  void *mem = VirtualAlloc(NULL, length, MEM_COMMIT,
59  exec ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE);
60  if (mem == NULL) {
61  /* One last attempt at the highest page.
62  On Windows VirtualAlloc(NULL) sometimes fails due to Illegal System DLL Relocation at a reserved address. */
63  SYSTEM_INFO SystemInfo;
64  size_t high;
65  int psz;
66  GetSystemInfo(&SystemInfo);
67  psz = SystemInfo.dwAllocationGranularity;
68  high = (size_t)SystemInfo.lpMaximumApplicationAddress - PN_ALIGN(length, psz) + 1;
69 #ifdef DEBUG
70  fprintf(stderr, "** potion_mmap(%ld%s) failed, try last page at 0x%x\n", length, exec ? ",exec" : "", high);
71 #endif
72  mem = VirtualAlloc((void*)high, length, MEM_COMMIT,
73  exec ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE);
74  if (mem == NULL) {
75  fprintf(stderr, "** potion_mmap(%ld%s) failed\n", length, exec ? ",exec" : "");
76  }
77  }
78  return mem;
79 }
80 
81 int potion_munmap(void *mem, size_t len)
82 {
83  return VirtualFree(mem, len, MEM_DECOMMIT) != 0 ? 0 : -1;
84 }
85 
86 #else
87 #include <sys/mman.h>
88 
89 void *potion_mmap(size_t length, const char exec)
90 {
91  int prot = exec ? PROT_EXEC : 0;
92  void *mem = mmap(NULL, length, prot|PROT_READ|PROT_WRITE,
93  (MAP_PRIVATE|MAP_ANON), -1, 0);
94  if (mem == MAP_FAILED) {
95  fprintf(stderr, "** potion_mmap(%ld%s) failed\n", (long)length, exec ? ",exec" : "");
96  return NULL;
97  }
98  return mem;
99 }
100 
101 int potion_munmap(void *mem, size_t len)
102 {
103  return munmap(mem, len);
104 }
105 
106 #endif
107 
108 #if POTION_WIN32
109 int vasprintf (char **strp, const char *fmt, va_list ap)
113 {
114  int len = vsnprintf (NULL, 0, fmt, ap) + 1;
115  char *res = (char *)malloc((unsigned int)len);
116  if (res == NULL)
117  return -1;
118  *strp = res;
119  return vsnprintf(res, (unsigned int)len, fmt, ap);
120 }
121 
123 int
124 asprintf (char **string_ptr, const char *format, ...)
125 {
126  va_list arg;
127  int done;
128 
129  va_start (arg, format);
130  done = vasprintf (string_ptr, format, arg);
131  va_end (arg);
132 
133  return done;
134 }
135 #endif
#define PN_ALIGN(o, x)
Definition: potion.h:223
#define ONEMASK
Definition: contrib.c:9
void * potion_mmap(size_t length, const char exec)
Definition: contrib.c:89
int potion_munmap(void *mem, size_t len)
Definition: contrib.c:101
size_t potion_cp_strlen_utf8(const char *_s)
wonderful utf-8 counting trickery by colin percival
Definition: contrib.c:17