Changeset 1162
- Timestamp:
- 11/24/07 02:24:13 (10 months ago)
- Files:
-
- 1.8.3/branches/devel/CHANGES.183 (modified) (1 diff)
- 1.8.3/branches/devel/hdrs/command.h (modified) (3 diffs)
- 1.8.3/branches/devel/hdrs/strtree.h (modified) (1 diff)
- 1.8.3/branches/devel/src/cmdlocal.dst (modified) (3 diffs)
- 1.8.3/branches/devel/src/command.c (modified) (23 diffs)
- 1.8.3/branches/devel/src/strtree.c (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
1.8.3/branches/devel/CHANGES.183
r1157 r1162 34 34 * A wildcard help topic search (help foo*) that only matches one 35 35 entry will display that entry. Suggested by Cheetah. 36 * New switches for commands no longer have to be added to the 37 SWITCHES file; the internal list of switches is now built based on 38 what switches are given in the command table and cmdlocal.c 39 additions. Suggested by Talek. 40 36 41 37 42 Flags and powers: 1.8.3/branches/devel/hdrs/command.h
r905 r1162 2 2 #define __COMMAND_H 3 3 4 #define NUM_BYTES 20 5 typedef unsigned char switch_mask[NUM_BYTES]; 4 5 typedef uint8_t *switch_mask; 6 extern int switch_bytes; 7 #define SW_ALLOC() mush_calloc(switch_bytes, 1, "cmd.switch.vector"); 8 #define SW_FREE(s) mush_free((s), "cmd.switch.vector"); 6 9 #define SW_SET(m,n) (m[(n) >> 3] |= (1 << ((n) & 0x7))) 7 10 #define SW_CLR(m,n) (m[(n) >> 3] &= ~(1 << ((n) & 0x7))) 8 11 #define SW_ISSET(m,n) (m[(n) >> 3] & (1 << ((n) & 0x7))) 9 #define SW_ZERO(m) memset(m, 0, NUM_BYTES) 12 bool SW_BY_NAME(switch_mask, const char *); 13 #define SW_ZERO(m) memset(m, 0, switch_bytes) 14 #define SW_COPY(new,old) memcpy((new), (old), switch_bytes) 10 15 11 16 /* These are type restrictors */ … … 129 134 object_flag_type flagmask; /**< Flags to which the command is restricted */ 130 135 object_flag_type powers; /**< Powers to which the command is restricted */ 131 switch_mask sw; /**< Bitflags of switches this command can take */ 136 /** Switches for this command. */ 137 union { 138 switch_mask mask; /**< Bitflags of switches this command can take */ 139 const char *names; /**< Space-seperated list of switches */ 140 } sw; 132 141 /** Hooks on this command. 133 142 */ … … 189 198 #include "switches.h" 190 199 191 extern switch_mask *switchmask(const char *switches);192 externCOMMAND_INFO *command_find(const char *name);193 externCOMMAND_INFO *command_find_exact(const char *name);194 externCOMMAND_INFO *command_add200 switch_mask switchmask(const char *switches); 201 COMMAND_INFO *command_find(const char *name); 202 COMMAND_INFO *command_find_exact(const char *name); 203 COMMAND_INFO *command_add 195 204 (const char *name, int type, const char *flagstr, const char *powers, 196 205 const char *switchstr, command_func func); 197 externCOMMAND_INFO *make_command206 COMMAND_INFO *make_command 198 207 (const char *name, int type, object_flag_type flagmask, 199 object_flag_type powers, switch_mask*sw, command_func func);200 externCOMMAND_INFO *command_modify(const char *name, int type,201 object_flag_type flagmask,202 object_flag_type powers, switch_mask *sw,203 command_func func);204 externvoid reserve_alias(const char *a);205 externint alias_command(const char *command, const char *alias);206 externvoid command_init_preconfig(void);207 externvoid command_init_postconfig(void);208 externvoid command_splitup208 object_flag_type powers, const char *sw, command_func func); 209 COMMAND_INFO *command_modify(const char *name, int type, 210 object_flag_type flagmask, 211 object_flag_type powers, switch_mask sw, 212 command_func func); 213 void reserve_alias(const char *a); 214 int alias_command(const char *command, const char *alias); 215 void command_init_preconfig(void); 216 void command_init_postconfig(void); 217 void command_splitup 209 218 (dbref player, dbref cause, char *from, char *to, char **args, 210 219 COMMAND_INFO *cmd, int side); 211 externvoid command_argparse220 void command_argparse 212 221 (dbref player, dbref cause, char **from, char *to, char **argv, 213 222 COMMAND_INFO *cmd, int side, int forcenoparse); 214 extern char *command_parse 215 (dbref player, dbref cause, char *string, int fromport); 216 extern void do_list_commands(dbref player, int lc); 217 extern char *list_commands(void); 218 extern int command_check_byname(dbref player, const char *name); 219 extern int restrict_command(const char *name, const char *restriction); 220 extern void reserve_aliases(void); 221 extern void local_commands(void); 222 extern void do_command_add(dbref player, char *name, int flags); 223 extern void do_command_delete(dbref player, char *name); 223 char *command_parse(dbref player, dbref cause, char *string, int fromport); 224 void do_list_commands(dbref player, int lc); 225 char *list_commands(void); 226 int command_check_byname(dbref player, const char *name); 227 int restrict_command(const char *name, const char *restriction); 228 void reserve_aliases(void); 229 void local_commands(void); 230 void do_command_add(dbref player, char *name, int flags); 231 void do_command_delete(dbref player, char *name); 224 232 225 233 1.8.3/branches/devel/hdrs/strtree.h
r905 r1162 37 37 void st_delete(char const *s, StrTree *root); 38 38 void st_print(StrTree *root); 39 typedef void (*STFunc) (const char *, int, void *); 40 void st_walk(StrTree *, STFunc, void *); 39 41 void st_flush(StrTree *root); 40 42 1.8.3/branches/devel/src/cmdlocal.dst
r905 r1162 1 /* -*- c -*- 1 2 /*----------------------------------------------------------------- 2 3 * Local stuff … … 53 54 if (SW_ISSET(sw, SWITCH_NOISY)) 54 55 notify_format(player, "Noisy silly with %s", arg_left); 56 if (SW_BY_NAME(sw, "VERY")) 57 notify(player, "The following line will be very silly indeed."); 55 58 notify_format(player, "SillyCommand %s", arg_left); 56 59 } … … 76 79 { 77 80 #ifdef EXAMPLE 78 command_add("@SILLY", CMD_T_ANY, "WIZARD ROYALTY", "SEE_ALL", "NOISY NOEVAL",79 cmd_local_silly);81 command_add("@SILLY", CMD_T_ANY, "WIZARD ROYALTY", "SEE_ALL", 82 "NOISY NOEVAL VERY", cmd_local_silly); 80 83 #endif 81 84 } 1.8.3/branches/devel/src/command.c
r1150 r1162 14 14 15 15 #include <string.h> 16 #include <assert.h> 17 #include <stdlib.h> 16 18 17 19 #include "conf.h" … … 28 30 #include "ptab.h" 29 31 #include "htab.h" 32 #include "strtree.h" 30 33 #include "function.h" 31 34 #include "command.h" … … 46 49 static const char *command_isattr(char *command); 47 50 static int command_check(dbref player, COMMAND_INFO *cmd); 48 static int switch_find(COMMAND_INFO *cmd, c har *sw);51 static int switch_find(COMMAND_INFO *cmd, const char *sw); 49 52 static void strccat(char *buff, char **bp, const char *from); 50 53 static int has_hook(struct hook_data *hook); 51 extern int global_fun_invocations; /**< Counter for function invocations */54 extern int global_fun_invocations; /**< Counter for function invocations */ 52 55 extern int global_fun_recursions; /**< Counter for function recursion */ 56 57 SWITCH_VALUE *dyn_switch_list = NULL; 58 int switch_bytes = 0; 59 size_t num_switches = 0; 60 61 enum command_load_state { CMD_LOAD_BUILTIN, 62 CMD_LOAD_LOCAL, 63 CMD_LOAD_DONE 64 }; 65 static enum command_load_state command_state = CMD_LOAD_BUILTIN; 66 static StrTree switch_names; 53 67 54 68 int run_hook(dbref player, dbref cause, struct hook_data *hook, … … 396 410 }; 397 411 398 399 412 static void 400 413 strccat(char *buff, char **bp, const char *from) … … 404 417 safe_str(from, buff, bp); 405 418 } 419 420 /* Comparison function for bsearch() */ 406 421 static int 407 switch_find(COMMAND_INFO *cmd, char *sw) 422 switch_cmp(const void *a, const void *b) 423 { 424 const char *name = a; 425 const SWITCH_VALUE *sw = b; 426 return strcmp(name, sw->name); 427 } 428 429 /* This has different semantics than a prefix table, or we'd use that. */ 430 static int 431 switch_find(COMMAND_INFO *cmd, const char *sw) 408 432 { 409 433 SWITCH_VALUE *sw_val; 410 int i = 0; 411 int len; 412 if (!sw || !*sw) 434 435 if (!sw || !*sw || !dyn_switch_list) 413 436 return 0; 414 len = strlen(sw); 415 /* Special case, for init */ 416 sw_val = switch_list; 437 417 438 if (!cmd) { 439 sw_val = bsearch(sw, dyn_switch_list, num_switches, sizeof(SWITCH_VALUE), 440 switch_cmp); 441 if (sw_val) 442 return sw_val->value; 443 else 444 return 0; 445 } else { 446 size_t len = strlen(sw); 447 sw_val = dyn_switch_list; 418 448 while (sw_val->name) { 419 if (strcmp(sw_val->name, sw) == 0) 449 if (SW_ISSET(cmd->sw.mask, sw_val->value) 450 && (strncmp(sw_val->name, sw, len) == 0)) 420 451 return sw_val->value; 421 452 sw_val++; 422 453 } 423 return 0;424 } else {425 while (sw_val->name) {426 i++;427 if (SW_ISSET(cmd->sw, i) && (strncmp(sw_val->name, sw, len) == 0))428 return i;429 sw_val++;430 }431 454 } 432 455 return 0; 456 } 457 458 /** Test if a particular switch was given, using name 459 * \param sw the switch mask to test 460 * \param name the name of the switch to test for. 461 */ 462 bool 463 SW_BY_NAME(switch_mask sw, const char *name) 464 { 465 int idx = switch_find(NULL, name); 466 if (idx) 467 return SW_ISSET(sw, idx); 468 else 469 return false; 433 470 } 434 471 … … 448 485 make_command(const char *name, int type, 449 486 object_flag_type flagmask, object_flag_type powers, 450 switch_mask*sw, command_func func)487 const char *sw, command_func func) 451 488 { 452 489 COMMAND_INFO *cmd; … … 459 496 cmd->flagmask = flagmask; 460 497 cmd->powers = powers; 461 if (sw) 462 memcpy(cmd->sw, sw, sizeof(switch_mask)); 463 else 464 SW_ZERO(cmd->sw); 498 switch (command_state) { 499 case CMD_LOAD_BUILTIN: 500 cmd->sw.names = sw; 501 break; 502 case CMD_LOAD_LOCAL:{ 503 char sw_copy[BUFFER_LEN]; 504 char *pos; 505 cmd->sw.names = sw; 506 mush_strncpy(sw_copy, sw, BUFFER_LEN); 507 pos = sw_copy; 508 while (pos) { 509 char *thisone = split_token(&pos, ' '); 510 st_insert(thisone, &switch_names); 511 } 512 break; 513 } 514 case CMD_LOAD_DONE:{ 515 switch_mask mask = switchmask(sw); 516 if (mask) { 517 cmd->sw.mask = SW_ALLOC(); 518 SW_COPY(cmd->sw.mask, mask); 519 } else 520 cmd->sw.mask = NULL; 521 } 522 } 465 523 cmd->hooks.before.obj = NOTHING; 466 524 cmd->hooks.before.attrname = NULL; … … 489 547 { 490 548 object_flag_type flagmask = NULL, powers = NULL; 491 switch_mask *sw = switchmask(switchstr);492 549 493 550 if (flagstr) … … 496 553 powers = string_to_bits("POWER", powerstr); 497 554 ptab_insert_one(&ptab_command, name, 498 make_command(name, type, flagmask, powers, sw , func));555 make_command(name, type, flagmask, powers, switchstr, func)); 499 556 return command_find(name); 500 557 } … … 556 613 command_modify(const char *name, int type, 557 614 object_flag_type flagmask, object_flag_type powers, 558 switch_mask *sw, command_func func)615 switch_mask sw, command_func func) 559 616 { 560 617 COMMAND_INFO *cmd; … … 569 626 cmd->powers = powers; 570 627 if (sw) 571 memcpy(cmd->sw, sw, sizeof(switch_mask));628 SW_COPY(cmd->sw.mask, sw); 572 629 if (func) 573 630 cmd->func = func; … … 581 638 * \return pointer to a static switch mask. 582 639 */ 583 switch_mask *640 switch_mask 584 641 switchmask(const char *switches) 585 642 { 586 static switch_mask sw; 643 static switch_mask sw = NULL; 644 static int sm_bytes = 0; 587 645 char buff[BUFFER_LEN]; 588 646 char *p, *s; 589 647 int switchnum; 648 649 if (sm_bytes < switch_bytes) { 650 sw = mush_realloc(sw, switch_bytes, "cmd.switch.vector"); 651 sm_bytes = switch_bytes; 652 } 653 590 654 SW_ZERO(sw); 591 655 if (!switches || !switches[0]) … … 601 665 SW_SET(sw, switchnum); 602 666 } 603 return &sw;667 return sw; 604 668 } 605 669 … … 617 681 hashadd(strupper(a), (void *) placeholder, &htab_reserved_aliases); 618 682 } 683 684 static StrTree switch_names; 619 685 620 686 /** Initialize command tables (before reading config file). … … 632 698 struct command_perms_t *c; 633 699 COMLIST *cmd; 700 SWITCH_VALUE *sv; 634 701 static int done = 0; 635 702 if (done == 1) … … 639 706 ptab_init(&ptab_command); 640 707 hashinit(&htab_reserved_aliases, 16); 708 709 /* Build initial switch table. */ 710 st_init(&switch_names); 711 for (sv = switch_list; sv->name; sv++) 712 st_insert(sv->name, &switch_names); 713 641 714 command_slab = slab_create("commands", sizeof(COMMAND_INFO)); 642 715 reserve_aliases(); 716 643 717 ptab_start_inserts(&ptab_command); 718 command_state = CMD_LOAD_BUILTIN; 644 719 for (cmd = commands; cmd->name; cmd++) { 720 if (cmd->switches) { 721 char sw_copy[BUFFER_LEN]; 722 char *pos; 723 strcpy(sw_copy, cmd->switches); 724 pos = sw_copy; 725 while (pos) { 726 char *sw = split_token(&pos, ' '); 727 st_insert(sw, &switch_names); 728 } 729 } 645 730 ptab_insert(&ptab_command, cmd->name, 646 731 make_command(cmd->name, cmd->type, 647 732 string_to_bits("FLAG", cmd->flagstr), 648 733 string_to_bits("POWER", cmd->powers), 649 switchmask(cmd->switches), cmd->func));734 cmd->switches, cmd->func)); 650 735 } 651 736 ptab_end_inserts(&ptab_command); … … 657 742 ptab_end_inserts(&ptab_command_perms); 658 743 744 command_state = CMD_LOAD_LOCAL; 659 745 local_commands(); 746 } 747 748 struct bst_data { 749 SWITCH_VALUE *table; 750 size_t n; 751 size_t start; 752 }; 753 754 static void 755 build_switch_table(const char *sw, int count __attribute__ ((__unused__)), 756 void *d) 757 { 758 SWITCH_VALUE *s; 759 struct bst_data *data = d; 760 761 for (s = switch_list; s->name; s++) { 762 if (strcmp(s->name, sw) == 0) { 763 data->table[data->n++] = *s; 764 return; 765 } 766 } 767 /* Not in switchinc.c table */ 768 data->table[data->n].value = data->start++; 769 data->table[data->n++].name = mush_strdup(sw, "switch.name"); 660 770 } 661 771 … … 668 778 command_init_postconfig(void) 669 779 { 780 struct bst_data sw_data; 781 COMMAND_INFO *c; 782 size_t sl_size; 783 784 command_state = CMD_LOAD_DONE; 785 786 /* First make the switch table */ 787 dyn_switch_list = mush_calloc(switch_names.count + 2, sizeof(SWITCH_VALUE), 788 "cmd_switch_table"); 789 if (!dyn_switch_list) 790 mush_panic(T("Unable to allocate command switch table")); 791 sw_data.table = dyn_switch_list; 792 sw_data.n = 0; 793 sw_data.start = sizeof switch_list / sizeof(SWITCH_VALUE); 794 sl_size = sw_data.start - 2; 795 st_walk(&switch_names, build_switch_table, &sw_data); 796 num_switches = sw_data.start; 797 dyn_switch_list[sw_data.n].name = NULL; 798 st_flush(&switch_names); 799 switch_bytes = ceil((double) num_switches / 8.0); 800 801 /* Then convert the list of switch names in all commands to masks */ 802 for (c = ptab_firstentry(&ptab_command); c; c = ptab_nextentry(&ptab_command)) { 803 const char *switchstr = c->sw.names; 804 if (switchstr) { 805 c->sw.mask = SW_ALLOC(); 806 SW_COPY(c->sw.mask, switchmask(switchstr)); 807 } 808 } 809 670 810 return; 671 811 } … … 869 1009 char b; 870 1010 int switchnum; 871 switch_mask sw ;1011 switch_mask sw = NULL; 872 1012 char switch_err[BUFFER_LEN], *se; 873 1013 int noeval; … … 877 1017 rhs_present = 0; 878 1018 879 command = (char *)mush_malloc(BUFFER_LEN, "string");880 swtch = (char *)mush_malloc(BUFFER_LEN, "string");881 ls = (char *)mush_malloc(BUFFER_LEN, "string");882 rs = (char *)mush_malloc(BUFFER_LEN, "string");883 switches = (char *)mush_malloc(BUFFER_LEN, "string");1019 command = mush_malloc(BUFFER_LEN, "string"); 1020 swtch = mush_malloc(BUFFER_LEN, "string"); 1021 ls = mush_malloc(BUFFER_LEN, "string"); 1022 rs = mush_malloc(BUFFER_LEN, "string"); 1023 switches = mush_malloc(BUFFER_LEN, "string"); 884 1024 if (!command || !swtch || !ls || !rs || !switches) 885 1025 mush_panic("Couldn't allocate memory in command_parse"); … … 1062 1202 } 1063 1203 /* Parse out any switches */ 1064 SW_ZERO(sw);1204 sw = SW_ALLOC(); 1065 1205 swp = switches; 1066 1206 *swp = '\0'; … … 1227 1367 } 1228 1368 1369 SW_FREE(sw); 1229 1370 command_parse_free_args; 1230 1371 return retval; … … 1620 1761 buff[0] = '\0'; 1621 1762 notify(player, show_command_flags(command->flagmask, command->powers)); 1622 bp = buff; 1623 for (sw_val = switch_list; sw_val->name; sw_val++) 1624 if (SW_ISSET(command->sw, sw_val->value)) 1625 strccat(buff, &bp, sw_val->name); 1626 *bp = '\0'; 1627 notify_format(player, "Switches : %s", buff); 1763 if (command->sw.mask) { 1764 bp = buff; 1765 for (sw_val = dyn_switch_list; sw_val->name; sw_val++) 1766 if (SW_ISSET(command->sw.mask, sw_val->value)) 1767 strccat(buff, &bp, sw_val->name); 1768 *bp = '\0'; 1769 notify_format(player, "Switches : %s", buff); 1770 } else 1771 notify(player, "Switches :"); 1628 1772 buff[0] = '\0'; 1629 1773 bp = buff; 1.8.3/branches/devel/src/strtree.c
r905 r1162 531 531 } 532 532 533 static void 534 st_node_walk(StrNode *node, STFunc callback, void *data) 535 { 536 if (node->left) 537 st_node_walk(node->left, callback, data); 538 callback(node->string, node->info >> ST_COLOR, data); 539 if (node->right) 540 st_node_walk(node->right, callback, data); 541 } 542 543 /** Call a function for each node in the tree, in-order */ 544 void 545 st_walk(StrTree *tree, STFunc callback, void *data) 546 { 547 if (!tree || !tree->root) 548 return; 549 st_node_walk(tree->root, callback, data); 550 } 551 533 552 /* Print the tree, for debugging purposes. */ 534 553 static void … … 589 608 (*perms)++; 590 609 else 591 (*nperms) += node->info ;610 (*nperms) += node->info >> ST_COLOR; 592 611 593 612 if (count > *maxdepth)
