/** * Change timetable data of an order. * @param tile Not used. * @param flags Operation to perform. * @param p1 Various bitstuffed elements * - p1 = (bit 0-19) - Vehicle with the orders to change. * - p1 = (bit 20-27) - Order index to modify. * - p1 = (bit 28-29) - Timetable data to change (@see ModifyTimetableFlags) * @param p2 The amount of time to wait. * - p2 = (bit 0-15) - The data to modify as specified by p1 bits 28-29. * 0 to clear times, UINT16_MAX to clear speed limit. * @param text unused * @return the cost of this operation or an error */ CommandCost CmdChangeTimetable(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { VehicleID veh = GB(p1, 0, 20); Vehicle *v = Vehicle::GetIfValid(veh); if (v == NULL || !v->IsPrimaryVehicle()) return CMD_ERROR; CommandCost ret = CheckOwnership(v->owner); if (ret.Failed()) return ret; VehicleOrderID order_number = GB(p1, 20, 8); Order *order = v->GetOrder(order_number); if (order == NULL || order->IsType(OT_IMPLICIT)) return CMD_ERROR; ModifyTimetableFlags mtf = Extract<ModifyTimetableFlags, 28, 2>(p1); if (mtf >= MTF_END) return CMD_ERROR; int wait_time = order->GetWaitTime(); int travel_time = order->GetTravelTime(); int max_speed = order->GetMaxSpeed(); switch (mtf) { case MTF_WAIT_TIME: wait_time = GB(p2, 0, 16); break; case MTF_TRAVEL_TIME: travel_time = GB(p2, 0, 16); break; case MTF_TRAVEL_SPEED: max_speed = GB(p2, 0, 16); if (max_speed == 0) max_speed = UINT16_MAX; // Disable speed limit. break; default: NOT_REACHED(); } if (wait_time != order->GetWaitTime()) { switch (order->GetType()) { case OT_GOTO_STATION: if (order->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION) return_cmd_error(STR_ERROR_TIMETABLE_NOT_STOPPING_HERE); break; case OT_CONDITIONAL: break; default: return_cmd_error(STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS); } } if (travel_time != order->GetTravelTime() && order->IsType(OT_CONDITIONAL)) return CMD_ERROR; if (max_speed != order->GetMaxSpeed() && (order->IsType(OT_CONDITIONAL) || v->type == VEH_AIRCRAFT)) return CMD_ERROR; if (flags & DC_EXEC) { switch (mtf) { case MTF_WAIT_TIME: /* Set time if changing the value or confirming an estimated time as timetabled. */ if (wait_time != order->GetWaitTime() || (wait_time > 0 && !order->IsWaitTimetabled())) { ChangeTimetable(v, order_number, wait_time, MTF_WAIT_TIME, wait_time > 0); } break; case MTF_TRAVEL_TIME: /* Set time if changing the value or confirming an estimated time as timetabled. */ if (travel_time != order->GetTravelTime() || (travel_time > 0 && !order->IsTravelTimetabled())) { ChangeTimetable(v, order_number, travel_time, MTF_TRAVEL_TIME, travel_time > 0); } break; case MTF_TRAVEL_SPEED: if (max_speed != order->GetMaxSpeed()) { ChangeTimetable(v, order_number, max_speed, MTF_TRAVEL_SPEED, max_speed != UINT16_MAX); } break; default: break; } } return CommandCost(); }
/** * Converts a given grayscale map to something that fits in OTTD map system * and create a map of that data. * @param img_width the with of the image in pixels/tiles * @param img_height the height of the image in pixels/tiles * @param map the input map */ static void GrayscaleToMapHeights(uint img_width, uint img_height, byte *map) { /* Defines the detail of the aspect ratio (to avoid doubles) */ const uint num_div = 16384; uint width, height; uint row, col; uint row_pad = 0, col_pad = 0; uint img_scale; uint img_row, img_col; TileIndex tile; /* Get map size and calculate scale and padding values */ switch (_settings_game.game_creation.heightmap_rotation) { default: NOT_REACHED(); case HM_COUNTER_CLOCKWISE: width = MapSizeX(); height = MapSizeY(); break; case HM_CLOCKWISE: width = MapSizeY(); height = MapSizeX(); break; } if ((img_width * num_div) / img_height > ((width * num_div) / height)) { /* Image is wider than map - center vertically */ img_scale = (width * num_div) / img_width; row_pad = (1 + height - ((img_height * img_scale) / num_div)) / 2; } else { /* Image is taller than map - center horizontally */ img_scale = (height * num_div) / img_height; col_pad = (1 + width - ((img_width * img_scale) / num_div)) / 2; } if (_settings_game.construction.freeform_edges) { for (uint x = 0; x < MapSizeX(); x++) MakeVoid(TileXY(x, 0)); for (uint y = 0; y < MapSizeY(); y++) MakeVoid(TileXY(0, y)); } /* Form the landscape */ for (row = 0; row < height; row++) { for (col = 0; col < width; col++) { switch (_settings_game.game_creation.heightmap_rotation) { default: NOT_REACHED(); case HM_COUNTER_CLOCKWISE: tile = TileXY(col, row); break; case HM_CLOCKWISE: tile = TileXY(row, col); break; } /* Check if current tile is within the 1-pixel map edge or padding regions */ if ((!_settings_game.construction.freeform_edges && DistanceFromEdge(tile) <= 1) || (row < row_pad) || (row >= (height - row_pad - (_settings_game.construction.freeform_edges ? 0 : 1))) || (col < col_pad) || (col >= (width - col_pad - (_settings_game.construction.freeform_edges ? 0 : 1)))) { SetTileHeight(tile, 0); } else { /* Use nearest neighbour resizing to scale map data. * We rotate the map 45 degrees (counter)clockwise */ img_row = (((row - row_pad) * num_div) / img_scale); switch (_settings_game.game_creation.heightmap_rotation) { default: NOT_REACHED(); case HM_COUNTER_CLOCKWISE: img_col = (((width - 1 - col - col_pad) * num_div) / img_scale); break; case HM_CLOCKWISE: img_col = (((col - col_pad) * num_div) / img_scale); break; } assert(img_row < img_height); assert(img_col < img_width); /* Colour scales from 0 to 255, OpenTTD height scales from 0 to 15 */ SetTileHeight(tile, map[img_row * img_width + img_col] / 16); } /* Only clear the tiles within the map area. */ if (IsInnerTile(tile)) { MakeClear(tile, CLEAR_GRASS, 3); } } } }
/* The first copy is invoked without command line arguments. Subsequent copies are invoked with a parameter 'depth' that describes how many parent processes preceded them. Each process spawns one or multiple recursive copies of itself, passing 'depth+1' as depth. Some children are started with the '-k' flag, which will result in abnormal termination. */ int main (int argc, char *argv[]) { int n; n = argc > 1 ? atoi (argv[1]) : 0; bool is_at_root = (n == 0); if (is_at_root) msg ("begin"); /* If -k is passed, crash this process. */ if (argc > 2 && !strcmp(argv[2], "-k")) { consume_some_resources_and_die (n); NOT_REACHED (); } int howmany = is_at_root ? EXPECTED_REPETITIONS : 1; int i, expected_depth = -1; for (i = 0; i < howmany; i++) { pid_t child_pid; /* Spawn a child that will be abnormally terminated. To speed the test up, do this only for processes spawned at a certain depth. */ if (n > EXPECTED_DEPTH_TO_PASS/2) { child_pid = spawn_child (n + 1, CRASH); if (child_pid != -1) { if (wait (child_pid) != -1) fail ("crashed child should return -1."); } /* If spawning this child failed, so should the next spawn_child below. */ } /* Now spawn the child that will recurse. */ child_pid = spawn_child (n + 1, RECURSE); /* If maximum depth is reached, return result. */ if (child_pid == -1) return n; /* Else wait for child to report how deeply it was able to recurse. */ int reached_depth = wait (child_pid); if (reached_depth == -1) fail ("wait returned -1."); /* Record the depth reached during the first run; on subsequent runs, fail if those runs do not match the depth achieved on the first run. */ if (i == 0) expected_depth = reached_depth; else if (expected_depth != reached_depth) fail ("after run %d/%d, expected depth %d, actual depth %d.", i, howmany, expected_depth, reached_depth); ASSERT (expected_depth == reached_depth); } consume_some_resources (); if (n == 0) { if (expected_depth < EXPECTED_DEPTH_TO_PASS) fail ("should have forked at least %d times.", EXPECTED_DEPTH_TO_PASS); msg ("success. program forked %d times.", howmany); msg ("end"); } return expected_depth; }
void memcache_parse_req(struct msg *r) { struct mbuf *b; uint8_t *p, *m; uint8_t ch; enum { SW_START, SW_REQ_TYPE, SW_SPACES_BEFORE_KEY, SW_KEY, SW_SPACES_BEFORE_KEYS, SW_SPACES_BEFORE_FLAGS, SW_FLAGS, SW_SPACES_BEFORE_EXPIRY, SW_EXPIRY, SW_SPACES_BEFORE_VLEN, SW_VLEN, SW_SPACES_BEFORE_CAS, SW_CAS, SW_RUNTO_VAL, SW_VAL, SW_SPACES_BEFORE_NUM, SW_NUM, SW_RUNTO_CRLF, SW_CRLF, SW_NOREPLY, SW_AFTER_NOREPLY, SW_ALMOST_DONE, SW_SENTINEL } state; state = r->state; b = STAILQ_LAST(&r->mhdr, mbuf, next); ASSERT(r->request); ASSERT(r->protocol == MEMCACHE_ASCII); ASSERT(state >= SW_START && state < SW_SENTINEL); ASSERT(b != NULL); ASSERT(b->pos <= b->last); /* validate the parsing maker */ ASSERT(r->pos != NULL); ASSERT(r->pos >= b->pos && r->pos <= b->last); for (p = r->pos; p < b->last; p++) { ch = *p; switch (state) { case SW_START: if (ch == ' ') { break; } if (!islower(ch)) { goto error; } /* req_start <- p; type_start <- p */ r->token = p; state = SW_REQ_TYPE; break; case SW_REQ_TYPE: if (ch == ' ' || ch == CR) { /* type_end = p - 1 */ m = r->token; r->token = NULL; r->type = MSG_UNKNOWN; switch (p - m) { case 3: if (str4cmp(m, 'g', 'e', 't', ' ')) { r->type = MSG_REQ_MC_GET; break; } if (str4cmp(m, 's', 'e', 't', ' ')) { r->type = MSG_REQ_MC_SET; break; } if (str4cmp(m, 'a', 'd', 'd', ' ')) { r->type = MSG_REQ_MC_ADD; break; } if (str4cmp(m, 'c', 'a', 's', ' ')) { r->type = MSG_REQ_MC_CAS; break; } break; case 4: if (str4cmp(m, 'g', 'e', 't', 's')) { r->type = MSG_REQ_MC_GETS; break; } if (str4cmp(m, 'i', 'n', 'c', 'r')) { r->type = MSG_REQ_MC_INCR; break; } if (str4cmp(m, 'd', 'e', 'c', 'r')) { r->type = MSG_REQ_MC_DECR; break; } if (str4cmp(m, 'q', 'u', 'i', 't')) { r->type = MSG_REQ_MC_QUIT; r->quit = 1; break; } break; case 6: if (str6cmp(m, 'a', 'p', 'p', 'e', 'n', 'd')) { r->type = MSG_REQ_MC_APPEND; break; } if (str6cmp(m, 'd', 'e', 'l', 'e', 't', 'e')) { r->type = MSG_REQ_MC_DELETE; break; } break; case 7: if (str7cmp(m, 'p', 'r', 'e', 'p', 'e', 'n', 'd')) { r->type = MSG_REQ_MC_PREPEND; break; } if (str7cmp(m, 'r', 'e', 'p', 'l', 'a', 'c', 'e')) { r->type = MSG_REQ_MC_REPLACE; break; } break; } switch (r->type) { case MSG_REQ_MC_GET: case MSG_REQ_MC_GETS: case MSG_REQ_MC_DELETE: case MSG_REQ_MC_CAS: case MSG_REQ_MC_SET: case MSG_REQ_MC_ADD: case MSG_REQ_MC_REPLACE: case MSG_REQ_MC_APPEND: case MSG_REQ_MC_PREPEND: case MSG_REQ_MC_INCR: case MSG_REQ_MC_DECR: if (ch == CR) { goto error; } state = SW_SPACES_BEFORE_KEY; break; case MSG_REQ_MC_QUIT: p = p - 1; /* go back by 1 byte */ state = SW_CRLF; break; case MSG_UNKNOWN: goto error; default: NOT_REACHED(); } } else if (!islower(ch)) { goto error; } break; case SW_SPACES_BEFORE_KEY: if (ch != ' ') { r->token = p; r->key_start = p; state = SW_KEY; } break; case SW_KEY: if (ch == ' ' || ch == CR) { if ((p - r->key_start) > MEMCACHE_MAX_KEY_LENGTH) { log_error("parsed bad req %"PRIu64" of type %d with key " "prefix '%.*s...' and length %d that exceeds " "maximum key length", r->id, r->type, 16, r->key_start, p - r->key_start); goto error; } r->key_end = p; r->token = NULL; /* get next state */ if (memcache_storage(r)) { state = SW_SPACES_BEFORE_FLAGS; } else if (memcache_arithmetic(r)) { state = SW_SPACES_BEFORE_NUM; } else if (memcache_delete(r)) { state = SW_RUNTO_CRLF; } else if (memcache_retrieval(r)) { state = SW_SPACES_BEFORE_KEYS; } else { state = SW_RUNTO_CRLF; } if (ch == CR) { if (memcache_storage(r) || memcache_arithmetic(r)) { goto error; } p = p - 1; /* go back by 1 byte */ } } break; case SW_SPACES_BEFORE_KEYS: ASSERT(memcache_retrieval(r)); switch (ch) { case ' ': break; case CR: state = SW_ALMOST_DONE; break; default: r->token = p; goto fragment; } break; case SW_SPACES_BEFORE_FLAGS: if (ch != ' ') { if (!isdigit(ch)) { goto error; } /* flags_start <- p; flags <- ch - '0' */ r->token = p; state = SW_FLAGS; } break; case SW_FLAGS: if (isdigit(ch)) { /* flags <- flags * 10 + (ch - '0') */ ; } else if (ch == ' ') { /* flags_end <- p - 1 */ r->token = NULL; state = SW_SPACES_BEFORE_EXPIRY; } else { goto error; } break; case SW_SPACES_BEFORE_EXPIRY: if (ch != ' ') { if (!isdigit(ch)) { goto error; } /* expiry_start <- p; expiry <- ch - '0' */ r->token = p; state = SW_EXPIRY; } break; case SW_EXPIRY: if (isdigit(ch)) { /* expiry <- expiry * 10 + (ch - '0') */ ; } else if (ch == ' ') { /* expiry_end <- p - 1 */ r->token = NULL; state = SW_SPACES_BEFORE_VLEN; } else { goto error; } break; case SW_SPACES_BEFORE_VLEN: if (ch != ' ') { if (!isdigit(ch)) { goto error; } /* vlen_start <- p */ r->token = p; r->vlen = (uint32_t)(ch - '0'); state = SW_VLEN; } break; case SW_VLEN: if (isdigit(ch)) { r->vlen = r->vlen * 10 + (uint32_t)(ch - '0'); } else if (memcache_cas(r)) { if (ch != ' ') { goto error; } /* vlen_end <- p - 1 */ p = p - 1; /* go back by 1 byte */ r->token = NULL; state = SW_SPACES_BEFORE_CAS; } else if (ch == ' ' || ch == CR) { /* vlen_end <- p - 1 */ p = p - 1; /* go back by 1 byte */ r->token = NULL; state = SW_RUNTO_CRLF; } else { goto error; } break; case SW_SPACES_BEFORE_CAS: if (ch != ' ') { if (!isdigit(ch)) { goto error; } /* cas_start <- p; cas <- ch - '0' */ r->token = p; state = SW_CAS; } break; case SW_CAS: if (isdigit(ch)) { /* cas <- cas * 10 + (ch - '0') */ ; } else if (ch == ' ' || ch == CR) { /* cas_end <- p - 1 */ p = p - 1; /* go back by 1 byte */ r->token = NULL; state = SW_RUNTO_CRLF; } else { goto error; } break; case SW_RUNTO_VAL: switch (ch) { case LF: /* val_start <- p + 1 */ state = SW_VAL; break; default: goto error; } break; case SW_VAL: m = p + r->vlen; if (m >= b->last) { ASSERT(r->vlen >= (uint32_t)(b->last - p)); r->vlen -= (uint32_t)(b->last - p); m = b->last - 1; p = m; /* move forward by vlen bytes */ break; } switch (*m) { case CR: /* val_end <- p - 1 */ p = m; /* move forward by vlen bytes */ state = SW_ALMOST_DONE; break; default: goto error; } break; case SW_SPACES_BEFORE_NUM: if (ch != ' ') { if (!isdigit(ch)) { goto error; } /* num_start <- p; num <- ch - '0' */ r->token = p; state = SW_NUM; } break; case SW_NUM: if (isdigit(ch)) { /* num <- num * 10 + (ch - '0') */ ; } else if (ch == ' ' || ch == CR) { r->token = NULL; /* num_end <- p - 1 */ p = p - 1; /* go back by 1 byte */ state = SW_RUNTO_CRLF; } else { goto error; } break; case SW_RUNTO_CRLF: switch (ch) { case ' ': break; case 'n': if (memcache_storage(r) || memcache_arithmetic(r) || memcache_delete(r)) { /* noreply_start <- p */ r->token = p; state = SW_NOREPLY; } else { goto error; } break; case CR: if (memcache_storage(r)) { state = SW_RUNTO_VAL; } else { state = SW_ALMOST_DONE; } break; default: goto error; } break; case SW_NOREPLY: switch (ch) { case ' ': case CR: m = r->token; if (((p - m) == 7) && str7cmp(m, 'n', 'o', 'r', 'e', 'p', 'l', 'y')) { ASSERT(memcache_storage(r) || memcache_arithmetic(r) || memcache_delete(r)); r->token = NULL; /* noreply_end <- p - 1 */ r->noreply = 1; state = SW_AFTER_NOREPLY; p = p - 1; /* go back by 1 byte */ } else { goto error; } } break; case SW_AFTER_NOREPLY: switch (ch) { case ' ': break; case CR: if (memcache_storage(r)) { state = SW_RUNTO_VAL; } else { state = SW_ALMOST_DONE; } break; default: goto error; } break; case SW_CRLF: switch (ch) { case ' ': break; case CR: state = SW_ALMOST_DONE; break; default: goto error; } break; case SW_ALMOST_DONE: switch (ch) { case LF: /* req_end <- p */ goto done; default: goto error; } break; case SW_SENTINEL: default: NOT_REACHED(); break; } } /* * At this point, buffer from b->pos to b->last has been parsed completely * but we haven't been able to reach to any conclusion. Normally, this * means that we have to parse again starting from the state we are in * after more data has been read. The newly read data is either read into * a new mbuf, if existing mbuf is full (b->last == b->end) or into the * existing mbuf. * * The only exception to this is when the existing mbuf is full (b->last * is at b->end) and token marker is set, which means that we have to * copy the partial token into a new mbuf and parse again with more data * read into new mbuf. */ ASSERT(p == b->last); r->pos = p; r->state = state; if (b->last == b->end && r->token != NULL) { r->pos = r->token; r->token = NULL; r->result = MSG_PARSE_REPAIR; } else { r->result = MSG_PARSE_AGAIN; } log_hexdump(LOG_VERB, b->pos, mbuf_length(b), "parsed req %"PRIu64" res %d " "type %d state %d rpos %d of %d", r->id, r->result, r->type, r->state, r->pos - b->pos, b->last - b->pos); return; fragment: ASSERT(p != b->last); ASSERT(r->token != NULL); r->pos = r->token; r->token = NULL; r->state = state; r->result = MSG_PARSE_FRAGMENT; log_hexdump(LOG_VERB, b->pos, mbuf_length(b), "parsed req %"PRIu64" res %d " "type %d state %d rpos %d of %d", r->id, r->result, r->type, r->state, r->pos - b->pos, b->last - b->pos); return; done: ASSERT(r->type > MSG_UNKNOWN && r->type < MSG_SENTINEL); r->pos = p + 1; ASSERT(r->pos <= b->last); r->state = SW_START; r->result = MSG_PARSE_OK; log_hexdump(LOG_VERB, b->pos, mbuf_length(b), "parsed req %"PRIu64" res %d " "type %d state %d rpos %d of %d", r->id, r->result, r->type, r->state, r->pos - b->pos, b->last - b->pos); return; error: r->result = MSG_PARSE_ERROR; r->state = state; errno = EINVAL; log_hexdump(LOG_INFO, b->pos, mbuf_length(b), "parsed bad req %"PRIu64" " "res %d type %d state %d", r->id, r->result, r->type, r->state); }
static void call_make_storage_req(struct context *ctx, struct call *call, uint32_t key_id, long int key_vlen) { struct opt *opt = &ctx->opt; int len; uint32_t i; for (i = 0; i < REQ_IOV_LEN; i++) { struct iovec *iov = &call->req.iov[i]; switch (i) { case REQ_IOV_METHOD: iov->iov_base = req_strings[opt->method].data; iov->iov_len = req_strings[opt->method].len; break; case REQ_IOV_KEY: len = mcp_scnprintf(call->req.keyname, sizeof(call->req.keyname), "%.*s%08"PRIx32" ", opt->prefix.len, opt->prefix.data, key_id); iov->iov_base = call->req.keyname; iov->iov_len = (size_t)len; break; case REQ_IOV_FLAG: iov->iov_base = msg_strings[MSG_ZERO].data; iov->iov_len = msg_strings[MSG_ZERO].len; break; case REQ_IOV_EXPIRY: len = mcp_scnprintf(call->req.expiry, sizeof(call->req.expiry), "%"PRIu32" ", opt->expiry); iov->iov_base = call->req.expiry; iov->iov_len = (size_t)len; break; case REQ_IOV_VLEN: len = mcp_scnprintf(call->req.keylen, sizeof(call->req.keylen), "%ld ", key_vlen); iov->iov_base = call->req.keylen; iov->iov_len = (size_t)len; break; case REQ_IOV_CAS: if (opt->method == REQ_CAS) { iov->iov_base = "1 "; iov->iov_len = 2; } else { iov->iov_base = NULL; iov->iov_len = 0; } break; case REQ_IOV_NOREPLY: if (opt->use_noreply) { iov->iov_base = msg_strings[MSG_NOREPLY].data; iov->iov_len = msg_strings[MSG_NOREPLY].len; call->req.noreply = 1; } else { iov->iov_base = NULL; iov->iov_len = 0; call->req.noreply = 0; } break; case REQ_IOV_CRLF: iov->iov_base = msg_strings[MSG_CRLF].data; iov->iov_len = msg_strings[MSG_CRLF].len; break; case REQ_IOV_VALUE: ASSERT(key_vlen >= 0 && key_vlen <= sizeof(ctx->buf1m)); iov->iov_base = ctx->buf1m; iov->iov_len = (size_t)key_vlen; break; case REQ_IOV_CRLF2: iov->iov_base = msg_strings[MSG_CRLF].data; iov->iov_len = msg_strings[MSG_CRLF].len; break; default: NOT_REACHED(); } call->req.send += iov->iov_len; } }
bool VideoDriver_SDL::CreateMainSurface(uint w, uint h) { SDL_Surface *newscreen, *icon; char caption[50]; int bpp = BlitterFactory::GetCurrentBlitter()->GetScreenDepth(); bool want_hwpalette; GetAvailableVideoMode(&w, &h); DEBUG(driver, 1, "SDL: using mode %ux%ux%d", w, h, bpp); if (bpp == 0) usererror("Can't use a blitter that blits 0 bpp for normal visuals"); char icon_path[MAX_PATH]; if (FioFindFullPath(icon_path, lastof(icon_path), BASESET_DIR, "openttd.32.bmp") != NULL) { /* Give the application an icon */ icon = SDL_CALL SDL_LoadBMP(icon_path); if (icon != NULL) { /* Get the colourkey, which will be magenta */ uint32 rgbmap = SDL_CALL SDL_MapRGB(icon->format, 255, 0, 255); SDL_CALL SDL_SetColorKey(icon, SDL_SRCCOLORKEY, rgbmap); SDL_CALL SDL_WM_SetIcon(icon, NULL); SDL_CALL SDL_FreeSurface(icon); } } if (_use_hwpalette == 2) { /* Default is to autodetect when to use SDL_HWPALETTE. * In this case, SDL_HWPALETTE is only used for 8bpp * blitters in fullscreen. * * When using an 8bpp blitter on a 8bpp system in * windowed mode with SDL_HWPALETTE, OpenTTD will claim * the system palette, making all other applications * get the wrong colours. In this case, we're better of * trying to approximate the colors we need using system * colors, using a shadow surface (see below). * * On a 32bpp system, SDL_HWPALETTE is ignored, so it * doesn't matter what we do. * * When using a 32bpp blitter on a 8bpp system, setting * SDL_HWPALETTE messes up rendering (at least on X11), * so we don't do that. In this case, SDL takes care of * color approximation using its own shadow surface * (which we can't force in 8bpp on 8bpp mode, * unfortunately). */ want_hwpalette = bpp == 8 && _fullscreen && _support8bpp == S8BPP_HARDWARE; } else { /* User specified a value manually */ want_hwpalette = _use_hwpalette; } if (want_hwpalette) DEBUG(driver, 1, "SDL: requesting hardware palete"); /* Free any previously allocated shadow surface */ if (_sdl_screen != NULL && _sdl_screen != _sdl_realscreen) SDL_CALL SDL_FreeSurface(_sdl_screen); if (_sdl_realscreen != NULL) { if (_requested_hwpalette != want_hwpalette) { /* SDL (at least the X11 driver), reuses the * same window and palette settings when the bpp * (and a few flags) are the same. Since we need * to hwpalette value to change (in particular * when switching between fullscreen and * windowed), we restart the entire video * subsystem to force creating a new window. */ DEBUG(driver, 0, "SDL: Restarting SDL video subsystem, to force hwpalette change"); SDL_CALL SDL_QuitSubSystem(SDL_INIT_VIDEO); SDL_CALL SDL_InitSubSystem(SDL_INIT_VIDEO); ClaimMousePointer(); SetupKeyboard(); } } /* Remember if we wanted a hwpalette. We can't reliably query * SDL for the SDL_HWPALETTE flag, since it might get set even * though we didn't ask for it (when SDL creates a shadow * surface, for example). */ _requested_hwpalette = want_hwpalette; /* DO NOT CHANGE TO HWSURFACE, IT DOES NOT WORK */ newscreen = SDL_CALL SDL_SetVideoMode(w, h, bpp, SDL_SWSURFACE | (want_hwpalette ? SDL_HWPALETTE : 0) | (_fullscreen ? SDL_FULLSCREEN : SDL_RESIZABLE)); if (newscreen == NULL) { DEBUG(driver, 0, "SDL: Couldn't allocate a window to draw on"); return false; } _sdl_realscreen = newscreen; if (bpp == 8 && (_sdl_realscreen->flags & SDL_HWPALETTE) != SDL_HWPALETTE) { /* Using an 8bpp blitter, if we didn't get a hardware * palette (most likely because we didn't request one, * see above), we'll have to set up a shadow surface to * render on. * * Our palette will be applied to this shadow surface, * while the real screen surface will use the shared * system palette (which will partly contain our colors, * but most likely will not have enough free color cells * for all of our colors). SDL can use these two * palettes at blit time to approximate colors used in * the shadow surface using system colors automatically. * * Note that when using an 8bpp blitter on a 32bpp * system, SDL will create an internal shadow surface. * This shadow surface will have SDL_HWPALLETE set, so * we won't create a second shadow surface in this case. */ DEBUG(driver, 1, "SDL: using shadow surface"); newscreen = SDL_CALL SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, bpp, 0, 0, 0, 0); if (newscreen == NULL) { DEBUG(driver, 0, "SDL: Couldn't allocate a shadow surface to draw on"); return false; } } /* Delay drawing for this cycle; the next cycle will redraw the whole screen */ _num_dirty_rects = 0; _screen.width = newscreen->w; _screen.height = newscreen->h; _screen.pitch = newscreen->pitch / (bpp / 8); _screen.dst_ptr = newscreen->pixels; _sdl_screen = newscreen; /* When in full screen, we will always have the mouse cursor * within the window, even though SDL does not give us the * appropriate event to know this. */ if (_fullscreen) _cursor.in_window = true; Blitter *blitter = BlitterFactory::GetCurrentBlitter(); blitter->PostResize(); InitPalette(); switch (blitter->UsePaletteAnimation()) { case Blitter::PALETTE_ANIMATION_NONE: case Blitter::PALETTE_ANIMATION_VIDEO_BACKEND: UpdatePalette(); break; case Blitter::PALETTE_ANIMATION_BLITTER: if (VideoDriver::GetInstance() != NULL) blitter->PaletteAnimate(_local_palette); break; default: NOT_REACHED(); } seprintf(caption, lastof(caption), "OpenTTD %s", _openttd_revision); SDL_CALL SDL_WM_SetCaption(caption, caption); GameSizeChanged(); return true; }
static void rsp_forward_stats(struct context *ctx, struct msg *msg, struct conn *s_conn, struct conn *c_conn) { struct msg *pmsg; struct server *server; ASSERT(!s_conn->client && !s_conn->proxy); ASSERT(c_conn->client && !c_conn->proxy); ASSERT(!msg->request && msg->peer != NULL); server = s_conn->owner; pmsg = msg->peer; stats_server_incr(ctx, server, responses); stats_server_incr_by(ctx, server, response_bytes, msg->mlen); switch (msg->type) { case MSG_RSP_NUM: stats_server_incr(ctx, server, num); break; case MSG_RSP_STORED: stats_server_incr(ctx, server, stored); break; case MSG_RSP_NOT_STORED: stats_server_incr(ctx, server, not_stored); break; case MSG_RSP_EXISTS: stats_server_incr(ctx, server, exists); break; case MSG_RSP_NOT_FOUND: stats_server_incr(ctx, server, not_found); break; case MSG_RSP_END: stats_server_incr(ctx, server, end); break; case MSG_RSP_VALUE: stats_server_incr(ctx, server, value); break; case MSG_RSP_DELETED: stats_server_incr(ctx, server, deleted); break; case MSG_RSP_ERROR: log_debug(LOG_INFO, "rsp error type %d from s %d for req %"PRIu64" " "type %d from c %d", msg->type, s_conn->sd, pmsg->id, pmsg->type, c_conn->sd); stats_server_incr(ctx, server, error); break; case MSG_RSP_CLIENT_ERROR: log_debug(LOG_INFO, "rsp error type %d from s %d for req %"PRIu64" " "type %d from c %d", msg->type, s_conn->sd, pmsg->id, pmsg->type, c_conn->sd); stats_server_incr(ctx, server, client_error); break; case MSG_RSP_SERVER_ERROR: log_debug(LOG_INFO, "rsp error type %d from s %d for req %"PRIu64" " "type %d from c %d", msg->type, s_conn->sd, pmsg->id, pmsg->type, c_conn->sd); stats_server_incr(ctx, server, server_error); break; default: NOT_REACHED(); } }
static void parse_named_action(enum ofputil_action_code code, const struct flow *flow, char *arg, struct ofpbuf *ofpacts) { struct ofpact_tunnel *tunnel; uint16_t vid; ovs_be32 ip; uint8_t pcp; uint8_t tos; switch (code) { case OFPUTIL_ACTION_INVALID: NOT_REACHED(); case OFPUTIL_OFPAT10_OUTPUT: case OFPUTIL_OFPAT11_OUTPUT: parse_output(arg, ofpacts); break; case OFPUTIL_OFPAT10_SET_VLAN_VID: case OFPUTIL_OFPAT11_SET_VLAN_VID: vid = str_to_u32(arg); if (vid & ~VLAN_VID_MASK) { ovs_fatal(0, "%s: not a valid VLAN VID", arg); } ofpact_put_SET_VLAN_VID(ofpacts)->vlan_vid = vid; break; case OFPUTIL_OFPAT10_SET_VLAN_PCP: case OFPUTIL_OFPAT11_SET_VLAN_PCP: pcp = str_to_u32(arg); if (pcp & ~7) { ovs_fatal(0, "%s: not a valid VLAN PCP", arg); } ofpact_put_SET_VLAN_PCP(ofpacts)->vlan_pcp = pcp; break; case OFPUTIL_OFPAT12_SET_FIELD: set_field_parse(arg, ofpacts); break; case OFPUTIL_OFPAT10_STRIP_VLAN: case OFPUTIL_OFPAT11_POP_VLAN: ofpact_put_STRIP_VLAN(ofpacts); break; case OFPUTIL_OFPAT10_SET_DL_SRC: case OFPUTIL_OFPAT11_SET_DL_SRC: str_to_mac(arg, ofpact_put_SET_ETH_SRC(ofpacts)->mac); break; case OFPUTIL_OFPAT10_SET_DL_DST: case OFPUTIL_OFPAT11_SET_DL_DST: str_to_mac(arg, ofpact_put_SET_ETH_DST(ofpacts)->mac); break; case OFPUTIL_OFPAT10_SET_NW_SRC: case OFPUTIL_OFPAT11_SET_NW_SRC: str_to_ip(arg, &ip); ofpact_put_SET_IPV4_SRC(ofpacts)->ipv4 = ip; break; case OFPUTIL_OFPAT10_SET_NW_DST: case OFPUTIL_OFPAT11_SET_NW_DST: str_to_ip(arg, &ip); ofpact_put_SET_IPV4_DST(ofpacts)->ipv4 = ip; break; case OFPUTIL_OFPAT10_SET_NW_TOS: case OFPUTIL_OFPAT11_SET_NW_TOS: tos = str_to_u32(arg); if (tos & ~IP_DSCP_MASK) { ovs_fatal(0, "%s: not a valid TOS", arg); } ofpact_put_SET_IPV4_DSCP(ofpacts)->dscp = tos; break; case OFPUTIL_OFPAT11_DEC_NW_TTL: NOT_REACHED(); case OFPUTIL_OFPAT10_SET_TP_SRC: case OFPUTIL_OFPAT11_SET_TP_SRC: ofpact_put_SET_L4_SRC_PORT(ofpacts)->port = str_to_u32(arg); break; case OFPUTIL_OFPAT10_SET_TP_DST: case OFPUTIL_OFPAT11_SET_TP_DST: ofpact_put_SET_L4_DST_PORT(ofpacts)->port = str_to_u32(arg); break; case OFPUTIL_OFPAT10_ENQUEUE: parse_enqueue(arg, ofpacts); break; case OFPUTIL_NXAST_RESUBMIT: parse_resubmit(arg, ofpacts); break; case OFPUTIL_NXAST_SET_TUNNEL: case OFPUTIL_NXAST_SET_TUNNEL64: tunnel = ofpact_put_SET_TUNNEL(ofpacts); tunnel->ofpact.compat = code; tunnel->tun_id = str_to_u64(arg); break; case OFPUTIL_NXAST_WRITE_METADATA: parse_metadata(ofpacts, arg); break; case OFPUTIL_NXAST_SET_QUEUE: ofpact_put_SET_QUEUE(ofpacts)->queue_id = str_to_u32(arg); break; case OFPUTIL_NXAST_POP_QUEUE: ofpact_put_POP_QUEUE(ofpacts); break; case OFPUTIL_NXAST_REG_MOVE: nxm_parse_reg_move(ofpact_put_REG_MOVE(ofpacts), arg); break; case OFPUTIL_NXAST_REG_LOAD: nxm_parse_reg_load(ofpact_put_REG_LOAD(ofpacts), arg); break; case OFPUTIL_NXAST_NOTE: parse_note(arg, ofpacts); break; case OFPUTIL_NXAST_MULTIPATH: multipath_parse(ofpact_put_MULTIPATH(ofpacts), arg); break; case OFPUTIL_NXAST_AUTOPATH__DEPRECATED: autopath_parse(ofpact_put_AUTOPATH(ofpacts), arg); break; case OFPUTIL_NXAST_BUNDLE: bundle_parse(arg, ofpacts); break; case OFPUTIL_NXAST_BUNDLE_LOAD: bundle_parse_load(arg, ofpacts); break; case OFPUTIL_NXAST_RESUBMIT_TABLE: case OFPUTIL_NXAST_OUTPUT_REG: case OFPUTIL_NXAST_DEC_TTL_CNT_IDS: NOT_REACHED(); case OFPUTIL_NXAST_LEARN: learn_parse(arg, flow, ofpacts); break; case OFPUTIL_NXAST_EXIT: ofpact_put_EXIT(ofpacts); break; case OFPUTIL_NXAST_DEC_TTL: parse_dec_ttl(ofpacts, arg); break; case OFPUTIL_NXAST_FIN_TIMEOUT: parse_fin_timeout(ofpacts, arg); break; case OFPUTIL_NXAST_CONTROLLER: parse_controller(ofpacts, arg); break; } }
/* Convert 'str_' (as described in the Flow Syntax section of the ovs-ofctl man * page) into 'fm' for sending the specified flow_mod 'command' to a switch. * If 'actions' is specified, an action must be in 'string' and may be expanded * or reallocated. * * To parse syntax for an OFPT_FLOW_MOD (or NXT_FLOW_MOD), use an OFPFC_* * constant for 'command'. To parse syntax for an OFPST_FLOW or * OFPST_AGGREGATE (or NXST_FLOW or NXST_AGGREGATE), use -1 for 'command'. */ void parse_ofp_str(struct ofputil_flow_mod *fm, int command, const char *str_, bool verbose) { enum { F_OUT_PORT = 1 << 0, F_ACTIONS = 1 << 1, F_TIMEOUT = 1 << 3, F_PRIORITY = 1 << 4, F_FLAGS = 1 << 5, } fields; char *string = xstrdup(str_); char *save_ptr = NULL; char *act_str = NULL; char *name; switch (command) { case -1: fields = F_OUT_PORT; break; case OFPFC_ADD: fields = F_ACTIONS | F_TIMEOUT | F_PRIORITY | F_FLAGS; break; case OFPFC_DELETE: fields = F_OUT_PORT; break; case OFPFC_DELETE_STRICT: fields = F_OUT_PORT | F_PRIORITY; break; case OFPFC_MODIFY: fields = F_ACTIONS | F_TIMEOUT | F_PRIORITY | F_FLAGS; break; case OFPFC_MODIFY_STRICT: fields = F_ACTIONS | F_TIMEOUT | F_PRIORITY | F_FLAGS; break; default: NOT_REACHED(); } match_init_catchall(&fm->match); fm->priority = OFP_DEFAULT_PRIORITY; fm->cookie = htonll(0); fm->cookie_mask = htonll(0); if (command == OFPFC_MODIFY || command == OFPFC_MODIFY_STRICT) { /* For modify, by default, don't update the cookie. */ fm->new_cookie = htonll(UINT64_MAX); } else{ fm->new_cookie = htonll(0); } fm->table_id = 0xff; fm->command = command; fm->idle_timeout = OFP_FLOW_PERMANENT; fm->hard_timeout = OFP_FLOW_PERMANENT; fm->buffer_id = UINT32_MAX; fm->out_port = OFPP_NONE; fm->flags = 0; if (fields & F_ACTIONS) { act_str = strstr(string, "action"); if (!act_str) { ofp_fatal(str_, verbose, "must specify an action"); } *act_str = '\0'; act_str = strchr(act_str + 1, '='); if (!act_str) { ofp_fatal(str_, verbose, "must specify an action"); } act_str++; } for (name = strtok_r(string, "=, \t\r\n", &save_ptr); name; name = strtok_r(NULL, "=, \t\r\n", &save_ptr)) { const struct protocol *p; if (parse_protocol(name, &p)) { match_set_dl_type(&fm->match, htons(p->dl_type)); if (p->nw_proto) { match_set_nw_proto(&fm->match, p->nw_proto); } } else if (fields & F_FLAGS && !strcmp(name, "send_flow_rem")) { fm->flags |= OFPFF_SEND_FLOW_REM; } else if (fields & F_FLAGS && !strcmp(name, "check_overlap")) { fm->flags |= OFPFF_CHECK_OVERLAP; } else { char *value; value = strtok_r(NULL, ", \t\r\n", &save_ptr); if (!value) { ofp_fatal(str_, verbose, "field %s missing value", name); } if (!strcmp(name, "table")) { fm->table_id = str_to_table_id(value); } else if (!strcmp(name, "out_port")) { if (!ofputil_port_from_string(name, &fm->out_port)) { ofp_fatal(str_, verbose, "%s is not a valid OpenFlow port", name); } } else if (fields & F_PRIORITY && !strcmp(name, "priority")) { fm->priority = str_to_u16(value, name); } else if (fields & F_TIMEOUT && !strcmp(name, "idle_timeout")) { fm->idle_timeout = str_to_u16(value, name); } else if (fields & F_TIMEOUT && !strcmp(name, "hard_timeout")) { fm->hard_timeout = str_to_u16(value, name); } else if (!strcmp(name, "cookie")) { char *mask = strchr(value, '/'); if (mask) { /* A mask means we're searching for a cookie. */ if (command == OFPFC_ADD) { ofp_fatal(str_, verbose, "flow additions cannot use " "a cookie mask"); } *mask = '\0'; fm->cookie = htonll(str_to_u64(value)); fm->cookie_mask = htonll(str_to_u64(mask+1)); } else { /* No mask means that the cookie is being set. */ if (command != OFPFC_ADD && command != OFPFC_MODIFY && command != OFPFC_MODIFY_STRICT) { ofp_fatal(str_, verbose, "cannot set cookie"); } fm->new_cookie = htonll(str_to_u64(value)); } } else if (mf_from_name(name)) { parse_field(mf_from_name(name), value, &fm->match); } else if (!strcmp(name, "duration") || !strcmp(name, "n_packets") || !strcmp(name, "n_bytes")) { /* Ignore these, so that users can feed the output of * "ovs-ofctl dump-flows" back into commands that parse * flows. */ } else { ofp_fatal(str_, verbose, "unknown keyword %s", name); } } } if (!fm->cookie_mask && fm->new_cookie == htonll(UINT64_MAX) && (command == OFPFC_MODIFY || command == OFPFC_MODIFY_STRICT)) { /* On modifies without a mask, we are supposed to add a flow if * one does not exist. If a cookie wasn't been specified, use a * default of zero. */ fm->new_cookie = htonll(0); } if (fields & F_ACTIONS) { struct ofpbuf ofpacts; ofpbuf_init(&ofpacts, 32); str_to_inst_ofpacts(&fm->match.flow, act_str, &ofpacts); fm->ofpacts_len = ofpacts.size; fm->ofpacts = ofpbuf_steal_data(&ofpacts); } else { fm->ofpacts_len = 0; fm->ofpacts = NULL; } free(string); }
static void syscall_handler (struct intr_frame *f) { /* printf ("system call!\n");//TODO remove thread_exit ();*/ uint32_t ret_val; offset = f->esp; int sys_call = (int) next_arg(); char *tmp; //TODO remove switch (sys_call) { case SYS_HALT: power_off(); NOT_REACHED (); case SYS_EXIT: syscall_exit((int) next_arg()); NOT_REACHED (); case SYS_EXEC: ret_val = exec(); break; case SYS_WAIT: ret_val = process_wait((tid_t) next_arg()); break; case SYS_CREATE: // printf("test\n"); // printf("file_name: %s, size: %d\n", next_str(), next_arg()); tmp = next_str(); ret_val = filesys_create(tmp, next_arg()); break; case SYS_REMOVE: ret_val = filesys_remove(next_str()); break; case SYS_OPEN: next_str(); break; case SYS_FILESIZE: next_arg(); break; case SYS_READ: /* next_arg(); next_arg(); next_arg(); */ ret_val = syscall_read(); break; case SYS_WRITE: //FIXME this is just a temporary function to print to console unil real call is implemented /*if ((int) next_arg() == STDOUT_FILENO) { printf("%s", (char *) next_arg()); }*/ ret_val = syscall_write(); break; case SYS_SEEK: break; case SYS_TELL: break; case SYS_CLOSE: break; default: //TODO print error message break; } f->eax = ret_val; }
/** * Stages cargo for unloading. The cargo is sorted so that packets to be * transferred, delivered or kept are in consecutive chunks in the list. At the * same time the designation_counts are updated to reflect the size of those * chunks. * @param accepted If the cargo will be accepted at the station. * @param current_station ID of the station. * @param next_station ID of the station the vehicle will go to next. * @param order_flags OrderUnloadFlags that will apply to the unload operation. * @param ge GoodsEntry for getting the flows. * @param payment Payment object for registering transfers. * return If any cargo will be unloaded. */ bool VehicleCargoList::Stage(bool accepted, StationID current_station, StationID next_station, uint8 order_flags, const GoodsEntry *ge, CargoPayment *payment) { this->AssertCountConsistency(); assert(this->action_counts[MTA_LOAD] == 0); this->action_counts[MTA_TRANSFER] = this->action_counts[MTA_DELIVER] = this->action_counts[MTA_KEEP] = 0; Iterator deliver = this->packets.end(); Iterator it = this->packets.begin(); uint sum = 0; bool force_keep = (order_flags & OUFB_NO_UNLOAD) != 0; bool force_unload = (order_flags & OUFB_UNLOAD) != 0; bool force_transfer = (order_flags & (OUFB_TRANSFER | OUFB_UNLOAD)) != 0; assert(this->count > 0 || it == this->packets.end()); while (sum < this->count) { CargoPacket *cp = *it; this->packets.erase(it++); StationID cargo_next = INVALID_STATION; MoveToAction action = MTA_LOAD; if (force_keep) { action = MTA_KEEP; } else if (force_unload && accepted && cp->source != current_station) { action = MTA_DELIVER; } else if (force_transfer) { action = MTA_TRANSFER; cargo_next = ge->GetVia(cp->source, current_station, next_station); assert((cargo_next != next_station || cargo_next == INVALID_STATION) && cargo_next != current_station); } else { /* Rewrite an invalid source station to some random other one to * avoid keeping the cargo in the vehicle forever. */ if (cp->source == INVALID_STATION && !ge->flows.empty()) { cp->source = ge->flows.begin()->first; } cargo_next = ge->GetVia(cp->source); if (cargo_next == INVALID_STATION) { action = (accepted && cp->source != current_station) ? MTA_DELIVER : MTA_KEEP; } else if (cargo_next == current_station) { action = MTA_DELIVER; } else if (cargo_next == next_station) { action = MTA_KEEP; } else { action = MTA_TRANSFER; } } Money share; switch (action) { case MTA_KEEP: this->packets.push_back(cp); if (deliver == this->packets.end()) --deliver; break; case MTA_DELIVER: this->packets.insert(deliver, cp); break; case MTA_TRANSFER: this->packets.push_front(cp); /* Add feeder share here to allow reusing field for next station. */ share = payment->PayTransfer(cp, cp->count); cp->AddFeederShare(share); this->feeder_share += share; cp->next_station = cargo_next; break; default: NOT_REACHED(); } this->action_counts[action] += cp->count; sum += cp->count; } this->AssertCountConsistency(); return this->action_counts[MTA_DELIVER] > 0 || this->action_counts[MTA_TRANSFER] > 0; }
/** * Build a path from #_path_builder xpos/ypos to the mouse cursor position. * @param mousexy Mouse position. */ void PathBuildManager::ComputeNewLongPath(const Point32 &mousexy) { static const TrackSlope slope_prios_down[] = {TSL_DOWN, TSL_FLAT, TSL_UP, TSL_INVALID}; // Order of preference when going down. static const TrackSlope slope_prios_flat[] = {TSL_FLAT, TSL_UP, TSL_DOWN, TSL_INVALID}; // Order of preference when at the right height. static const TrackSlope slope_prios_up[] = {TSL_UP, TSL_FLAT, TSL_DOWN, TSL_INVALID}; // Order of preference when going up. Viewport *vp = GetViewport(); if (vp == nullptr) return; int c1, c2, c3; switch (vp->orientation) { case VOR_NORTH: c1 = 1; c2 = 2; c3 = 2; break; case VOR_EAST: c1 = -1; c2 = -2; c3 = 2; break; case VOR_SOUTH: c1 = 1; c2 = -2; c3 = -2; break; case VOR_WEST: c1 = -1; c2 = 2; c3 = -2; break; default: NOT_REACHED(); } XYZPoint16 path_pos(0, 0, 0); path_pos.y = this->pos.y * 256 + 128; int32 lambda_y = path_pos.y - mousexy.y; // Distance to constant Y plane at current tile cursor. path_pos.x = this->pos.x * 256 + 128; int32 lambda_x = path_pos.x - mousexy.x; // Distance to constant X plane at current tile cursor. if (abs(lambda_x) < abs(lambda_y)) { /* X constant. */ path_pos.x /= 256; path_pos.y = Clamp<int32>(mousexy.y + c1 * lambda_x, 0, _world.GetYSize() * 256 - 1) / 256; path_pos.z = Clamp<int32>(vp->view_pos.z + c3 * lambda_x, 0, WORLD_Z_SIZE * 256 - 1) / 256; } else { /* Y constant. */ path_pos.x = Clamp<int32>(mousexy.x + c1 * lambda_y, 0, _world.GetXSize() * 256 - 1) / 256; path_pos.y /= 256; path_pos.z = Clamp<int32>(vp->view_pos.z + c2 * lambda_y, 0, WORLD_Z_SIZE * 256 - 1) / 256; } if (this->long_pos != path_pos) { this->long_pos = path_pos; _additions.Clear(); path_pos = this->pos; /* Find the right direction from the selected tile to the current cursor location. */ TileEdge direction; Point16 dxy; for (direction = EDGE_BEGIN; direction < EDGE_COUNT; direction++) { dxy = _tile_dxy[direction]; if (!GoodDirection(dxy.x, path_pos.x, this->long_pos.x) || !GoodDirection(dxy.y, path_pos.y, this->long_pos.y)) continue; break; } if (direction == EDGE_COUNT) return; /* 'Walk' to the cursor as long as possible. */ while (path_pos.x != this->long_pos.x || path_pos.y != this->long_pos.y) { uint8 slopes = CanBuildPathFromEdge(path_pos, direction); const TrackSlope *slope_prio; /* Get order of slope preference. */ if (path_pos.z > this->long_pos.z) { slope_prio = slope_prios_down; } else if (path_pos.z == this->long_pos.z) { slope_prio = slope_prios_flat; } else { slope_prio = slope_prios_up; } /* Find best slope, and take it. */ while (*slope_prio != TSL_INVALID && (slopes & (1 << *slope_prio)) == 0) slope_prio++; if (*slope_prio == TSL_INVALID) break; path_pos.x += dxy.x; path_pos.y += dxy.y; const Voxel *v = _world.GetVoxel(path_pos); if (v != nullptr && HasValidPath(v)) { if (!ChangePath(path_pos, this->path_type, false)) break; if (*slope_prio == TSL_UP) path_pos.z++; } else { if (*slope_prio == TSL_UP) { if (!BuildUpwardPath(path_pos, static_cast<TileEdge>((direction + 2) & 3), this->path_type, false)) break; path_pos.z++; } else if (*slope_prio == TSL_DOWN) { v = _world.GetVoxel(path_pos + XYZPoint16(0, 0, -1)); if (v != nullptr && HasValidPath(v)) { if (!ChangePath(path_pos + XYZPoint16(0, 0, -1), this->path_type, false)) break; } else { if (!BuildDownwardPath(path_pos, static_cast<TileEdge>((direction + 2) & 3), this->path_type, false)) break; } path_pos.z--; } else { if (!BuildFlatPath(path_pos, this->path_type, false)) break; } } } vp->EnableWorldAdditions(); vp->EnsureAdditionsAreVisible(); } }
static struct ring_msg * dmsg_parse(struct dmsg *dmsg) { //rstatus_t status; uint8_t *p, *q, *start, *end, *pipe_p; uint8_t *host_id, *host_addr, *ts, *node_state; uint32_t k, delimlen, host_id_len, host_addr_len, ts_len, node_state_len; char delim[] = ",,,"; delimlen = 3; /* parse "host_id1,generation_ts1,host_state1,host_broadcast_address1|host_id2,generation_ts2,host_state2,host_broadcast_address2" */ /* host_id = dc-rack-token */ //p = dmsg->data + dmsg->mlen - 1; //p = dmsg->owner->pos + dmsg->owner->mlen - 1; p = dmsg->payload + dmsg->plen - 1; end = p; //start = dmsg->data; //start = dmsg->owner->pos; start = dmsg->payload; log_debug(LOG_VERB, "parsing msg '%.*s'", dmsg->plen, start); host_id = NULL; host_addr = NULL; ts = NULL; node_state = NULL; host_id_len = 0; host_addr_len = 0; ts_len = 0; node_state_len = 0; pipe_p = start; int count = 0; do { q = dn_strrchr(p, start, '|'); count++; p = q - 1; } while (q != NULL); struct ring_msg *ring_msg = create_ring_msg_with_size(count, true); if (ring_msg == NULL) { log_debug(LOG_ERR, "Error: unable to create a new ring msg!"); //we just drop this msg return NULL; } struct server_pool *sp = (struct server_pool *) dmsg->owner->owner->owner; ring_msg->sp = sp; ring_msg->cb = gossip_msg_peer_update; count = 0; //p = dmsg->data + dmsg->mlen - 1; p = dmsg->payload + dmsg->plen - 1; do { for (k = 0; k < sizeof(delim)-1; k++) { q = dn_strrchr(p, start, delim[k]); switch (k) { case 0: host_addr = q + 1; host_addr_len = (uint32_t)(p - host_addr + 1); break; case 1: node_state = q + 1; node_state_len = (uint32_t)(p - node_state + 1); break; case 2: ts = q + 1; ts_len = (uint32_t)(p - ts + 1); break; default: NOT_REACHED(); } p = q - 1; } if (k != delimlen) { loga("Error: this is insanely bad"); return NULL;// DN_ERROR; } pipe_p = dn_strrchr(p, start, '|'); if (pipe_p == NULL) { pipe_p = start; } else { pipe_p = pipe_p + 1; p = pipe_p - 2; } //host_id = dmsg->data; //host_id_len = dmsg->mlen - (host_addr_len + node_state_len + ts_len + 3); host_id = pipe_p; host_id_len = end - pipe_p - (host_addr_len + node_state_len + ts_len + 3) + 1; end = p; #ifdef DN_DEBUG_LOG log_hexdump(LOG_VERB, host_id, host_id_len, "host_id: "); log_hexdump(LOG_VERB, ts, ts_len, "ts: "); log_hexdump(LOG_VERB, node_state, node_state_len, "state: "); log_hexdump(LOG_VERB, host_addr, host_addr_len, "host_addr: "); log_debug(LOG_VERB, "\t\t host_id : '%.*s'", host_id_len, host_id); log_debug(LOG_VERB, "\t\t ts : '%.*s'", ts_len, ts); log_debug(LOG_VERB, "\t\t node_state : '%.*s'", node_state_len, node_state); log_debug(LOG_VERB, "\t\t host_addr : '%.*s'", host_addr_len, host_addr); #endif struct node *rnode = (struct node *) array_get(&ring_msg->nodes, count); dmsg_parse_host_id(host_id, host_id_len, &rnode->dc, &rnode->rack, &rnode->token); #ifdef DN_DEBUG_LOG print_dyn_token(&rnode->token, 5); #endif string_copy(&rnode->name, host_addr, host_addr_len); string_copy(&rnode->pname, host_addr, host_addr_len); //need to add port rnode->port = sp->d_port; rnode->is_local = false; rnode->is_seed = false; ts[ts_len] = '\0'; rnode->ts = atol(ts); node_state[node_state_len] = '\0'; rnode->state = (uint8_t) atoi(node_state); count++; } while (pipe_p != start); //TODOs: should move this outside dmsg_to_gossip(ring_msg); return ring_msg; }
static bool dyn_parse_core(struct msg *r) { struct dmsg *dmsg; struct mbuf *b; uint8_t *p; uint8_t ch; uint64_t num = 0; state = r->dyn_state; b = STAILQ_LAST(&r->mhdr, mbuf, next); dmsg = r->dmsg; if (dmsg == NULL) { r->dmsg = dmsg_get(); dmsg = r->dmsg; if (dmsg == NULL) {//should track this as a dropped message goto error; //should count as OOM error } } //log_hexdump(LOG_VERB, b->pos, mbuf_length(b), "dyn parser: parsed req %"PRIu64" res %d type %d", r->id, r->result, r->type, r->dyn_state); for (p = r->pos; p < b->last; p++) { ch = *p; switch (state) { case DYN_START: //log_debug(LOG_DEBUG, "DYN_START"); if (ch == ' ') { break; } else if (isdigit(ch)) { num = ch - '0'; state = DYN_MAGIC_NUMBER; } else { goto skip; } break; case DYN_MAGIC_NUMBER: //log_debug(LOG_DEBUG, "DYN_MAGIC_NUMBER"); //log_debug(LOG_DEBUG, "num = %d", num); if (isdigit(ch)) { num = num*10 + (ch - '0'); } else { if (num == MAGIC_NUMBER) { state = DYN_SPACES_BEFORE_MSG_ID; } else { goto error; } } break; case DYN_SPACES_BEFORE_MSG_ID: //log_debug(LOG_DEBUG, "DYN_SPACES_BEFORE_MSG_ID"); if (ch == ' ') { break; } else if (isdigit(ch)) { num = ch - '0'; state = DYN_MSG_ID; } else { goto error; } break; case DYN_MSG_ID: log_debug(LOG_DEBUG, "DYN_MSG_ID"); log_debug(LOG_DEBUG, "num = %d", num); if (isdigit(ch)) { num = num*10 + (ch - '0'); } else if (ch != ' ') { goto error; } else { //if (num >= 0) { //log_debug(LOG_DEBUG, "MSG ID : %d", num); dmsg->id = num; state = DYN_SPACES_BEFORE_TYPE_ID; //} else { // goto error; //} } break; case DYN_SPACES_BEFORE_TYPE_ID: log_debug(LOG_DEBUG, "DYN_SPACES_BEFORE_TYPE_ID"); if (ch == ' ') { break; } else if (isdigit(ch)) { num = ch - '0'; state = DYN_TYPE_ID; } else { goto error; } break; case DYN_TYPE_ID: log_debug(LOG_DEBUG, "DYN_TYPE_ID"); log_debug(LOG_DEBUG, "num = %d", num); if (isdigit(ch)) { num = num*10 + (ch - '0'); } else { if (num > 0) { log_debug(LOG_DEBUG, "Type Id: %d", num); dmsg->type = num; //state = DYN_SPACES_BEFORE_VERSION; state = DYN_SPACES_BEFORE_BIT_FIELD; } else { goto error; } } break; case DYN_SPACES_BEFORE_BIT_FIELD: if (ch == ' ') { break; } else if (isdigit(ch)) { num = ch - '0'; state = DYN_BIT_FIELD; } else { goto error; } break; case DYN_BIT_FIELD: log_debug(LOG_DEBUG, "DYN_BIT_FIELD"); log_debug(LOG_DEBUG, "num = %d", num); if (isdigit(ch)) { num = num*10 + (ch - '0'); } else { if (ch == ' ') { log_debug(LOG_DEBUG, "DYN_BIT_FIELD : %d", num); dmsg->bit_field = num & 0xF; state = DYN_SPACES_BEFORE_VERSION; } else { goto error; } } log_debug(LOG_DEBUG, "Post DYN_BIT_FIELD"); log_debug(LOG_DEBUG, "num = %d", num); break; case DYN_SPACES_BEFORE_VERSION: log_debug(LOG_DEBUG, "DYN_SPACES_BEFORE_VERSION"); if (ch == ' ') { break; } else if (isdigit(ch)) { num = ch - '0'; state = DYN_VERSION; } else { goto error; } break; case DYN_VERSION: log_debug(LOG_DEBUG, "DYN_VERSION"); log_debug(LOG_DEBUG, "num = %d", num); if (isdigit(ch)) { num = num*10 + (ch - '0'); } else { if (ch == ' ') { //log_debug(LOG_DEBUG, "VERSION : %d", num); dmsg->version = num; state = DYN_SPACES_BEFORE_STAR; } else { goto error; } } break; case DYN_SPACES_BEFORE_STAR: //log_debug(LOG_DEBUG, "DYN_CRLF_BEFORE_STAR"); if (ch == ' ') { break; } else if (ch == '*') { state = DYN_DATA_LEN; num = 0; } else { goto error; } //else { // state = DYN_STAR; //} break; //case DYN_STAR: //log_debug(LOG_DEBUG, "DYN_STAR"); // if (ch == '*') { // state = DYN_DATA_LEN; // num = 0; // } else { // goto error; // } // break; case DYN_DATA_LEN: log_debug(LOG_DEBUG, "DYN_DATA_LEN"); log_debug(LOG_DEBUG, "num = %d", num); if (isdigit(ch)) { num = num*10 + (ch - '0'); } else { if (ch == ' ') { log_debug(LOG_DEBUG, "Data len: %d", num); dmsg->mlen = num; state = DYN_SPACE_BEFORE_DATA; num = 0; } else { goto error; } } break; case DYN_SPACE_BEFORE_DATA: log_debug(LOG_DEBUG, "DYN_SPACE_BEFORE_DATA"); state = DYN_DATA; break; case DYN_DATA: log_debug(LOG_DEBUG, "DYN_DATA"); p -= 1; if (dmsg->mlen > 0) { dmsg->data = p; p += dmsg->mlen - 1; state = DYN_SPACES_BEFORE_PAYLOAD_LEN; } else { goto error; } break; case DYN_SPACES_BEFORE_PAYLOAD_LEN: //this only need in dynomite's custome msg log_debug(LOG_DEBUG, "DYN_SPACES_BEFORE_PAYLOAD_LEN"); if (ch == ' ') { break; } else if (ch == '*') { state = DYN_PAYLOAD_LEN; num = 0; } else { goto error; } break; case DYN_PAYLOAD_LEN: if (isdigit(ch)) { num = num*10 + (ch - '0'); } else { if (ch == CR) { log_debug(LOG_DEBUG, "Payload len: %d", num); dmsg->plen = num; state = DYN_CRLF_BEFORE_DONE; num = 0; } else { goto error; } } break; case DYN_CRLF_BEFORE_DONE: //log_debug(LOG_DEBUG, "DYN_CRLF_BEFORE_DONE"); if (*p == LF) { state = DYN_DONE; } else { goto error; } break; case DYN_DONE: //log_debug(LOG_DEBUG, "DYN_DONE"); r->pos = p; dmsg->payload = p; r->dyn_state = DYN_DONE; b->pos = p; goto done; break; default: NOT_REACHED(); break; } } done: dmsg->owner = r; dmsg->source_address = r->owner->addr; //r->mlen = mbuf_length(b); //log_debug(LOG_DEBUG, "at done with p at %d", p); dmsg_dump(r->dmsg); log_hexdump(LOG_VERB, b->pos, mbuf_length(b), "dyn: parsed req %"PRIu64" res %d " "type %d state %d rpos %d of %d", r->id, r->result, r->type, r->dyn_state, r->pos - b->pos, b->last - b->pos); return true; skip: //log_debug(LOG_DEBUG, "This is not a dyn message"); dmsg->type = DMSG_UNKNOWN; dmsg->owner = r; dmsg->source_address = r->owner->addr; return true; error: log_debug(LOG_ERR, "at error"); r->result = MSG_PARSE_ERROR; r->state = state; errno = EINVAL; log_hexdump(LOG_INFO, b->pos, mbuf_length(b), "parsed bad req %"PRIu64" " "res %d type %d state %d", r->id, r->result, r->type, r->state); return false; return true; //fix me }
/** * Draw the details for the given vehicle at the given position * * @param v current vehicle * @param left The left most coordinate to draw * @param right The right most coordinate to draw * @param y The y coordinate * @param vscroll_pos Position of scrollbar * @param vscroll_cap Number of lines currently displayed * @param det_tab Selected details tab */ void DrawTrainDetails(const Train *v, int left, int right, int y, int vscroll_pos, uint16 vscroll_cap, TrainDetailsWindowTabs det_tab) { /* draw the first 3 details tabs */ if (det_tab != TDW_TAB_TOTALS) { bool rtl = _dynlang.text_dir == TD_RTL; Direction dir = rtl ? DIR_E : DIR_W; int x = rtl ? right : left; int sprite_y_offset = 4 + (FONT_HEIGHT_NORMAL - 10) / 2; int line_height = WD_MATRIX_TOP + FONT_HEIGHT_NORMAL + WD_MATRIX_BOTTOM; for (; v != NULL && vscroll_pos > -vscroll_cap; v = v->GetNextVehicle()) { GetCargoSummaryOfArticulatedVehicle(v, &_cargo_summary); /* Draw sprites */ int dx = 0; int px = x; const Train *u = v; do { Point offset; int width = u->GetDisplayImageWidth(&offset); if (vscroll_pos <= 0 && vscroll_pos > -vscroll_cap) { SpriteID pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v); DrawSprite(u->GetImage(dir), pal, px + (rtl ? -offset.x : offset.x), y - line_height * vscroll_pos + sprite_y_offset + offset.y); } px += rtl ? -width : width; dx += width; u = u->Next(); } while (u != NULL && u->IsArticulatedPart()); bool separate_sprite_row = (dx > TRAIN_DETAILS_MAX_INDENT); if (separate_sprite_row) { vscroll_pos--; dx = 0; } uint num_lines = max(1u, _cargo_summary.Length()); for (uint i = 0; i < num_lines; i++) { int sprite_width = max<int>(dx, TRAIN_DETAILS_MIN_INDENT) + 3; int data_left = left + (rtl ? 0 : sprite_width); int data_right = right - (rtl ? sprite_width : 0); if (vscroll_pos <= 0 && vscroll_pos > -vscroll_cap) { int py = y - line_height * vscroll_pos; if (i > 0 || separate_sprite_row) { if (vscroll_pos != 0) GfxFillRect(left, py - WD_MATRIX_TOP - 1, right, py - WD_MATRIX_TOP, _colour_gradient[COLOUR_GREY][5]); } switch (det_tab) { case TDW_TAB_CARGO: if (i < _cargo_summary.Length()) { TrainDetailsCargoTab(&_cargo_summary[i], data_left, data_right, py); } else { DrawString(data_left, data_right, py, STR_QUANTITY_N_A, TC_LIGHT_BLUE); } break; case TDW_TAB_INFO: if (i == 0) TrainDetailsInfoTab(v, data_left, data_right, py); break; case TDW_TAB_CAPACITY: if (i < _cargo_summary.Length()) { TrainDetailsCapacityTab(&_cargo_summary[i], data_left, data_right, py); } else { DrawString(data_left, data_right, py, STR_VEHICLE_INFO_NO_CAPACITY); } break; default: NOT_REACHED(); } } vscroll_pos--; } } } else { CargoArray act_cargo; CargoArray max_cargo; Money feeder_share = 0; for (const Vehicle *u = v; u != NULL; u = u->Next()) { act_cargo[u->cargo_type] += u->cargo.Count(); max_cargo[u->cargo_type] += u->cargo_cap; feeder_share += u->cargo.FeederShare(); } /* draw total cargo tab */ DrawString(left, right, y, STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_TEXT); y += WD_MATRIX_TOP + FONT_HEIGHT_NORMAL + WD_MATRIX_BOTTOM; for (CargoID i = 0; i < NUM_CARGO; i++) { if (max_cargo[i] > 0 && --vscroll_pos < 0 && vscroll_pos > -vscroll_cap) { SetDParam(0, i); // {CARGO} #1 SetDParam(1, act_cargo[i]); // {CARGO} #2 SetDParam(2, i); // {SHORTCARGO} #1 SetDParam(3, max_cargo[i]); // {SHORTCARGO} #2 SetDParam(4, _settings_game.vehicle.freight_trains); DrawString(left, right, y, FreightWagonMult(i) > 1 ? STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_MULT : STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY); y += WD_MATRIX_TOP + FONT_HEIGHT_NORMAL + WD_MATRIX_BOTTOM; } } SetDParam(0, feeder_share); DrawString(left, right, y, STR_VEHICLE_INFO_FEEDER_CARGO_VALUE); } }
Bool FileIO_AtomicUpdate(FileIODescriptor *newFD, // IN/OUT: file IO descriptor FileIODescriptor *currFD) // IN/OUT: file IO descriptor { char *currPath = NULL; char *newPath = NULL; #if defined(_WIN32) uint32 currAccess; uint32 newAccess; FileIOResult status; FileIODescriptor tmpFD; #else int fd; #endif int savedErrno = 0; Bool ret = FALSE; ASSERT(FileIO_IsValid(newFD)); ASSERT(FileIO_IsValid(currFD)); if (HostType_OSIsVMK()) { #if defined(VMX86_SERVER) FS_SwapFilesArgs *args = NULL; char *dirName = NULL; char *fileName = NULL; char *dstDirName = NULL; char *dstFileName = NULL; currPath = File_FullPath(FileIO_Filename(currFD)); if (!currPath) { savedErrno = errno; Log("%s: File_FullPath of '%s' failed.\n", __FUNCTION__, FileIO_Filename(currFD)); goto swapdone; } newPath = File_FullPath(FileIO_Filename(newFD)); if (!newPath) { savedErrno = errno; Log("%s: File_FullPath of '%s' failed.\n", __FUNCTION__, FileIO_Filename(newFD)); goto swapdone; } File_GetPathName(newPath, &dirName, &fileName); File_GetPathName(currPath, &dstDirName, &dstFileName); ASSERT(dirName && *dirName); ASSERT(fileName && *fileName); ASSERT(dstDirName && *dstDirName); ASSERT(dstFileName && *dstFileName); ASSERT(!strcmp(dirName, dstDirName)); args = (FS_SwapFilesArgs *) Util_SafeCalloc(1, sizeof(*args)); if (Str_Snprintf(args->srcFile, sizeof(args->srcFile), "%s", fileName) < 0) { Log("%s: Path too long \"%s\".\n", __FUNCTION__, fileName); savedErrno = ENAMETOOLONG; goto swapdone; } if (Str_Snprintf(args->dstFilePath, sizeof(args->dstFilePath), "%s/%s", dstDirName, dstFileName) < 0) { Log("%s: Path too long \"%s\".\n", __FUNCTION__, dstFileName); savedErrno = ENAMETOOLONG; goto swapdone; } /* * Issue the ioctl on the directory rather than on the file, * because the file could be open. */ fd = Posix_Open(dirName, O_RDONLY); if (fd < 0) { Log("%s: Open failed \"%s\" %d.\n", __FUNCTION__, dirName, errno); ASSERT(errno != EBUSY); /* #615124. */ savedErrno = errno; goto swapdone; } if (ioctl(fd, IOCTLCMD_VMFS_SWAP_FILES, args) != 0) { savedErrno = errno; if (errno != ENOSYS && errno != ENOTTY) { Log("%s: ioctl failed %d.\n", __FUNCTION__, errno); ASSERT(errno != EBUSY); /* #615124. */ } } else { ret = TRUE; } close(fd); /* * Did we fail because we are on a file system that does not * support the IOCTLCMD_VMFS_SWAP_FILES ioctl? If so fallback to * using rename. * * Check for both ENOSYS and ENOTTY. PR 957695 */ if (savedErrno == ENOSYS || savedErrno == ENOTTY) { /* * NFS allows renames of locked files, even if both files * are locked. The file lock follows the file handle, not * the name, so after the rename we can swap the underlying * file descriptors instead of closing and reopening the * target file. * * This is different than the hosted path below because * ESX uses native file locks and hosted does not. * * We assume that all ESX file systems that support rename * have the same file lock semantics as NFS. */ if (File_Rename(newPath, currPath)) { Log("%s: rename of '%s' to '%s' failed %d.\n", __FUNCTION__, newPath, currPath, errno); savedErrno = errno; goto swapdone; } ret = TRUE; fd = newFD->posix; newFD->posix = currFD->posix; currFD->posix = fd; FileIO_Close(newFD); } swapdone: free(args); free(dirName); free(fileName); free(dstDirName); free(dstFileName); free(currPath); free(newPath); errno = savedErrno; return ret; #else NOT_REACHED(); #endif } #if defined(_WIN32) currPath = Unicode_Duplicate(FileIO_Filename(currFD)); newPath = Unicode_Duplicate(FileIO_Filename(newFD)); newAccess = newFD->flags; currAccess = currFD->flags; FileIO_Close(newFD); /* * The current file needs to be closed and reopened, * but we don't want to drop the file lock by calling * FileIO_Close() on it. Instead, use native close primitives. * We'll reopen it later with FileIO_Open. Set the * descriptor/handle to an invalid value while we're in the * middle of transferring ownership. */ CloseHandle(currFD->win32); currFD->win32 = INVALID_HANDLE_VALUE; if (File_RenameRetry(newPath, currPath, 10) == 0) { ret = TRUE; } else { savedErrno = errno; ASSERT(!ret); } FileIO_Invalidate(&tmpFD); /* * Clear the locking bits from the requested access so that reopening * the file ignores the advisory lock. */ ASSERT((currAccess & FILEIO_OPEN_LOCK_MANDATORY) == 0); currAccess &= ~(FILEIO_OPEN_LOCK_MANDATORY | FILEIO_OPEN_LOCK_ADVISORY | FILEIO_OPEN_LOCK_BEST | FILEIO_OPEN_LOCKED); status = FileIO_Open(&tmpFD, currPath, currAccess, FILEIO_OPEN); if (!FileIO_IsSuccess(status)) { Panic("Failed to reopen dictionary after renaming " "\"%s\" to \"%s\": %s (%d)\n", newPath, currPath, FileIO_ErrorEnglish(status), status); } ASSERT(tmpFD.lockToken == NULL); currFD->win32 = tmpFD.win32; FileIO_Cleanup(&tmpFD); Unicode_Free(currPath); Unicode_Free(newPath); errno = savedErrno; return ret; #else currPath = (char *)FileIO_Filename(currFD); newPath = (char *)FileIO_Filename(newFD); if (File_Rename(newPath, currPath)) { Log("%s: rename of '%s' to '%s' failed %d.\n", __FUNCTION__, newPath, currPath, errno); savedErrno = errno; } else { ret = TRUE; fd = newFD->posix; newFD->posix = currFD->posix; currFD->posix = fd; FileIO_Close(newFD); } errno = savedErrno; return ret; #endif }
int event_wait(struct event_base *evb, int timeout) { int ep = evb->ep; struct epoll_event *event = evb->event; int nevent = evb->nevent; ASSERT(ep > 0); ASSERT(event != NULL); ASSERT(nevent > 0); for (;;) { int i, nsd; nsd = epoll_wait(ep, event, nevent, timeout); if (nsd > 0) { for (i = 0; i < nsd; i++) { struct epoll_event *ev = &evb->event[i]; uint32_t events = 0; log_debug(LOG_VVERB, "epoll %04"PRIX32" triggered on conn %p", ev->events, ev->data.ptr); if (ev->events & EPOLLERR) { events |= EVENT_ERR; } if (ev->events & (EPOLLIN | EPOLLHUP)) { events |= EVENT_READ; } if (ev->events & EPOLLOUT) { events |= EVENT_WRITE; } if (evb->cb != NULL) { evb->cb(ev->data.ptr, events); } } return nsd; } if (nsd == 0) { if (timeout == -1) { log_error("epoll wait on e %d with %d events and %d timeout " "returned no events", ep, nevent, timeout); return -1; } return 0; } if (errno == EINTR) { continue; } log_error("epoll wait on e %d with %d events failed: %s", ep, nevent, strerror(errno)); return -1; } NOT_REACHED(); }
bool operands_equal(operand_t const *op1, operand_t const *op2) { if (op1->type != op2->type) { return false; } if (op1->size != op2->size) { return false; } if (op1->type == invalid) { return true; } switch (op1->type) { case op_reg: return ( op1->val.reg == op2->val.reg && op1->tag.reg == op2->tag.reg); case op_seg: return ( op1->val.seg == op2->val.seg && op1->tag.seg == op2->tag.seg); case op_mem: return ( op1->val.mem.segtype == op2->val.mem.segtype && op1->val.mem.seg.all == op2->val.mem.seg.all && op1->val.mem.base == op2->val.mem.base && op1->val.mem.scale == op2->val.mem.scale && op1->val.mem.index == op2->val.mem.index && op1->val.mem.disp == op2->val.mem.disp && op1->tag.mem.seg.all == op2->tag.mem.seg.all && op1->tag.mem.all == op2->tag.mem.all && op1->tag.mem.base == op2->tag.mem.base && op1->tag.mem.index == op2->tag.mem.index && op1->tag.mem.disp == op2->tag.mem.disp); case op_imm: /* All tag_const imm operands should have 0 size. */ ASSERT(op1->tag.imm != tag_const || op1->size == 0); ASSERT(op2->tag.imm != tag_const || op2->size == 0); return ( op1->val.imm == op2->val.imm && op1->tag.imm == op2->tag.imm); case op_pcrel: /* All tag_const pcrel operands should have 0 size. */ ASSERT(0); ASSERT(op1->tag.pcrel != tag_const || op1->size == 0); ASSERT(op2->tag.pcrel != tag_const || op2->size == 0); return ( op1->val.pcrel == op2->val.pcrel && op1->tag.pcrel == op2->tag.pcrel); case op_cr: return ( op1->val.cr == op2->val.cr && op1->tag.cr == op2->tag.cr); case op_db: return ( op1->val.db == op2->val.db && op1->tag.db == op2->tag.db); case op_tr: return ( op1->val.tr == op2->val.tr && op1->tag.tr == op2->tag.tr); case op_mmx: return ( op1->val.mmx == op2->val.mmx && op1->tag.mmx == op2->tag.mmx); case op_xmm: return ( op1->val.xmm == op2->val.xmm && op1->tag.xmm == op2->tag.xmm); case op_3dnow: return ( op1->val.d3now == op2->val.d3now && op1->tag.d3now == op2->tag.d3now); case op_prefix: return ( op1->val.prefix == op2->val.prefix && op1->tag.prefix == op2->tag.prefix); case op_st: case invalid: NOT_REACHED(); } ASSERT(0); return false; }
static int ssl_connect(struct stream *stream) { struct ssl_stream *sslv = ssl_stream_cast(stream); int retval; switch (sslv->state) { case STATE_TCP_CONNECTING: retval = check_connection_completion(sslv->fd); if (retval) { return retval; } sslv->state = STATE_SSL_CONNECTING; /* Fall through. */ case STATE_SSL_CONNECTING: /* Capture the first few bytes of received data so that we can guess * what kind of funny data we've been sent if SSL negotation fails. */ if (sslv->n_head <= 0) { sslv->n_head = recv(sslv->fd, sslv->head, sizeof sslv->head, MSG_PEEK); } retval = (sslv->type == CLIENT ? SSL_connect(sslv->ssl) : SSL_accept(sslv->ssl)); if (retval != 1) { int error = SSL_get_error(sslv->ssl, retval); if (retval < 0 && ssl_wants_io(error)) { return EAGAIN; } else { int unused; interpret_ssl_error((sslv->type == CLIENT ? "SSL_connect" : "SSL_accept"), retval, error, &unused); shutdown(sslv->fd, SHUT_RDWR); stream_report_content(sslv->head, sslv->n_head, STREAM_SSL, THIS_MODULE, stream_get_name(stream)); return EPROTO; } } else if (bootstrap_ca_cert) { return do_ca_cert_bootstrap(stream); } else if (verify_peer_cert && ((SSL_get_verify_mode(sslv->ssl) & (SSL_VERIFY_NONE | SSL_VERIFY_PEER)) != SSL_VERIFY_PEER)) { /* Two or more SSL connections completed at the same time while we * were in bootstrap mode. Only one of these can finish the * bootstrap successfully. The other one(s) must be rejected * because they were not verified against the bootstrapped CA * certificate. (Alternatively we could verify them against the CA * certificate, but that's more trouble than it's worth. These * connections will succeed the next time they retry, assuming that * they have a certificate against the correct CA.) */ VLOG_INFO("rejecting SSL connection during bootstrap race window"); return EPROTO; } else { return 0; } } NOT_REACHED(); }
/** * Add the remaining articulated parts to the given vehicle. * @param first The head of the articulated bit. */ void AddArticulatedParts(Vehicle *first) { VehicleType type = first->type; if (!HasBit(EngInfo(first->engine_type)->callback_mask, CBM_VEHICLE_ARTIC_ENGINE)) return; Vehicle *v = first; for (uint i = 1; i < MAX_ARTICULATED_PARTS; i++) { bool flip_image; EngineID engine_type = GetNextArticulatedPart(i, first->engine_type, first, &flip_image); if (engine_type == INVALID_ENGINE) return; /* In the (very rare) case the GRF reported wrong number of articulated parts * and we run out of available vehicles, bail out. */ if (!Vehicle::CanAllocateItem()) return; GroundVehicleCache *gcache = v->GetGroundVehicleCache(); gcache->first_engine = v->engine_type; // Needs to be set before first callback const Engine *e_artic = Engine::Get(engine_type); switch (type) { default: NOT_REACHED(); case VEH_TRAIN: { Train *front = Train::From(first); Train *t = new Train(); v->SetNext(t); v = t; t->subtype = 0; t->track = front->track; t->railtype = front->railtype; t->spritenum = e_artic->u.rail.image_index; if (e_artic->CanCarryCargo()) { t->cargo_type = e_artic->GetDefaultCargoType(); t->cargo_cap = e_artic->u.rail.capacity; // Callback 36 is called when the consist is finished } else { t->cargo_type = front->cargo_type; // Needed for livery selection t->cargo_cap = 0; } t->SetArticulatedPart(); break; } case VEH_ROAD: { RoadVehicle *front = RoadVehicle::From(first); RoadVehicle *rv = new RoadVehicle(); v->SetNext(rv); v = rv; rv->subtype = 0; gcache->cached_veh_length = VEHICLE_LENGTH; // Callback is called when the consist is finished rv->state = RVSB_IN_DEPOT; rv->roadtype = front->roadtype; rv->compatible_roadtypes = front->compatible_roadtypes; rv->spritenum = e_artic->u.road.image_index; if (e_artic->CanCarryCargo()) { rv->cargo_type = e_artic->GetDefaultCargoType(); rv->cargo_cap = e_artic->u.road.capacity; // Callback 36 is called when the consist is finished } else { rv->cargo_type = front->cargo_type; // Needed for livery selection rv->cargo_cap = 0; } rv->SetArticulatedPart(); break; } } /* get common values from first engine */ v->direction = first->direction; v->owner = first->owner; v->tile = first->tile; v->x_pos = first->x_pos; v->y_pos = first->y_pos; v->z_pos = first->z_pos; v->build_year = first->build_year; v->vehstatus = first->vehstatus & ~VS_STOPPED; v->cargo_subtype = 0; v->max_age = 0; v->engine_type = engine_type; v->value = 0; v->cur_image = SPR_IMG_QUERY; v->random_bits = VehicleRandomBits(); if (flip_image) v->spritenum++; VehicleMove(v, false); } }
struct conn * conn_get(void *owner, bool client, unsigned source_type, struct conn_base *cb) { struct conn *conn; conn = _conn_get(cb); if (conn == NULL) { return NULL; } /* this connection either handles redis or memcache messages */ if (source_type == NC_SOURCE_TYPE_REDIS) { conn->source_type = NC_SOURCE_TYPE_REDIS; } else if (source_type == NC_SOURCE_TYPE_PROXY) { conn->source_type = NC_SOURCE_TYPE_PROXY; } else if (source_type == NC_SOURCE_TYPE_MC) { conn->source_type = NC_SOURCE_TYPE_MC; } else { NOT_REACHED(); } conn->client = client ? 1 : 0; if (conn->client) { /* * client receives a request, possibly parsing it, and sends a * response downstream. */ conn->recv = msg_recv; conn->recv_next = req_recv_next; conn->recv_done = req_recv_done; conn->send = msg_send; conn->send_next = rsp_send_next; conn->send_done = rsp_send_done; conn->close = client_close; conn->active = client_active; conn->ref = client_ref; conn->unref = client_unref; conn->enqueue_inq = NULL; conn->dequeue_inq = NULL; conn->enqueue_outq = req_client_enqueue_omsgq; conn->dequeue_outq = req_client_dequeue_omsgq; conn->post_connect = NULL; conn->swallow_msg = NULL; if (cb) cb->ncurr_cconn++; STATS_LOCK(); ncurr_cconn ++; STATS_UNLOCK(); } else { /* * server receives a response, possibly parsing it, and sends a * request upstream. */ conn->recv = msg_recv; conn->recv_next = rsp_recv_next; conn->recv_done = rsp_recv_done; conn->send = msg_send; conn->send_next = req_send_next; conn->send_done = req_send_done; conn->close = server_close; conn->active = server_active; conn->ref = server_ref; conn->unref = server_unref; conn->enqueue_inq = req_server_enqueue_imsgq; conn->dequeue_inq = req_server_dequeue_imsgq; conn->enqueue_outq = req_server_enqueue_omsgq; conn->dequeue_outq = req_server_dequeue_omsgq; if (source_type == NC_SOURCE_TYPE_REDIS) { conn->post_connect = redis_post_connect; conn->swallow_msg = redis_swallow_msg; } else { conn->post_connect = memcache_post_connect; conn->swallow_msg = memcache_swallow_msg; } } if (source_type == NC_SOURCE_TYPE_PROXY) { } conn->ref(conn, owner); log_debug(LOG_VVERB, "get conn %p client %d", conn, conn->client); return conn; }
/* Reads a record from a disk file into R. Returns true if successful, false on error or at end of file. */ static bool read_file_record (struct dfm_reader *r) { assert (r->fh != fh_inline_file ()); ds_clear (&r->line); switch (fh_get_mode (r->fh)) { case FH_MODE_TEXT: if (ds_read_line (&r->line, r->file, SIZE_MAX)) { ds_chomp_byte (&r->line, '\n'); return true; } else { if (ferror (r->file)) read_error (r); return false; } case FH_MODE_FIXED: if (ds_read_stream (&r->line, 1, fh_get_record_width (r->fh), r->file)) return true; else { if (ferror (r->file)) read_error (r); else if (!ds_is_empty (&r->line)) partial_record (r); return false; } case FH_MODE_VARIABLE: { size_t leading_size; size_t trailing_size; int status; /* Read leading record size. */ status = read_size (r, &leading_size); if (status <= 0) return false; /* Read record data. */ if (!ds_read_stream (&r->line, leading_size, 1, r->file)) { if (ferror (r->file)) read_error (r); else partial_record (r); return false; } /* Read trailing record size and check that it's the same as the leading record size. */ status = read_size (r, &trailing_size); if (status <= 0) { if (status == 0) partial_record (r); return false; } if (leading_size != trailing_size) { corrupt_size (r); return false; } return true; } case FH_MODE_360_VARIABLE: case FH_MODE_360_SPANNED: for (;;) { size_t record_size; int segment; int status; /* If we've exhausted our current block, start another one by reading the new block descriptor word. */ if (r->block_left == 0) { status = read_descriptor_word (r, BLOCK, &r->block_left, NULL); if (status < 0) return false; else if (status == 0) return !ds_is_empty (&r->line); } /* Read record descriptor. */ if (r->block_left < 4) { partial_record (r); return false; } r->block_left -= 4; status = read_descriptor_word (r, RECORD, &record_size, &segment); if (status <= 0) { if (status == 0) partial_record (r); return false; } if (record_size > r->block_left) { msg (ME, _("Record exceeds remaining block length.")); return false; } /* Read record data. */ if (!ds_read_stream (&r->line, record_size, 1, r->file)) { if (ferror (r->file)) read_error (r); else partial_record (r); return false; } r->block_left -= record_size; /* In variable mode, read only a single record. In spanned mode, a segment value of 0 should designate a whole record without spanning, 1 the first segment in a record, 2 the last segment in a record, and 3 an intermediate segment in a record. For compatibility, though, we actually pay attention only to whether the segment value is even or odd. */ if (fh_get_mode (r->fh) == FH_MODE_360_VARIABLE || (segment & 1) == 0) return true; } } NOT_REACHED (); }
void memcache_parse_rsp(struct msg *r) { struct mbuf *b; uint8_t *p, *m; uint8_t ch; enum { SW_START, SW_RSP_NUM, SW_RSP_STR, SW_SPACES_BEFORE_KEY, SW_KEY, SW_SPACES_BEFORE_FLAGS, SW_FLAGS, SW_SPACES_BEFORE_VLEN, SW_VLEN, SW_RUNTO_VAL, SW_VAL, SW_VAL_LF, SW_END, SW_RUNTO_CRLF, SW_CRLF, SW_ALMOST_DONE, SW_SENTINEL } state; state = r->state; b = STAILQ_LAST(&r->mhdr, mbuf, next); ASSERT(!r->request); ASSERT(r->protocol == MEMCACHE_ASCII); ASSERT(state >= SW_START && state < SW_SENTINEL); ASSERT(b != NULL); ASSERT(b->pos <= b->last); /* validate the parsing marker */ ASSERT(r->pos != NULL); ASSERT(r->pos >= b->pos && r->pos <= b->last); for (p = r->pos; p < b->last; p++) { ch = *p; switch (state) { case SW_START: if (isdigit(ch)) { state = SW_RSP_NUM; } else { state = SW_RSP_STR; } p = p - 1; /* go back by 1 byte */ break; case SW_RSP_NUM: if (r->token == NULL) { /* rsp_start <- p; type_start <- p */ r->token = p; } if (isdigit(ch)) { /* num <- num * 10 + (ch - '0') */ ; } else if (ch == ' ' || ch == CR) { /* type_end <- p - 1 */ r->token = NULL; r->type = MSG_RSP_MC_NUM; p = p - 1; /* go back by 1 byte */ state = SW_CRLF; } else { goto error; } break; case SW_RSP_STR: if (r->token == NULL) { /* rsp_start <- p; type_start <- p */ r->token = p; } if (ch == ' ' || ch == CR) { /* type_end <- p - 1 */ m = r->token; r->token = NULL; r->type = MSG_UNKNOWN; switch (p - m) { case 3: if (str4cmp(m, 'E', 'N', 'D', '\r')) { r->type = MSG_RSP_MC_END; /* end_start <- m; end_end <- p - 1*/ r->end = m; break; } break; case 5: if (str5cmp(m, 'V', 'A', 'L', 'U', 'E')) { /* * Encompasses responses for 'get', 'gets' and * 'cas' command. */ r->type = MSG_RSP_MC_VALUE; break; } if (str5cmp(m, 'E', 'R', 'R', 'O', 'R')) { r->type = MSG_RSP_MC_ERROR; break; } break; case 6: if (str6cmp(m, 'S', 'T', 'O', 'R', 'E', 'D')) { r->type = MSG_RSP_MC_STORED; break; } if (str6cmp(m, 'E', 'X', 'I', 'S', 'T', 'S')) { r->type = MSG_RSP_MC_EXISTS; break; } break; case 7: if (str7cmp(m, 'D', 'E', 'L', 'E', 'T', 'E', 'D')) { r->type = MSG_RSP_MC_DELETED; break; } break; case 9: if (str9cmp(m, 'N', 'O', 'T', '_', 'F', 'O', 'U', 'N', 'D')) { r->type = MSG_RSP_MC_NOT_FOUND; break; } break; case 10: if (str10cmp(m, 'N', 'O', 'T', '_', 'S', 'T', 'O', 'R', 'E', 'D')) { r->type = MSG_RSP_MC_NOT_STORED; break; } break; case 12: if (str12cmp(m, 'C', 'L', 'I', 'E', 'N', 'T', '_', 'E', 'R', 'R', 'O', 'R')) { r->type = MSG_RSP_MC_CLIENT_ERROR; break; } if (str12cmp(m, 'S', 'E', 'R', 'V', 'E', 'R', '_', 'E', 'R', 'R', 'O', 'R')) { r->type = MSG_RSP_MC_SERVER_ERROR; break; } break; } switch (r->type) { case MSG_UNKNOWN: goto error; case MSG_RSP_MC_STORED: case MSG_RSP_MC_NOT_STORED: case MSG_RSP_MC_EXISTS: case MSG_RSP_MC_NOT_FOUND: case MSG_RSP_MC_DELETED: state = SW_CRLF; break; case MSG_RSP_MC_END: state = SW_CRLF; break; case MSG_RSP_MC_VALUE: state = SW_SPACES_BEFORE_KEY; break; case MSG_RSP_MC_ERROR: state = SW_CRLF; break; case MSG_RSP_MC_CLIENT_ERROR: case MSG_RSP_MC_SERVER_ERROR: state = SW_RUNTO_CRLF; break; default: NOT_REACHED(); } p = p - 1; /* go back by 1 byte */ } break; case SW_SPACES_BEFORE_KEY: if (ch != ' ') { state = SW_KEY; p = p - 1; /* go back by 1 byte */ } break; case SW_KEY: if (r->token == NULL) { r->token = p; r->key_start = p; } if (ch == ' ') { if ((p - r->key_start) > MEMCACHE_MAX_KEY_LENGTH) { log_error("parsed bad req %"PRIu64" of type %d with key " "prefix '%.*s...' and length %d that exceeds " "maximum key length", r->id, r->type, 16, r->key_start, p - r->key_start); goto error; } r->key_end = p; r->token = NULL; state = SW_SPACES_BEFORE_FLAGS; } break; case SW_SPACES_BEFORE_FLAGS: if (ch != ' ') { if (!isdigit(ch)) { goto error; } state = SW_FLAGS; p = p - 1; /* go back by 1 byte */ } break; case SW_FLAGS: if (r->token == NULL) { /* flags_start <- p */ r->token = p; } if (isdigit(ch)) { /* flags <- flags * 10 + (ch - '0') */ ; } else if (ch == ' ') { /* flags_end <- p - 1 */ r->token = NULL; state = SW_SPACES_BEFORE_VLEN; } else { goto error; } break; case SW_SPACES_BEFORE_VLEN: if (ch != ' ') { if (!isdigit(ch)) { goto error; } p = p - 1; /* go back by 1 byte */ state = SW_VLEN; } break; case SW_VLEN: if (r->token == NULL) { /* vlen_start <- p */ r->token = p; r->vlen = (uint32_t)(ch - '0'); } else if (isdigit(ch)) { r->vlen = r->vlen * 10 + (uint32_t)(ch - '0'); } else if (ch == ' ' || ch == CR) { /* vlen_end <- p - 1 */ p = p - 1; /* go back by 1 byte */ r->token = NULL; state = SW_RUNTO_CRLF; } else { goto error; } break; case SW_RUNTO_VAL: switch (ch) { case LF: /* val_start <- p + 1 */ state = SW_VAL; break; default: goto error; } break; case SW_VAL: m = p + r->vlen; if (m >= b->last) { ASSERT(r->vlen >= (uint32_t)(b->last - p)); r->vlen -= (uint32_t)(b->last - p); m = b->last - 1; p = m; /* move forward by vlen bytes */ break; } switch (*m) { case CR: /* val_end <- p - 1 */ p = m; /* move forward by vlen bytes */ state = SW_VAL_LF; break; default: goto error; } break; case SW_VAL_LF: switch (ch) { case LF: state = SW_END; break; default: goto error; } break; case SW_END: if (r->token == NULL) { if (ch != 'E') { goto error; } /* end_start <- p */ r->token = p; } else if (ch == CR) { /* end_end <- p */ m = r->token; r->token = NULL; switch (p - m) { case 3: if (str4cmp(m, 'E', 'N', 'D', '\r')) { r->end = m; state = SW_ALMOST_DONE; } break; default: goto error; } } break; case SW_RUNTO_CRLF: switch (ch) { case CR: if (r->type == MSG_RSP_MC_VALUE) { state = SW_RUNTO_VAL; } else { state = SW_ALMOST_DONE; } break; default: break; } break; case SW_CRLF: switch (ch) { case ' ': break; case CR: state = SW_ALMOST_DONE; break; default: goto error; } break; case SW_ALMOST_DONE: switch (ch) { case LF: /* rsp_end <- p */ goto done; default: goto error; } break; case SW_SENTINEL: default: NOT_REACHED(); break; } } ASSERT(p == b->last); r->pos = p; r->state = state; if (b->last == b->end && r->token != NULL) { r->pos = r->token; r->token = NULL; r->result = MSG_PARSE_REPAIR; } else { r->result = MSG_PARSE_AGAIN; } log_hexdump(LOG_VERB, b->pos, mbuf_length(b), "parsed rsp %"PRIu64" res %d " "type %d state %d rpos %d of %d", r->id, r->result, r->type, r->state, r->pos - b->pos, b->last - b->pos); return; done: ASSERT(r->type > MSG_UNKNOWN && r->type < MSG_SENTINEL); r->pos = p + 1; ASSERT(r->pos <= b->last); r->state = SW_START; r->token = NULL; r->result = MSG_PARSE_OK; log_hexdump(LOG_VERB, b->pos, mbuf_length(b), "parsed rsp %"PRIu64" res %d " "type %d state %d rpos %d of %d", r->id, r->result, r->type, r->state, r->pos - b->pos, b->last - b->pos); return; error: r->result = MSG_PARSE_ERROR; r->state = state; errno = EINVAL; log_hexdump(LOG_INFO, b->pos, mbuf_length(b), "parsed bad rsp %"PRIu64" " "res %d type %d state %d", r->id, r->result, r->type, r->state); }
char * conf_add_server(struct conf *cf, struct command *cmd, void *conf) { rstatus_t status; struct array *a; struct string *value; struct conf_server *field; uint8_t *p, *q, *start; uint8_t *pname, *addr, *port, *weight, *name; uint32_t k, delimlen, pnamelen, addrlen, portlen, weightlen, namelen; char delim[] = " ::"; p = conf; a = (struct array *)(p + cmd->offset); field = array_push(a); if (field == NULL) { return CONF_ERROR; } conf_server_init(field); value = array_top(&cf->arg); /* parse "hostname:port:weight [name]" or "/path/unix_socket:weight [name]" from the end */ p = value->data + value->len - 1; start = value->data; addr = NULL; addrlen = 0; weight = NULL; weightlen = 0; port = NULL; portlen = 0; name = NULL; namelen = 0; delimlen = value->data[0] == '/' ? 2 : 3; for (k = 0; k < sizeof(delim); k++) { q = nc_strrchr(p, start, delim[k]); if (q == NULL) { if (k == 0) { /* * name in "hostname:port:weight [name]" format string is * optional */ continue; } break; } switch (k) { case 0: name = q + 1; namelen = (uint32_t)(p - name + 1); break; case 1: weight = q + 1; weightlen = (uint32_t)(p - weight + 1); break; case 2: port = q + 1; portlen = (uint32_t)(p - port + 1); break; default: NOT_REACHED(); } p = q - 1; } if (k != delimlen) { return "has an invalid \"hostname:port:weight [name]\"or \"/path/unix_socket:weight [name]\" format string"; } pname = value->data; pnamelen = namelen > 0 ? value->len - (namelen + 1) : value->len; status = string_copy(&field->pname, pname, pnamelen); if (status != NC_OK) { array_pop(a); return CONF_ERROR; } addr = start; addrlen = (uint32_t)(p - start + 1); field->weight = nc_atoi(weight, weightlen); if (field->weight < 0) { return "has an invalid weight in \"hostname:port:weight [name]\" format string"; } else if (field->weight == 0) { return "has a zero weight in \"hostname:port:weight [name]\" format string"; } if (value->data[0] != '/') { field->port = nc_atoi(port, portlen); if (field->port < 0 || !nc_valid_port(field->port)) { return "has an invalid port in \"hostname:port:weight [name]\" format string"; } } if (name == NULL) { /* * To maintain backward compatibility with libmemcached, we don't * include the port as the part of the input string to the consistent * hashing algorithm, when it is equal to 11211. */ if (field->port == CONF_DEFAULT_KETAMA_PORT) { name = addr; namelen = addrlen; } else { name = addr; namelen = addrlen + 1 + portlen; } } status = string_copy(&field->name, name, namelen); if (status != NC_OK) { return CONF_ERROR; } status = string_copy(&field->addrstr, addr, addrlen); if (status != NC_OK) { return CONF_ERROR; } /* * The address resolution of the backend server hostname is lazy. * The resolution occurs when a new connection to the server is * created, which could either be the first time or every time * the server gets re-added to the pool after an auto ejection */ field->valid = 1; return CONF_OK; }
static void call_make_arithmetic_req(struct context *ctx, struct call *call, uint32_t key_id, long int key_vlen) { struct opt *opt = &ctx->opt; int len; uint32_t i; for (i = 0; i < REQ_IOV_LEN; i++) { struct iovec *iov = &call->req.iov[i]; switch (i) { case REQ_IOV_METHOD: iov->iov_base = req_strings[opt->method].data; iov->iov_len = req_strings[opt->method].len; break; case REQ_IOV_KEY: len = mcp_scnprintf(call->req.keyname, sizeof(call->req.keyname), "%.*s%08"PRIx32" ", opt->prefix.len, opt->prefix.data, key_id); iov->iov_base = call->req.keyname; iov->iov_len = (size_t)len; break; case REQ_IOV_FLAG: iov->iov_base = NULL; iov->iov_len = 0; break; case REQ_IOV_EXPIRY: /* use expiry iov as incr/decr value */ len = mcp_scnprintf(call->req.expiry, sizeof(call->req.expiry), "%ld ", key_vlen); iov->iov_base = call->req.expiry; iov->iov_len = (size_t)len; break; case REQ_IOV_VLEN: case REQ_IOV_CAS: iov->iov_base = NULL; iov->iov_len = 0; break; case REQ_IOV_NOREPLY: if (opt->use_noreply) { iov->iov_base = msg_strings[MSG_NOREPLY].data; iov->iov_len = msg_strings[MSG_NOREPLY].len; call->req.noreply = 1; } else { iov->iov_base = NULL; iov->iov_len = 0; call->req.noreply = 0; } break; case REQ_IOV_CRLF: iov->iov_base = msg_strings[MSG_CRLF].data; iov->iov_len = msg_strings[MSG_CRLF].len; break; case REQ_IOV_VALUE: case REQ_IOV_CRLF2: iov->iov_base = NULL; iov->iov_len = 0; break; default: NOT_REACHED(); } call->req.send += iov->iov_len; } }
static rstatus_t conf_parse_core(struct conf *cf, void *data) { rstatus_t status; bool done, leaf, new_pool; ASSERT(cf->sound); status = conf_event_next(cf); if (status != NC_OK) { return status; } log_debug(LOG_VVERB, "next event %d depth %"PRIu32" seq %d", cf->event.type, cf->depth, cf->seq); done = false; leaf = false; new_pool = false; switch (cf->event.type) { case YAML_MAPPING_END_EVENT: cf->depth--; if (cf->depth == 1) { conf_pop_scalar(cf); } else if (cf->depth == 0) { done = true; } break; case YAML_MAPPING_START_EVENT: cf->depth++; break; case YAML_SEQUENCE_START_EVENT: cf->seq = 1; break; case YAML_SEQUENCE_END_EVENT: conf_pop_scalar(cf); cf->seq = 0; break; case YAML_SCALAR_EVENT: status = conf_push_scalar(cf); if (status != NC_OK) { break; } /* take appropriate action */ if (cf->seq) { /* for a sequence, leaf is at CONF_MAX_DEPTH */ ASSERT(cf->depth == CONF_MAX_DEPTH); leaf = true; } else if (cf->depth == CONF_ROOT_DEPTH) { /* create new conf_pool */ data = array_push(&cf->pool); if (data == NULL) { status = NC_ENOMEM; break; } new_pool = true; } else if (array_n(&cf->arg) == cf->depth + 1) { /* for {key: value}, leaf is at CONF_MAX_DEPTH */ ASSERT(cf->depth == CONF_MAX_DEPTH); leaf = true; } break; default: NOT_REACHED(); break; } conf_event_done(cf); if (status != NC_OK) { return status; } if (done) { /* terminating condition */ return NC_OK; } if (leaf || new_pool) { status = conf_handler(cf, data); if (leaf) { conf_pop_scalar(cf); if (!cf->seq) { conf_pop_scalar(cf); } } if (status != NC_OK) { return status; } } return conf_parse_core(cf, data); }
int Unicode_CompareRange(const char *str1, // IN: UnicodeIndex str1Start, // IN: UnicodeIndex str1Length, // IN: const char *str2, // IN: UnicodeIndex str2Start, // IN: UnicodeIndex str2Length, // IN: Bool ignoreCase) // IN: { int result = -1; char *substr1 = NULL; char *substr2 = NULL; utf16_t *substr1UTF16 = NULL; utf16_t *substr2UTF16 = NULL; UnicodeIndex i = 0; UnicodeIndex utf16Index; utf16_t codeUnit1; utf16_t codeUnit2; uint32 codePoint1; uint32 codePoint2; /* * TODO: Allocating substrings is a performance hit. We should do this * search in-place. (However, searching UTF-8 requires tender loving * care, and it's just easier to search UTF-16.) */ substr1 = Unicode_Substr(str1, str1Start, str1Length); if (!substr1) { goto out; } substr2 = Unicode_Substr(str2, str2Start, str2Length); if (!substr2) { goto out; } /* * XXX TODO: Need to normalize the incoming strings to NFC or NFD. */ substr1UTF16 = Unicode_GetAllocUTF16(substr1); if (!substr1UTF16) { goto out; } substr2UTF16 = Unicode_GetAllocUTF16(substr2); if (!substr2UTF16) { goto out; } /* * TODO: This is the naive string search algorithm, which is O(n * m). We * can do better with KMP or Boyer-Moore if this proves to be a bottleneck. */ while (TRUE) { codeUnit1 = *(substr1UTF16 + i); codeUnit2 = *(substr2UTF16 + i); /* * TODO: Simple case folding doesn't handle the situation where more * than one code unit is needed to store the result of the case folding. * * This means that German "straBe" (where B = sharp S, U+00DF) will not * match "STRASSE", even though the two strings are the same. */ if (ignoreCase) { codeUnit1 = UnicodeSimpleCaseFold(codeUnit1); codeUnit2 = UnicodeSimpleCaseFold(codeUnit2); } if (codeUnit1 != codeUnit2) { break; } if (codeUnit1 == 0) { // End of both strings reached: strings are equal. result = 0; goto out; } i++; } /* * The two UTF-16 code units differ. If they're the first code unit of a * surrogate pair (for Unicode values past U+FFFF), decode the surrogate * pair into a full Unicode code point. */ if (U16_IS_SURROGATE(codeUnit1)) { ssize_t substrUTF16Len = Unicode_UTF16Strlen(substr1UTF16); // U16_NEXT modifies the index, so let it work on a copy. utf16Index = i; // Decode the surrogate if needed. U16_NEXT(substr1UTF16, utf16Index, substrUTF16Len, codePoint1); } else { // Not a surrogate? Then the code point value is the code unit. codePoint1 = codeUnit1; } if (U16_IS_SURROGATE(codeUnit2)) { ssize_t substrUTF16Len = Unicode_UTF16Strlen(substr2UTF16); utf16Index = i; U16_NEXT(substr2UTF16, utf16Index, substrUTF16Len, codePoint2); } else { codePoint2 = codeUnit2; } if (codePoint1 < codePoint2) { result = -1; } else if (codePoint1 > codePoint2) { result = 1; } else { // If we hit the end of the string, we've already gone to 'out'. NOT_REACHED(); } out: free(substr1UTF16); free(substr2UTF16); free(substr1); free(substr2); return result; }
static rstatus_t conf_validate_structure(struct conf *cf) { rstatus_t status; int type, depth; uint32_t i, count[CONF_MAX_DEPTH + 1]; bool done, error, seq; status = conf_yaml_init(cf); if (status != NC_OK) { return status; } done = false; error = false; seq = false; depth = 0; for (i = 0; i < CONF_MAX_DEPTH + 1; i++) { count[i] = 0; } /* * Validate that the configuration conforms roughly to the following * yaml tree structure: * * keyx: * key1: value1 * key2: value2 * seq: * - elem1 * - elem2 * - elem3 * key3: value3 * * keyy: * key1: value1 * key2: value2 * seq: * - elem1 * - elem2 * - elem3 * key3: value3 */ do { status = conf_event_next(cf); if (status != NC_OK) { return status; } type = cf->event.type; log_debug(LOG_VVERB, "next event %d depth %d seq %d", type, depth, seq); switch (type) { case YAML_STREAM_START_EVENT: case YAML_DOCUMENT_START_EVENT: break; case YAML_DOCUMENT_END_EVENT: break; case YAML_STREAM_END_EVENT: done = true; break; case YAML_MAPPING_START_EVENT: if (depth == CONF_ROOT_DEPTH && count[depth] != 1) { error = true; log_error("conf: '%s' has more than one \"key:value\" at depth" " %d", cf->fname, depth); } else if (depth >= CONF_MAX_DEPTH) { error = true; log_error("conf: '%s' has a depth greater than %d", cf->fname, CONF_MAX_DEPTH); } depth++; break; case YAML_MAPPING_END_EVENT: if (depth == CONF_MAX_DEPTH) { if (seq) { seq = false; } else { error = true; log_error("conf: '%s' missing sequence directive at depth " "%d", cf->fname, depth); } } depth--; count[depth] = 0; break; case YAML_SEQUENCE_START_EVENT: if (seq) { error = true; log_error("conf: '%s' has more than one sequence directive", cf->fname); } else if (depth != CONF_MAX_DEPTH) { error = true; log_error("conf: '%s' has sequence at depth %d instead of %d", cf->fname, depth, CONF_MAX_DEPTH); } else if (count[depth] != 1) { error = true; log_error("conf: '%s' has invalid \"key:value\" at depth %d", cf->fname, depth); } seq = true; break; case YAML_SEQUENCE_END_EVENT: ASSERT(depth == CONF_MAX_DEPTH); count[depth] = 0; break; case YAML_SCALAR_EVENT: if (depth == 0) { error = true; log_error("conf: '%s' has invalid empty \"key:\" at depth %d", cf->fname, depth); } else if (depth == CONF_ROOT_DEPTH && count[depth] != 0) { error = true; log_error("conf: '%s' has invalid mapping \"key:\" at depth %d", cf->fname, depth); } else if (depth == CONF_MAX_DEPTH && count[depth] == 2) { /* found a "key: value", resetting! */ count[depth] = 0; } count[depth]++; break; default: NOT_REACHED(); } conf_event_done(cf); } while (!done && !error); conf_yaml_deinit(cf); return !error ? NC_OK : NC_ERROR; }
Variant UserFSNode::invoke(const Func* func, const String& name, const Array& args, bool& invoked) { JIT::VMRegAnchor _; // Assume failure invoked = false; // Public method, no private ancestor, no need for further checks (common) if (func && !(func->attrs() & (AttrPrivate|AttrProtected|AttrAbstract)) && !func->hasPrivateAncestor()) { Variant ret; g_context->invokeFunc(ret.asTypedValue(), func, args, m_obj.get()); invoked = true; return ret; } // No explicitly defined function, no __call() magic method // Give up. if (!func && !m_Call) { return uninit_null(); } HPHP::JIT::CallerFrame cf; Class* ctx = arGetContextClass(cf()); switch(g_context->lookupObjMethod(func, m_cls, name.get(), ctx)) { case LookupResult::MethodFoundWithThis: { Variant ret; g_context->invokeFunc(ret.asTypedValue(), func, args, m_obj.get()); invoked = true; return ret; } case LookupResult::MagicCallFound: { Variant ret; g_context->invokeFunc(ret.asTypedValue(), func, make_packed_array(name, args), m_obj.get()); invoked = true; return ret; } case LookupResult::MethodNotFound: // There's a method somewhere in the hierarchy, but none // which are accessible. /* fallthrough */ case LookupResult::MagicCallStaticFound: // We're not calling statically, so this result is unhelpful // Also, it's never produced by lookupObjMethod, so it'll // never happen, but we must handle all enums return uninit_null(); case LookupResult::MethodFoundNoThis: // Should never happen (Attr::Static check in ctor) assert(false); raise_error("%s::%s() must not be declared static", m_cls->name()->data(), name.data()); return uninit_null(); } NOT_REACHED(); return uninit_null(); }
Unicode Unicode_Normalize(ConstUnicode str, // IN UnicodeNormalizationForm form) // IN { UNormalizationMode mode; UChar *uchars; Unicode result; int32_t normalizedLen; UErrorCode status = U_ZERO_ERROR; UCharIterator strIter; UBool neededToNormalize = FALSE; uiter_setUTF8(&strIter, (const char *)str, -1); switch (form) { case UNICODE_NORMAL_FORM_C: mode = UNORM_NFC; break; case UNICODE_NORMAL_FORM_D: mode = UNORM_NFD; break; default: NOT_REACHED(); } normalizedLen = unorm_next(&strIter, NULL, 0, mode, 0, TRUE, &neededToNormalize, &status); if (U_FAILURE(status) && status != U_BUFFER_OVERFLOW_ERROR) { // We expect U_BUFFER_OVERFLOW_ERROR here. Anything else is a problem. ASSERT(U_SUCCESS(status)); return NULL; } uchars = Util_SafeMalloc(sizeof *uchars * normalizedLen); // Reset back to the beginning of the UTF-8 input. (*strIter.move)(&strIter, 0, UITER_START); status = U_ZERO_ERROR; normalizedLen = unorm_next(&strIter, uchars, normalizedLen, mode, 0, TRUE, &neededToNormalize, &status); if (U_FAILURE(status)) { ASSERT(U_SUCCESS(status)); return NULL; } result = Unicode_AllocWithLength(uchars, normalizedLen * 2, STRING_ENCODING_UTF16); free(uchars); return result; }