int command_set_cgdb_mode_key(const char *value) { struct cgdbrc_config_option option; option.option_kind = CGDBRC_CGDB_MODE_KEY; if (value) { /* If the user typed in a single key, use it. */ if (strlen(value) == 1) { option.variant.int_val = value[0]; } else { /* The user may have typed in a keycode. (e.g. <Esc>) * attempt to translate it. */ int key = kui_term_get_cgdb_key_from_keycode(value); if (key == -1) return -1; option.variant.int_val = key; } } else { return -1; } return cgdbrc_set_val(option); }
int kui_term_string_to_key_array (const char *string, int **cgdb_key_array) { int i; enum state_type { KUI_MAP_STATE_NORMAL, KUI_MAP_STATE_MACRO } state; char cur_char; int length; /* A buffer to store macros */ char *macro; int macro_pos; /* A buffer to store the outbound parameter */ int *local_cgdb_key_array; int cgdb_key_array_pos; /* Verify parameters */ if ( !string ) return -1; if ( !cgdb_key_array ) return -1; /* Initial stack parameters */ state = KUI_MAP_STATE_NORMAL; length = strlen ( string ); /* * Assertion * * The macro and output buffer will always be smaller than the input * buffer. So, to make life easy, they are always malloced to be the * size of the input buffer. This may be a little wasteful, but it should * not be to bad. Later, if a better ADT is available, use it here. */ /* Initialize the macro buffer */ macro = (char*)malloc ( sizeof ( char ) * (length+1) ); macro_pos = 0; /* Initialize the output buffer */ local_cgdb_key_array = (int*)malloc ( sizeof ( int ) * (length+1) ); cgdb_key_array_pos = 0; for (i = 0; i < length; i++){ cur_char = string[i]; switch(state){ case KUI_MAP_STATE_NORMAL: /* Check for keycode start */ if ( cur_char == '<' ) { state = KUI_MAP_STATE_MACRO; /* Capture macro */ macro[macro_pos++] = cur_char; } else { /* Place into output buffer */ local_cgdb_key_array[cgdb_key_array_pos++] = (int)cur_char; } break; case KUI_MAP_STATE_MACRO: /* Getting a macro start symbol within a macro means that from the * first '<' until here was not a macro. Dump it into the * output buffer and start fresh, assumming this is the start * of a new macro. */ if ( cur_char == '<' ) { int j; for ( j = 0; j < macro_pos; ++j ) local_cgdb_key_array[cgdb_key_array_pos++] = macro[j]; macro_pos = 0; } /* Capture macro */ macro[macro_pos++] = cur_char; if ( cur_char == '>' ) { int cgdb_key; state = KUI_MAP_STATE_NORMAL; /* Null terminate macro captured */ macro[macro_pos] = '\0'; /* Place captured macro into output buffer */ cgdb_key = kui_term_get_cgdb_key_from_keycode ( macro ); if ( cgdb_key == -1 ) return -1; /* The key doesn't exist, write the data into the * buffer. */ if ( cgdb_key == CGDB_KEY_ERROR ) { int j; for ( j = 0; j < macro_pos; ++j ) local_cgdb_key_array[cgdb_key_array_pos++] = macro[j]; } else local_cgdb_key_array[cgdb_key_array_pos++] = cgdb_key; macro_pos = 0; } break; } } /* This means that there was a '<' symbol not eventually followed by a '>' * symbol. Therefore, everything from the '<' on is not part of a macro. It * should be copied into the output buffer exactly the way it is. */ if ( state == KUI_MAP_STATE_MACRO ) { int j; for ( j = 0; j < macro_pos; ++j ) local_cgdb_key_array[cgdb_key_array_pos++] = macro[j]; } local_cgdb_key_array[cgdb_key_array_pos++] = 0; *cgdb_key_array = local_cgdb_key_array; free ( macro ); macro = NULL; return 0; }