static void windows_add(Windows *wins, HWND hwnd) { if(wins->count >= sb_count(wins->windows)) { sb_push(wins->windows, hwnd); } else { wins->windows[wins->count] = hwnd; } wins->count++; }
int main(int arg, char **argv) { int i; int *arr = NULL; for (i=0; i < 1000000; ++i) sb_push(arr, i); assert(sb_count(arr) == 1000000); for (i=0; i < 1000000; ++i) assert(arr[i] == i); sb_free(arr); arr = NULL; for (i=0; i < 1000; ++i) sb_add(arr, 1000); assert(sb_count(arr) == 1000000); return 0; }
static void *stb__sbgrowf(void *arr, int increment, int itemsize) { int dbl_cur = arr ? 2*stb__sbm(arr) : 0; int min_needed = sb_count(arr) + increment; int m = dbl_cur > min_needed ? dbl_cur : min_needed; int *p = realloc(arr ? stb__sbraw(arr) : 0, itemsize * m + sizeof(int)*2); if(p) { if(!arr) { p[1] = 0; } p[0] = m; return p+2; } else { exit(1); return (void *)(2*sizeof(int)); } }
static const char* poly_fill_stateful(const vec2d* poly, int32_t poly_len, const vec2d* expected, int32_t expected_len, int32_t batch_size, const char* name) { fill_poly_state state; fill_poly_state_init(&state, poly, poly_len); int32_t total_batches = (int32_t)ceil((double)expected_len / (double)batch_size); vec2d* result = NULL; for (int32_t i = 0; i < total_batches - 1; i++) { vec2d* filled = fill_poly_advance(&state, batch_size); for (int32_t j = 0; j < sb_count(filled); j++) { sb_push(result, filled[j]); } sb_free(filled); } while (!state.finished) { vec2d* filled = fill_poly_advance(&state, batch_size); for (int32_t j = 0; j < sb_count(filled); j++) { sb_push(result, filled[j]); } sb_free(filled); } qsort(result, sb_count(result), sizeof(vec2d), line_cmp); if (sb_count(result) != expected_len) { printf("%d fills, expected %d\n", sb_count(result), expected_len); print_coords(result, sb_count(result)); return name; } for (int32_t i = 0; i < expected_len; i++) { if (expected[i].x != result[i].x || expected[i].y != result[i].y) { printf("mismatch at index %d. expected: (%.1f, %.1f), got (%.1f, %.1f)\n", i, expected[i].x, expected[i].y, result[i].x, result[i].y); print_coords(result, expected_len); return name; } } return NULL; }
static void *stb__sbgrowf(void *arr, unsigned increment, unsigned itemsize) { unsigned dbl_cur = arr ? 2*stb__sbm(arr) : 0; unsigned min_needed = sb_count(arr) + increment; unsigned m = dbl_cur > min_needed ? dbl_cur : min_needed; unsigned *p; if (arr) { p = HeapReAlloc(GetProcessHeap(), 0, stb__sbraw(arr), itemsize*m + sizeof(unsigned)*2); } else { p = HeapAlloc(GetProcessHeap(), 0, itemsize*m + sizeof(unsigned)*2); } if (p) { if (!arr) { p[1] = 0; } p[0] = m; return p+2; } else { ExitProcess(1); return (void *)(2*sizeof(unsigned)); } }
static bool Expand(const char* filename, int* line, FILE* f, char** pBuf, int end, Dict* env, Array* arr, int arrIndex) { char* buf = *pBuf; while(true) { int c = getc(f); if (c == end) { break; } if(c == '\n') ++*line; if(c == '[') { c = getc(f); if(c == '[') { sb_push(buf, '['); continue; } char var[VAR_SIZE]; const Tiny_Value* val = ReadVar(filename, line, f, env, arr, arrIndex, c, var); c = getc(f); if(c != ']') { ERROR("Expected ']' after %s.\n", var); } c = getc(f); if(c != '{') { ERROR("Expected '{' after ']'.\n"); } c = getc(f); long epos = ftell(f); int nest = 1; while(c != EOF && nest != 0) { if(c == '\n') ++*line; if (c == '{') ++nest; if (c == '}') --nest; c = getc(f); } if (c == EOF) { ERROR("Unexpected EOF.\n"); } long pos = ftell(f); if(!val || Tiny_GetProp(*val) != &ArrayProp) { ERROR("Attempted to expand '[%s]' but %s is not an array.\n", var, var); } else { Array* a = Tiny_ToAddr(*val); *pBuf = buf; for(int i = 0; i < a->length; ++i) { fseek(f, epos, SEEK_SET); Expand(filename, line, f, pBuf, '}', env, a, i); } buf = *pBuf; fseek(f, pos, SEEK_SET); } } else if(c == '?') { c = getc(f); if(c == '?') { sb_push(buf, '?'); continue; } char var[VAR_SIZE]; const Tiny_Value* val = ReadVar(filename, line, f, env, arr, arrIndex, c, var); c = getc(f); if(c != '{') { ERROR("Expected '{' after %s.\n", var); } c = getc(f); long tp = ftell(f); int nest = 1; while(c != EOF && nest != 0) { if(c == '\n') ++*line; if (c == '{') ++nest; if (c == '}') --nest; c = getc(f); } if (c == EOF) { ERROR("Unexpected EOF.\n"); } if(c != '{') { ERROR("Expected '{' after '}' in '?%s' clause.\n", var); } c = getc(f); long fp = ftell(f); nest = 1; while(c != EOF && nest != 0) { if(c == '\n') ++*line; if (c == '{') ++nest; if (c == '}') --nest; c = getc(f); } if (c == EOF) { ERROR("Unexpected EOF.\n"); } long pos = ftell(f); if(!val || !Tiny_ToBool(*val)) { fseek(f, fp, SEEK_SET); } else { fseek(f, tp, SEEK_SET); } *pBuf = buf; Expand(filename, line, f, pBuf, '}', env, NULL, -1); buf = *pBuf; fseek(f, pos, SEEK_SET); } else if(c == '$') { c = getc(f); if(c == '$') { sb_push(buf, c); continue; } char var[VAR_SIZE]; const Tiny_Value* val = ReadVar(filename, line, f, env, arr, arrIndex, c, var); if(!val) { ERROR("Var '%s' doesn't exist in env.\n", var); } switch(val->type) { case TINY_VAL_BOOL: { AppendStr(&buf, val->boolean ? "true" : "false"); } break; case TINY_VAL_INT: { char s[32]; sprintf(s, "%i", val->i); AppendStr(&buf, s); } break; case TINY_VAL_FLOAT: { char s[32]; sprintf(s, "%g", val->f); AppendStr(&buf, s); } break; case TINY_VAL_STRING: case TINY_VAL_CONST_STRING: { AppendStr(&buf, Tiny_ToString(*val)); } break; case TINY_VAL_NATIVE: { if(Tiny_GetProp(*val) != &BufProp) { goto defaultCase; } char* b = *(char**)Tiny_ToAddr(*val); for(int i = 0; i < sb_count(b); ++i) { sb_push(buf, b[i]); } } break; defaultCase: default: { ERROR("Attempted to expand unsupported value at '$%s'.\n", var); } break; } } else { sb_push(buf, c); } } *pBuf = buf; return true; error: *pBuf = buf; return false; }
// Returns the number of bytes read from buf or REQUEST_ERROR int ParseRequest(RequestParser* p, Request* r, const char* buf, int len) { if(p->state == REQUEST_STATE_FIRST_LINE) { int n = sscanf(buf, "%" X(REQUEST_METHOD_SIZE) "s %" X(REQUEST_TARGET_SIZE) "s %" X(REQUEST_VERSION_SIZE) "s", r->method, r->target, r->version); if(n != 3) { fprintf(stderr, "Failed to parse request start line.\n"); return REQUEST_ERROR; } const char* lineEnd = strchr(buf, '\n'); if(!lineEnd) { fprintf(stderr, "Missing end of line in first line of request.\n"); return REQUEST_ERROR; } n = lineEnd - buf + 1; buf = lineEnd + 1; if(n == len) { p->state = REQUEST_STATE_DONE; } else { p->nameLen = 0; p->bodyBytesLeft = 0; p->state = REQUEST_STATE_HEADER_NAME; } return n; } if(p->state == REQUEST_STATE_HEADER_NAME) { int i = 0; while(i < len) { if(buf[i] == '\r') { if(p->nameLen > 0) { fprintf(stderr, "Invalid request: carriage return in request header name.\n"); return REQUEST_ERROR; } else { i += 1; continue; } } if(buf[i] == '\n') { if(p->nameLen > 0) { fprintf(stderr, "Invalid request: newline in request header name.\n"); return REQUEST_ERROR; } i += 1; if(p->bodyBytesLeft > 0) { p->state = REQUEST_STATE_BODY; } else { p->state = REQUEST_STATE_DONE; } break; } if(buf[i] == ':') { p->state = REQUEST_STATE_HEADER_VALUE; p->curHeader.name[p->nameLen] = 0; p->curHeader.value = NULL; i += 1; // We skip the ':' so + 1 break; } if(p->nameLen >= REQUEST_HEADER_NAME_SIZE - 1) { fprintf(stderr, "Header name in request was too long.\n"); return REQUEST_ERROR; } p->curHeader.name[p->nameLen++] = buf[i++]; } return i; } if(p->state == REQUEST_STATE_HEADER_VALUE) { int i = 0; while(i < len) { if(buf[i] == '\r') { i += 1; continue; } if(buf[i] == '\n') { if(strcmp(p->curHeader.name, "Content-Length") == 0) { sb_push(p->curHeader.value, 0); p->bodyBytesLeft = atoi(p->curHeader.value); } p->state = REQUEST_STATE_HEADER_NAME; p->nameLen = 0; sb_push(p->curHeader.value, 0); sb_push(r->headers, p->curHeader); i += 1; break; } if (sb_count(p->curHeader.value) == 0 && isspace(buf[i])) { i += 1; continue; } sb_push(p->curHeader.value, buf[i]); i += 1; } return i; } if(p->state == REQUEST_STATE_BODY) { int i = 0; while(i < len) { if(p->bodyBytesLeft == 0) { break; } sb_push(r->body, buf[i]); p->bodyBytesLeft -= 1; i += 1; } if(p->bodyBytesLeft == 0) { sb_push(r->body, 0); p->state = REQUEST_STATE_DONE; } return i; } assert(0); return REQUEST_ERROR; }
int main(int argc, char** argv) { signal(SIGINT, IntHandler); Server serv; // Initialize the server InitConfig(&serv.conf, argv[1], argc, argv); if(!serv.conf.name) { fprintf(stderr, "Script doesn't specify a server name.\n"); return 1; } if(!serv.conf.port) { fprintf(stderr, "Script doesn't specify a port.\n"); return 1; } printf("Successfully configured server.\n" "Name: %s\n" "Port: %s\n" "Num Threads: %d\n" "Cycles Per Loop: %d\n" "Num Routes: %d\n", serv.conf.name, serv.conf.port, serv.conf.numThreads, serv.conf.cyclesPerLoop, sb_count(serv.conf.routes)); InitList(&serv.clientQueue, sizeof(Sock)); InitList(&serv.requestQueue, sizeof(ClientRequest)); cnd_init(&serv.updateLoop); cnd_init(&serv.newConn); // The loop thread is responsible for initializing LoopData thrd_t loopThread, connThread; thrd_create(&loopThread, MainLoop, &serv); thrd_create(&connThread, ConnLoop, &serv); // Initialize winsock and listen for clients WSADATA wsaData; SOCKET listenSocket; int iResult = WSAStartup(MAKEWORD(2,2), &wsaData); if(iResult != 0) { fprintf(stderr, "WSAStartup failed: %d\n", iResult); return 1; } struct addrinfo hints; ZeroMemory(&hints, sizeof(hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; hints.ai_flags = AI_PASSIVE; struct addrinfo* result; iResult = getaddrinfo(NULL, serv.conf.port, &hints, &result); if(iResult != 0) { fprintf(stderr, "getaddrinfo failed: %d\n", iResult); WSACleanup(); return 1; } listenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol); if(listenSocket == INVALID_SOCKET) { fprintf(stderr, "Error at socket(): %d\n", WSAGetLastError()); freeaddrinfo(result); WSACleanup(); return 1; } freeaddrinfo(result); iResult = bind(listenSocket, result->ai_addr, (int)result->ai_addrlen); if(iResult == SOCKET_ERROR) { fprintf(stderr, "bind failed with error: %d\n", WSAGetLastError()); closesocket(listenSocket); WSACleanup(); return 1; } if(listen(listenSocket, SOMAXCONN) == SOCKET_ERROR) { fprintf(stderr, "listen failed with error: %d\n", WSAGetLastError()); closesocket(listenSocket); WSACleanup(); return 1; } while (KeepRunning) { SOCKET clientSocket = accept(listenSocket, NULL, NULL); if (clientSocket == INVALID_SOCKET) { fprintf(stderr, "accept failed: %d\n", WSAGetLastError()); continue; } int iMode = 1; if (ioctlsocket(clientSocket, FIONBIO, &iMode) == SOCKET_ERROR) { fprintf(stderr, "ioctlsocket failed: %d\n", WSAGetLastError()); continue; } Sock sock; InitSock(&sock, (void*)clientSocket); ListPushBack(&serv.clientQueue, &sock); cnd_signal(&serv.newConn); } WSACleanup(); thrd_join(&connThread, NULL); thrd_join(&loopThread, NULL); cnd_destroy(&serv.newConn); cnd_destroy(&serv.updateLoop); DestroyList(&serv.requestQueue); DestroyList(&serv.clientQueue); DestroyConfig(&serv.conf); return 0; }