| 236 | } |
| 237 | |
| 238 | void ckpt_delete_directory(struct ParseState* Parser, struct Value* ReturnValue, struct Value** Param, int NumArgs) |
| 239 | { |
| 240 | // Through ScriptHeap, not free(): makeDirData allocated these, so the heap |
| 241 | // still owns them and a raw free() would leave it holding dangling keys to |
| 242 | // free again at the end of the run. |
| 243 | // |
| 244 | // NULL is accepted — sav_list answers NULL on error and a cleanup path |
| 245 | // should be able to hand that straight back — but anything else must be a |
| 246 | // struct the heap handed out, because the loop below walks it. Same rule as |
| 247 | // json_delete: a pointer this heap does not own is a script mistake, and |
| 248 | // this is the only place that can still say where it was made. |
| 249 | const ScriptArgs args(Parser, Param, NumArgs, "delete_directory"); |
| 250 | dirData* dir = (dirData*)args.ptrOrNull(0); |
| 251 | if (dir == nullptr) { |
| 252 | return; |
| 253 | } |
| 254 | ScriptHeap& heap = ScriptHeap::get(); |
| 255 | if (!heap.owns(dir)) { |
| 256 | args.fail("argument 1 is not a directory from read_directory/sav_list"); |
| 257 | } |
| 258 | |
| 259 | for (int i = 0; i < dir->count; i++) { |
| 260 | heap.release(dir->files[i]); |
| 261 | } |
| 262 | heap.release(dir->files); |
| 263 | heap.release(dir); |
| 264 | } |
| 265 | |
| 266 | void ckpt_sd_mkdirs(struct ParseState* Parser, struct Value* ReturnValue, struct Value** Param, int NumArgs) |
| 267 | { |