/* parse an int */ int cmdline_parse_num(cmdline_parse_token_hdr_t *tk, const char *srcbuf, void *res, unsigned ressize) { struct cmdline_token_num_data nd; enum num_parse_state_t st = START; const char * buf; char c; uint64_t res1 = 0; if (!tk) return -1; if (!srcbuf || !*srcbuf) return -1; buf = srcbuf; c = *buf; memcpy(&nd, &((struct cmdline_token_num *)tk)->num_data, sizeof(nd)); /* check that we have enough room in res */ if (res) { if (check_res_size(&nd, ressize) < 0) return -1; } while ( st != ERROR && c && ! cmdline_isendoftoken(c) ) { debug_printf("%c %x -> ", c, c); switch (st) { case START: if (c == '-') { st = DEC_NEG; } else if (c == '0') { st = ZERO_OK; } else if (c >= '1' && c <= '9') { if (add_to_res(c - '0', &res1, 10) < 0) st = ERROR; else st = DEC_POS_OK; } else { st = ERROR; } break; case ZERO_OK: if (c == 'x') { st = HEX; } else if (c == 'b') { st = BIN; } else if (c >= '0' && c <= '7') { if (add_to_res(c - '0', &res1, 10) < 0) st = ERROR; else st = OCTAL_OK; } else { st = ERROR; } break; case DEC_NEG: if (c >= '0' && c <= '9') { if (add_to_res(c - '0', &res1, 10) < 0) st = ERROR; else st = DEC_NEG_OK; } else { st = ERROR; } break; case DEC_NEG_OK: if (c >= '0' && c <= '9') { if (add_to_res(c - '0', &res1, 10) < 0) st = ERROR; } else { st = ERROR; } break; case DEC_POS_OK: if (c >= '0' && c <= '9') { if (add_to_res(c - '0', &res1, 10) < 0) st = ERROR; } else { st = ERROR; } break; case HEX: st = HEX_OK; /* no break */ case HEX_OK: if (c >= '0' && c <= '9') { if (add_to_res(c - '0', &res1, 16) < 0) st = ERROR; } else if (c >= 'a' && c <= 'f') { if (add_to_res(c - 'a' + 10, &res1, 16) < 0) st = ERROR; } else if (c >= 'A' && c <= 'F') { if (add_to_res(c - 'A' + 10, &res1, 16) < 0) st = ERROR; } else { st = ERROR; } break; case OCTAL_OK: if (c >= '0' && c <= '7') { if (add_to_res(c - '0', &res1, 8) < 0) st = ERROR; } else { st = ERROR; } break; case BIN: st = BIN_OK; /* no break */ case BIN_OK: if (c >= '0' && c <= '1') { if (add_to_res(c - '0', &res1, 2) < 0) st = ERROR; } else { st = ERROR; } break; default: debug_printf("not impl "); } debug_printf("(%"PRIu64")\n", res1); buf ++; c = *buf; /* token too long */ if (buf-srcbuf > 127) return -1; } switch (st) { case ZERO_OK: case DEC_POS_OK: case HEX_OK: case OCTAL_OK: case BIN_OK: if ( nd.type == INT8 && res1 <= INT8_MAX ) { if (res) *(int8_t *)res = (int8_t) res1; return buf-srcbuf; } else if ( nd.type == INT16 && res1 <= INT16_MAX ) { if (res) *(int16_t *)res = (int16_t) res1; return buf-srcbuf; } else if ( nd.type == INT32 && res1 <= INT32_MAX ) { if (res) *(int32_t *)res = (int32_t) res1; return buf-srcbuf; } else if ( nd.type == INT64 && res1 <= INT64_MAX ) { if (res) *(int64_t *)res = (int64_t) res1; return buf-srcbuf; } else if ( nd.type == UINT8 && res1 <= UINT8_MAX ) { if (res) *(uint8_t *)res = (uint8_t) res1; return buf-srcbuf; } else if (nd.type == UINT16 && res1 <= UINT16_MAX ) { if (res) *(uint16_t *)res = (uint16_t) res1; return buf-srcbuf; } else if ( nd.type == UINT32 && res1 <= UINT32_MAX ) { if (res) *(uint32_t *)res = (uint32_t) res1; return buf-srcbuf; } else if ( nd.type == UINT64 ) { if (res) *(uint64_t *)res = res1; return buf-srcbuf; } else { return -1; } break; case DEC_NEG_OK: if ( nd.type == INT8 && res1 <= INT8_MAX + 1 ) { if (res) *(int8_t *)res = (int8_t) (-res1); return buf-srcbuf; } else if ( nd.type == INT16 && res1 <= (uint16_t)INT16_MAX + 1 ) { if (res) *(int16_t *)res = (int16_t) (-res1); return buf-srcbuf; } else if ( nd.type == INT32 && res1 <= (uint32_t)INT32_MAX + 1 ) { if (res) *(int32_t *)res = (int32_t) (-res1); return buf-srcbuf; } else if ( nd.type == INT64 && res1 <= (uint64_t)INT64_MAX + 1 ) { if (res) *(int64_t *)res = (int64_t) (-res1); return buf-srcbuf; } else { return -1; } break; default: debug_printf("error\n"); return -1; } }
static Vector<Vector<Vector2> > _b2d_decompose(const Vector<Vector2> &p_polygon) { Vector<Vector<Vector2> > res; if (p_polygon.size() < 3) return res; b2Vec2 *polys = memnew_arr(b2Vec2, p_polygon.size()); for (int i = 0; i < p_polygon.size(); i++) polys[i] = b2Vec2(p_polygon[i].x, p_polygon[i].y); b2Polygon *p = new b2Polygon(polys, p_polygon.size()); b2Polygon *decomposed = new b2Polygon[p->nVertices - 2]; //maximum number of polys memdelete_arr(polys); int32 nPolys = DecomposeConvex(p, decomposed, p->nVertices - 2); //int32 extra = 0; for (int32 i = 0; i < nPolys; ++i) { // b2FixtureDef* toAdd = &pdarray[i+extra]; // *toAdd = *prototype; //Hmm, shouldn't have to do all this... b2Polygon curr = decomposed[i]; //TODO ewjordan: move this triangle handling to a better place so that //it happens even if this convenience function is not called. if (curr.nVertices == 3) { //Check here for near-parallel edges, since we can't //handle this in merge routine for (int j = 0; j < 3; ++j) { int32 lower = (j == 0) ? (curr.nVertices - 1) : (j - 1); int32 middle = j; int32 upper = (j == curr.nVertices - 1) ? (0) : (j + 1); float32 dx0 = curr.x[middle] - curr.x[lower]; float32 dy0 = curr.y[middle] - curr.y[lower]; float32 dx1 = curr.x[upper] - curr.x[middle]; float32 dy1 = curr.y[upper] - curr.y[middle]; float32 norm0 = sqrtf(dx0 * dx0 + dy0 * dy0); float32 norm1 = sqrtf(dx1 * dx1 + dy1 * dy1); if (!(norm0 > 0.0f && norm1 > 0.0f)) { //Identical points, don't do anything! goto Skip; } dx0 /= norm0; dy0 /= norm0; dx1 /= norm1; dy1 /= norm1; float32 cross = dx0 * dy1 - dx1 * dy0; float32 dot = dx0 * dx1 + dy0 * dy1; if (fabs(cross) < b2_angularSlop && dot > 0) { //Angle too close, split the triangle across from this point. //This is guaranteed to result in two triangles that satify //the tolerance (one of the angles is 90 degrees) float32 dx2 = curr.x[lower] - curr.x[upper]; float32 dy2 = curr.y[lower] - curr.y[upper]; float32 norm2 = sqrtf(dx2 * dx2 + dy2 * dy2); if (norm2 == 0.0f) { goto Skip; } dx2 /= norm2; dy2 /= norm2; float32 thisArea = curr.GetArea(); float32 thisHeight = 2.0f * thisArea / norm2; float32 buffer2 = dx2; dx2 = dy2; dy2 = -buffer2; //Make two new polygons //printf("dx2: %f, dy2: %f, thisHeight: %f, middle: %d\n",dx2,dy2,thisHeight,middle); float32 newX1[3] = { curr.x[middle] + dx2 * thisHeight, curr.x[lower], curr.x[middle] }; float32 newY1[3] = { curr.y[middle] + dy2 * thisHeight, curr.y[lower], curr.y[middle] }; float32 newX2[3] = { newX1[0], curr.x[middle], curr.x[upper] }; float32 newY2[3] = { newY1[0], curr.y[middle], curr.y[upper] }; b2Polygon p1(newX1, newY1, 3); b2Polygon p2(newX2, newY2, 3); if (p1.IsUsable()) { add_to_res(res, p1); //++extra; } else if (B2_POLYGON_REPORT_ERRORS) { printf("Didn't add unusable polygon. Dumping vertices:\n"); p1.print(); } if (p2.IsUsable()) { add_to_res(res, p2); //p2.AddTo(pdarray[i+extra]); //bd->CreateFixture(toAdd); } else if (B2_POLYGON_REPORT_ERRORS) { printf("Didn't add unusable polygon. Dumping vertices:\n"); p2.print(); } goto Skip; } } } if (decomposed[i].IsUsable()) { add_to_res(res, decomposed[i]); //decomposed[i].AddTo(*toAdd); //bd->CreateFixture((const b2FixtureDef*)toAdd); } else if (B2_POLYGON_REPORT_ERRORS) { printf("Didn't add unusable polygon. Dumping vertices:\n"); decomposed[i].print(); } Skip:; } //delete[] pdarray; delete[] decomposed; delete p; return res; // pdarray; //needs to be deleted after body is created }
/* parse an int or a float */ int8_t parse_num(parse_token_hdr_t * tk, const char * srcbuf, void * res) { struct token_num_data nd; enum num_parse_state_t st = START; const char * buf = srcbuf; char c = *buf; uint32_t res1=0, res2=0, res3=1; memcpy(&nd, &((struct token_num *)tk)->num_data, sizeof(nd)); while ( st != ERROR && c && ! isendoftoken(c) ) { debug_printf("%c %x -> ", c, c); switch (st) { case START: if (c == '-') { st = DEC_NEG; } else if (c == '0') { st = ZERO_OK; } #ifndef CONFIG_MODULE_PARSE_NO_FLOAT else if (c == '.') { st = FLOAT_POS; res1 = 0; } #endif else if (c >= '1' && c <= '9') { if (add_to_res(c - '0', &res1, 10) < 0) st = ERROR; else st = DEC_POS_OK; } else { st = ERROR; } break; case ZERO_OK: if (c == 'x') { st = HEX; } else if (c == 'b') { st = BIN; } #ifndef CONFIG_MODULE_PARSE_NO_FLOAT else if (c == '.') { st = FLOAT_POS; res1 = 0; } #endif else if (c >= '0' && c <= '7') { if (add_to_res(c - '0', &res1, 10) < 0) st = ERROR; else st = OCTAL_OK; } else { st = ERROR; } break; case DEC_NEG: if (c >= '0' && c <= '9') { if (add_to_res(c - '0', &res1, 10) < 0) st = ERROR; else st = DEC_NEG_OK; } #ifndef CONFIG_MODULE_PARSE_NO_FLOAT else if (c == '.') { res1 = 0; st = FLOAT_NEG; } #endif else { st = ERROR; } break; case DEC_NEG_OK: if (c >= '0' && c <= '9') { if (add_to_res(c - '0', &res1, 10) < 0) st = ERROR; } #ifndef CONFIG_MODULE_PARSE_NO_FLOAT else if (c == '.') { st = FLOAT_NEG; } #endif else { st = ERROR; } break; case DEC_POS_OK: if (c >= '0' && c <= '9') { if (add_to_res(c - '0', &res1, 10) < 0) st = ERROR; } #ifndef CONFIG_MODULE_PARSE_NO_FLOAT else if (c == '.') { st = FLOAT_POS; } #endif else { st = ERROR; } break; case HEX: st = HEX_OK; /* no break */ case HEX_OK: if (c >= '0' && c <= '9') { if (add_to_res(c - '0', &res1, 16) < 0) st = ERROR; } else if (c >= 'a' && c <= 'f') { if (add_to_res(c - 'a' + 10, &res1, 16) < 0) st = ERROR; } else if (c >= 'A' && c <= 'F') { if (add_to_res(c - 'A' + 10, &res1, 16) < 0) st = ERROR; } else { st = ERROR; } break; case OCTAL_OK: if (c >= '0' && c <= '7') { if (add_to_res(c - '0', &res1, 8) < 0) st = ERROR; } else { st = ERROR; } break; case BIN: st = BIN_OK; /* no break */ case BIN_OK: if (c >= '0' && c <= '1') { if (add_to_res(c - '0', &res1, 2) < 0) st = ERROR; } else { st = ERROR; } break; #ifndef CONFIG_MODULE_PARSE_NO_FLOAT case FLOAT_POS: if (c >= '0' && c <= '9') { if (add_to_res(c - '0', &res2, 10) < 0) st = ERROR; else st = FLOAT_POS_OK; res3 = 10; } else { st = ERROR; } break; case FLOAT_NEG: if (c >= '0' && c <= '9') { if (add_to_res(c - '0', &res2, 10) < 0) st = ERROR; else st = FLOAT_NEG_OK; res3 = 10; } else { st = ERROR; } break; case FLOAT_POS_OK: if (c >= '0' && c <= '9') { if (add_to_res(c - '0', &res2, 10) < 0) st = ERROR; if (add_to_res(0, &res3, 10) < 0) st = ERROR; } else { st = ERROR; } break; case FLOAT_NEG_OK: if (c >= '0' && c <= '9') { if (add_to_res(c - '0', &res2, 10) < 0) st = ERROR; if (add_to_res(0, &res3, 10) < 0) st = ERROR; } else { st = ERROR; } break; #endif default: debug_printf("not impl "); } /* XXX uint32_t et %d */ debug_printf("(%d) (%d) (%d)\n", res1, res2, res3); buf ++; c = *buf; /* token too long */ if (buf-srcbuf > 127) return -1; } switch (st) { case ZERO_OK: case DEC_POS_OK: case HEX_OK: case OCTAL_OK: case BIN_OK: if ( nd.type == INT8 && res1 <= S08_MAX ) { if (res) *(int8_t *)res = (int8_t) res1; return (buf-srcbuf); } else if ( nd.type == INT16 && res1 <= S16_MAX ) { if (res) *(int16_t *)res = (int16_t) res1; return (buf-srcbuf); } else if ( nd.type == INT32 && res1 <= S32_MAX ) { if (res) *(int32_t *)res = (int32_t) res1; return (buf-srcbuf); } else if ( nd.type == UINT8 && res1 <= U08_MAX ) { if (res) *(uint8_t *)res = (uint8_t) res1; return (buf-srcbuf); } else if (nd.type == UINT16 && res1 <= U16_MAX ) { if (res) *(uint16_t *)res = (uint16_t) res1; return (buf-srcbuf); } else if ( nd.type == UINT32 ) { if (res) *(uint32_t *)res = (uint32_t) res1; return (buf-srcbuf); } #ifndef CONFIG_MODULE_PARSE_NO_FLOAT else if ( nd.type == FLOAT ) { if (res) *(float *)res = (float)res1; return (buf-srcbuf); } #endif else { return -1; } break; case DEC_NEG_OK: if ( nd.type == INT8 && res1 <= S08_MAX + 1 ) { if (res) *(int8_t *)res = - (int8_t) res1; return (buf-srcbuf); } else if ( nd.type == INT16 && res1 <= (uint16_t)S16_MAX + 1 ) { if (res) *(int16_t *)res = - (int16_t) res1; return (buf-srcbuf); } else if ( nd.type == INT32 && res1 <= (uint32_t)S32_MAX + 1 ) { if (res) *(int32_t *)res = - (int32_t) res1; return (buf-srcbuf); } #ifndef CONFIG_MODULE_PARSE_NO_FLOAT else if ( nd.type == FLOAT ) { if (res) *(float *)res = - (float)res1; return (buf-srcbuf); } #endif else { return -1; } break; #ifndef CONFIG_MODULE_PARSE_NO_FLOAT case FLOAT_POS: case FLOAT_POS_OK: if ( nd.type == FLOAT ) { if (res) *(float *)res = (float)res1 + ((float)res2 / (float)res3); return (buf-srcbuf); } else { return -1; } break; case FLOAT_NEG: case FLOAT_NEG_OK: if ( nd.type == FLOAT ) { if (res) *(float *)res = - ((float)res1 + ((float)res2 / (float)res3)); return (buf-srcbuf); } else { return -1; } break; #endif default: debug_printf("error\n"); return -1; } return -1; }