📄 halcmd.c
字号:
} raw_buf[strlen(raw_buf)]='\0'; retval = replace_vars(raw_buf, cmd_buf, sizeof(cmd_buf)-2); if (retval != 0) { rtapi_print_msg(RTAPI_MSG_ERR, "HAL:%d: bad variable replacement\n", linenumber); } else { retval = tokenize(cmd_buf, tokens); /* tokens[] contains MAX_TOK+1 elements so there is always at least one empty one at the end... make it empty now */ if (retval != 0) { rtapi_print_msg(RTAPI_MSG_ERR, "HAL:%d: Bad state in token parser\n", linenumber); /* the only error that can happen here is so strange, that we exit the program */ goto out; } } /* tokens[] contains MAX_TOK+1 elements so there is always at least one empty one at the end... make it empty now */ tokens[MAX_TOK] = ""; /* process the command */ if (retval == 0) { retval = parse_cmd(tokens); if ( retval != 0 ) { errorcount++; } } } else { if (prompt_mode != 0) { rtapi_print(scriptmode == 1 ? "%\n" : "halcmd: "); fflush(stdout); } /* read command line(s) from 'srcfile' */ while (fgets(raw_buf, MAX_CMD_LEN, srcfile) != NULL) { linenumber++; /* do variable replacements on command line */ retval = replace_vars(raw_buf, cmd_buf, sizeof(cmd_buf)-2); if (retval != 0) { rtapi_print_msg(RTAPI_MSG_ERR, "HAL:%d: bad variable replacement\n", linenumber); } if (retval==0) { retval = tokenize(cmd_buf, tokens); /* tokens[] contains MAX_TOK+1 elements so there is always at least one empty one at the end... make it empty now */ if (retval != 0) { rtapi_print_msg(RTAPI_MSG_ERR, "HAL:%d: Bad state in token parser\n", linenumber); /* the only error that can happen here is so strange, that we exit the program */ goto out; } } tokens[MAX_TOK] = ""; /* the "quit" command is not handled by parse_cmd() */ if ( ( strcasecmp(tokens[0],"quit") == 0 ) || ( strcasecmp(tokens[0],"exit") == 0 ) ) { break; } /* process command */ if (retval == 0) retval = parse_cmd(tokens); /* did a signal happen while we were busy? */ if ( done ) { /* treat it as an error */ errorcount++; /* exit from loop */ break; } if ( retval != 0 ) { errorcount++; } if (( errorcount > 0 ) && ( keep_going == 0 )) { /* exit from loop */ break; } if (prompt_mode != 0) { rtapi_print(scriptmode == 1 ? "%\n" : "halcmd: "); fflush(stdout); } } } /* all done */out: /* tell the signal handler we might have the mutex */ hal_flag = 1; hal_exit(comp_id); if ( errorcount > 0 ) { return 1; } else { return 0; }}/************************************************************************ LOCAL FUNCTION DEFINITIONS *************************************************************************//* release_HAL_mutex() unconditionally releases the hal_mutex very useful after a program segfaults while holding the mutex*/static int release_HAL_mutex(void){ int comp_id, mem_id, retval; void *mem; hal_data_t *hal_data; /* do RTAPI init */ comp_id = rtapi_init("hal_unlocker"); if (comp_id < 0) { rtapi_print_msg(RTAPI_MSG_ERR, "ERROR: rtapi init failed\n"); return HAL_FAIL; } /* get HAL shared memory block from RTAPI */ mem_id = rtapi_shmem_new(HAL_KEY, comp_id, HAL_SIZE); if (mem_id < 0) { rtapi_print_msg(RTAPI_MSG_ERR, "ERROR: could not open shared memory\n"); rtapi_exit(comp_id); return HAL_FAIL; } /* get address of shared memory area */ retval = rtapi_shmem_getptr(mem_id, &mem); if (retval != RTAPI_SUCCESS) { rtapi_print_msg(RTAPI_MSG_ERR, "ERROR: could not access shared memory\n"); rtapi_exit(comp_id); return HAL_FAIL; } /* set up internal pointers to shared mem and data structure */ hal_data = (hal_data_t *) mem; /* release mutex */ rtapi_mutex_give(&(hal_data->mutex)); /* release RTAPI resources */ rtapi_shmem_delete(mem_id, comp_id); rtapi_exit(comp_id); /* done */ return HAL_SUCCESS;}/* replace_vars: replaces environment and ini var references in source_str. This routine does string replacement only return value is 0 on success (ie, no variable lookups failed) The source string is not modified In case of an error, dest_str will contain everything that was successfully replaced, but will not contain anything past the var that caused the error. environment vars are in the following formats: $envvar<whitespace> $(envvar)<any char> ini vars are in the following formats: [SECTION]VAR<whitespace> [SECTION](VAR)<any char> return values: 0 success -1 missing close parenthesis -2 null variable name (either environment or ini varname) -3 missing close square bracket -4 environment variable not found -5 ini variable not found*/static int replace_vars(char *source_str, char *dest_str, int max_chars){ int retval = 0, loopcount=0; int next_delim, remaining; char *replacement, sec[128], var[128]; char *sp=source_str, *dp=dest_str, *secP, *varP; const char * words = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-_"; dest_str[max_chars-1] = '\0'; /* make sure there's a terminator */ while ((remaining = strlen(sp)) > 0) { loopcount++; next_delim=strcspn(sp, "$["); strncpy(dp, sp, next_delim); dp[next_delim]='\0'; dp += next_delim; sp += next_delim; if (next_delim < remaining) { /* a new delimiter was found */ switch (*sp++) { /* this is the found delimiter, since sp was incremented */ case '$': varP = sp; if (*sp=='(') { /* look for a parenthesized var */ varP=++sp; next_delim=strcspn(varP, ")"); if (next_delim > strlen(varP)) /* error - no matching parens */ return -1; sp++; } else next_delim = strspn(varP, words); if (next_delim == 0) return -2; strncpy(var, varP, next_delim); var[next_delim]='\0'; replacement = getenv(var); if (replacement == NULL) return -4; strcat(dp, replacement); dp += strlen(replacement); sp += next_delim; break; case '[': secP = sp; next_delim = strcspn(secP, "]"); if (next_delim > strlen(secP)) /* error - no matching square bracket */ return -3; strncpy(sec, secP, next_delim); sec[next_delim]='\0'; sp += next_delim+1; varP = sp; /* should point past the ']' now */ if (*sp=='(') { /* look for a parenthesized var */ varP=++sp; next_delim=strcspn(varP, ")"); if (next_delim > strlen(varP)) /* error - no matching parens */ return -1; sp++; } else next_delim = strspn(varP, words); if (next_delim == 0) return -2; strncpy(var, varP, next_delim); var[next_delim]='\0'; if ( strlen(sec) > 0 ) { /* get value from ini file */ /* cast to char ptr, we are discarding the 'const' */ replacement = (char *) iniFind(inifile, var, sec); } else { /* no section specified */ replacement = (char *) iniFind(inifile, var, NULL); } if (replacement==NULL) return -5; strcat(dp, replacement); dp += strlen(replacement); sp += next_delim; break; } } } return retval;}/* parse_cmd() decides which command has been invoked, gathers any arguments that are needed, and calls a function to execute the command.*/static int parse_cmd(char *tokens[]){ int retval=0;#if 0 int n; /* for testing: prints tokens that make up the command */ for ( n = 0 ; n < MAX_TOK ; n++ ) { printf ( "HAL:%d: %02d:{%s}\n", linenumber, n, tokens[n] ); }#endif /* tell the signal handler that we might have the mutex and can't just quit */ hal_flag = 1; /* tokens[0] is the command */ if ((tokens[0][0] == '#') || (tokens[0][0] == '\0')) { /* comment or blank line, do nothing */ retval = 0; } else if (strcasecmp(tokens[0], "help") == 0) { /* help for a specific command? */ if (tokens[1][0] != '\0') { /* yes, get info for that command */ retval = do_help_cmd(tokens[1]); } else { /* no, print list of commands */ print_help_commands(); retval = 0; } } else if (strcmp(tokens[0], "linkps") == 0) { /* check for an arrow */ if ((tokens[2][0] == '=') || (tokens[2][0] == '<')) { retval = do_link_cmd(tokens[1], tokens[3]); } else { retval = do_link_cmd(tokens[1], tokens[2]); } } else if (strcmp(tokens[0], "linksp") == 0) { /* check for an arrow */ if ((tokens[2][0] == '=') || (tokens[2][0] == '<')) { /* arrow found, skip it */ retval = do_link_cmd(tokens[3], tokens[1]); } else { /* no arrow */ retval = do_link_cmd(tokens[2], tokens[1]); } } else if (strcmp(tokens[0], "linkpp") == 0) { /* check for an arrow */ if ((tokens[2][0] == '=') || (tokens[2][0] == '<') || (tokens[2][0] == '>')) { /* arrow found, skip it - is this bad for bidir pins? */ retval = do_linkpp_cmd(tokens[1], tokens[3]); } else { /* no arrow */ retval = do_linkpp_cmd(tokens[1], tokens[2]); } } else if (strcmp(tokens[0], "unlinkp") == 0) { retval = do_link_cmd(tokens[1], "\0"); } else if (strcmp(tokens[0], "newsig") == 0) { retval = do_newsig_cmd(tokens[1], tokens[2]); } else if (strcmp(tokens[0], "delsig") == 0) { retval = do_delsig_cmd(tokens[1]); } else if (strcmp(tokens[0], "setp") == 0) { retval = do_setp_cmd(tokens[1], tokens[2]); } else if (strcmp(tokens[1], "=") == 0) { retval = do_setp_cmd(tokens[0], tokens[2]); } else if (strcmp(tokens[0], "sets") == 0) { retval = do_sets_cmd(tokens[1], tokens[2]); } else if (strcmp(tokens[0], "getp") == 0) { retval = do_getp_cmd(tokens[1]); } else if (strcmp(tokens[0], "gets") == 0) { retval = do_gets_cmd(tokens[1]); } else if (strcmp(tokens[0], "show") == 0) { retval = do_show_cmd(tokens[1], tokens[2]); } else if (strcmp(tokens[0], "list") == 0) { retval = do_list_cmd(tokens[1], tokens[2]); } else if (strcmp(tokens[0], "status") == 0) { retval = do_status_cmd(tokens[1]); } else if (strcmp(tokens[0], "lock") == 0) { retval = do_lock_cmd(tokens[1]); } else if (strcmp(tokens[0], "unlock") == 0) { retval = do_unlock_cmd(tokens[1]); } else if (strcmp(tokens[0], "loadrt") == 0) { retval = do_loadrt_cmd(tokens[1], &tokens[2]); } else if (strcmp(tokens[0], "unloadrt") == 0) { retval = do_unloadrt_cmd(tokens[1]); } else if (strcmp(tokens[0], "loadusr") == 0) { retval = do_loadusr_cmd(&tokens[1]); } else if (strcmp(tokens[0], "save") == 0) { retval = do_save_cmd(tokens[1]); } else if (strcmp(tokens[0], "addf") == 0) { /* did the user specify a position? */ if (tokens[3][0] == '\0') { /* no - add function at end of thread */ retval = hal_add_funct_to_thread(tokens[1], tokens[2], -1); } else { retval = hal_add_funct_to_thread(tokens[1], tokens[2], atoi(tokens[3])); } if (retval == 0) { /* print success message */ rtapi_print_msg(RTAPI_MSG_INFO, "HAL:%d: Function '%s' added to thread '%s'\n", linenumber, tokens[1], tokens[2]); } } else if (strcmp(tokens[0], "delf") == 0) { retval = hal_del_funct_from_thread(tokens[1], tokens[2]); if (retval == 0) { /* print success message */ rtapi_print_msg(RTAPI_MSG_INFO, "Function '%s' removed from thread '%s'\n", tokens[1], tokens[2]); } } else if (strcmp(tokens[0], "start") == 0) { retval = hal_start_threads(); if (retval == 0) { /* print success message */ rtapi_print_msg(RTAPI_MSG_INFO, "Realtime threads started\n"); } } else if (strcmp(tokens[0], "stop") == 0) { retval = hal_stop_threads(); if (retval == 0) { /* print success message */ rtapi_print_msg(RTAPI_MSG_INFO, "Realtime threads stopped\n"); } } else { if ((tokens[1][0] == '\0') && (tokens[2][0] == '\0')) { /* try to match params, signals, pins, and return the value of the named item(s) */ retval = do_show_cmd("all", tokens[0]); } if (retval != 0) { rtapi_print_msg(RTAPI_MSG_ERR, "HAL:%d: Unknown command '%s'\n", linenumber, tokens[0]); retval = -1; } } /* tell the signal handler that we no longer can have the mutex */ hal_flag = 0; return retval;}static int do_lock_cmd(char *command){ int retval=0; /* if command is blank, want to lock everything */ if (*command == '\0') { retval = hal_set_lock(HAL_LOCK_ALL); } else if (strcmp(command, "none") == 0) { retval = hal_set_lock(HAL_LOCK_NONE); } else if (strcmp(command, "tune") == 0) { retval = hal_set_lock(HAL_LOCK_LOAD & HAL_LOCK_CONFIG); } else if (strcmp(command, "all") == 0) { retval = hal_set_lock(HAL_LOCK_ALL); } if (retval == 0) { /* print success message */ rtapi_print_msg(RTAPI_MSG_INFO, "Locking completed"); } else { rtapi_print_msg(RTAPI_MSG_INFO, "HAL:%d: Locking failed\n", linenumber); } return retval;}static int do_unlock_cmd(char *command){ int retval=0; /* if command is blank, want to lock everything */ if (*command == '\0') { retval = hal_set_lock(HAL_LOCK_NONE); } else if (strcmp(command, "all") == 0) { retval = hal_set_lock(HAL_LOCK_NONE); } else if (strcmp(command, "tune") == 0) { retval = hal_set_lock(HAL_LOCK_LOAD & HAL_LOCK_CONFIG); } if (retval == 0) { /* print success message */ rtapi_print_msg(RTAPI_MSG_INFO, "Unlocking completed"); } else { rtapi_print_msg(RTAPI_MSG_INFO, "HAL:%d: Unlocking failed\n", linenumber); } return retval;}static int do_linkpp_cmd(char *first_pin_name, char *second_pin_name){ int retval; hal_pin_t *first_pin, *second_pin;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -