2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
27 #define KEY_CODE_ESCAPE 27
28 #define KEY_CODE_BACKSPACE 127
29 #define KEY_CODE_TAB 9
30 #define KEY_CODE_ARROW_UP 65
31 #define KEY_CODE_ARROW_DOWN 66
32 #define KEY_CODE_ARROW_RIGHT 67
33 #define KEY_CODE_ARROW_LEFT 68
35 /* The list data structure to keep history of the test suite commands */
36 typedef struct __cmd_history_s {
37 struct __cmd_history_s *prev;
38 struct __cmd_history_s *next;
39 char cmd[MAX_COMMAND_LINE_LEN];
42 static _cmd_history_t *_cmd_history_tail = NULL;
43 static _cmd_history_t *_cmd_history_curp = NULL;
44 static char OUTPUT_LOG_FILE[MAX_PATH_LEN] = "out.log";
48 printf("Usage: sound_pool_test [options] \n");
49 printf("Test Suite for testing Tizen SoundPool module \n");
50 printf("-h, --help - shows this help; \n");
51 printf("-s, --script=SCRIPT - executes commands from the text file \n"
52 " directly after start; \n");
53 printf("-t, --target=TARGET(S) - selects the target or targets to \n"
54 " output logs. Possible targets are: \n"
55 " stderr, dlog, file. You can also \n"
56 " select multiple targets using coma. \n"
58 " > sound_pool_test -t stderr,file \n"
59 " will output both in standard \n"
60 " error and file; \n");
61 printf("-f, --file=FILEPATH - selects file for file output logging.\n"
62 " Works only in -t argument value \n"
63 " includes 'file' target; \n");
66 _cmd_history_t *add_cmd_to_history(const char *cmd)
71 if (!_cmd_history_tail) {
72 _cmd_history_tail = malloc(sizeof(_cmd_history_t));
73 if (!_cmd_history_tail)
75 _cmd_history_tail->prev = NULL;
76 _cmd_history_tail->next = NULL;
78 _cmd_history_tail->next = malloc(sizeof(_cmd_history_t));
79 if (!_cmd_history_tail->next)
81 _cmd_history_tail->next->prev = _cmd_history_tail;
82 _cmd_history_tail->next->next = NULL;
83 _cmd_history_tail = _cmd_history_tail->next;
86 strncpy(_cmd_history_tail->cmd, cmd, MAX_COMMAND_LINE_LEN - 1);
87 _cmd_history_tail->cmd[MAX_COMMAND_LINE_LEN - 1] = '\0';
88 _cmd_history_curp = _cmd_history_tail;
89 return _cmd_history_tail;
92 const char *pop_up_curp_from_cmd_history()
94 if (!_cmd_history_curp)
97 const char *curp_cmd = _cmd_history_curp->cmd;
98 if (_cmd_history_curp->prev)
99 _cmd_history_curp = _cmd_history_curp->prev;
103 const char *pop_down_curp_from_cmd_history()
105 if (!_cmd_history_curp)
108 const char *curp_cmd = _cmd_history_curp->cmd;
109 if (_cmd_history_curp->next)
110 _cmd_history_curp = _cmd_history_curp->next;
114 /* Searches the same part of two strings from the start and returns the length
115 of this part. For example, for the strings "Big Troll" and "Big troll" value
116 4 will be returned (the same part is "Big "). */
117 size_t get_identical_start_len(const char *str1, const char *str2)
119 size_t len1 = strnlen(str1, MAX_COMMAND_LINE_LEN);
120 size_t len2 = strnlen(str2, MAX_COMMAND_LINE_LEN);
122 while (idx < len1 && idx < len2) {
123 if (str1[idx] != str2[idx])
130 size_t auto_fill(const char *cmd_start, char fill_hint[MAX_COMMAND_LINE_LEN])
133 size_t cmd_start_len = strnlen(cmd_start, MAX_COMMAND_LINE_LEN);
135 char auto_fill[MAX_COMMAND_LINE_LEN] = { '\0' };
136 size_t fill_found = 0;
138 for (; idx < CMD_COUNT; ++idx) {
139 if (strncmp(cmd_start, cmd_list[idx], cmd_start_len) == 0) {
141 strncpy(auto_fill, cmd_list[idx], MAX_COMMAND_LINE_LEN - 1);
142 fill_found = strnlen(auto_fill, MAX_COMMAND_LINE_LEN - 1);
144 fill_found = get_identical_start_len(auto_fill, cmd_list[idx]);
145 auto_fill[fill_found] = '\0';
151 strncpy(fill_hint, cmd_start, MAX_COMMAND_LINE_LEN - 1);
153 strncpy(fill_hint, auto_fill, MAX_COMMAND_LINE_LEN - 1);
155 fill_hint[MAX_COMMAND_LINE_LEN - 1] = '\0';
160 size_t print_cmd_prompt()
162 const char *prompt = "sound-pool-ts-cmd > ";
163 printf("%s", prompt);
164 /* Return the length of comand prompt c-string */
165 return strnlen(prompt, MAX_COMMAND_LINE_LEN);
170 struct termios oldattr, newattr;
172 tcgetattr(STDIN_FILENO, &oldattr);
174 newattr.c_lflag &= ~(ICANON | ECHO);
175 tcsetattr(STDIN_FILENO, TCSANOW, &newattr);
177 tcsetattr(STDIN_FILENO, TCSANOW, &oldattr);
181 size_t ts_getline(char *cmd_line)
188 /* Read whole line */
192 while ((c = getch()) != EOF && (cc = (char)c) != '\n' &&
193 ci < MAX_COMMAND_LINE_LEN - 1) {
194 if (cc == KEY_CODE_ESCAPE) { /* Arrow keys */
199 cc = (char)c; /* Here is particular arrow code */
200 const char *curp_cmd = NULL;
201 if (cc == KEY_CODE_ARROW_UP) {
202 if ((curp_cmd = pop_up_curp_from_cmd_history())) {
205 printf("%s", curp_cmd);
206 strncpy(cmd_line, curp_cmd, MAX_COMMAND_LINE_LEN);
207 ci = strnlen(curp_cmd, MAX_COMMAND_LINE_LEN);
209 } else if (cc == KEY_CODE_ARROW_DOWN) {
210 if ((curp_cmd = pop_down_curp_from_cmd_history())) {
213 printf("%s", curp_cmd);
214 strncpy(cmd_line, curp_cmd, MAX_COMMAND_LINE_LEN);
215 ci = strnlen(curp_cmd, MAX_COMMAND_LINE_LEN);
220 if (cc == KEY_CODE_BACKSPACE) { /* Backspace key */
223 cmd_line[ci--] = '\0';
227 if (cc == KEY_CODE_TAB) { /* Tab key */
228 size_t hint_len = auto_fill(cmd_line, cmd_line);
229 while (ci < hint_len)
230 printf("%c", cmd_line[ci++]);
244 int main(int argc, char* argv[])
246 _logger_set_log_tag("TIZEN_SOUND_POOL_TEST_SUITE");
247 _logger_set_logging_mode(LOG_MODE_STDERR | LOG_MODE_DLOG);
249 # define OPTIONS "s:f:t:h"
250 struct option options[] = {
251 { "script", required_argument, NULL, 's' },
252 { "logfile", required_argument, NULL, 'f' },
253 { "target", required_argument, NULL, 't' },
254 { "help", no_argument, NULL, 'h' },
258 char commands[MAX_COMMAND_LINE_LEN] = { '\0' };
259 size_t last_cmd_end = 0;
262 int do_print_usage = 0;
264 while ((opt = getopt_long(argc, argv, OPTIONS, options, NULL)) != -1) {
267 snprintf(commands + last_cmd_end, MAX_COMMAND_LINE_LEN - 1,
268 "%s %s\n", CMD_EXECUTE_SCRIPT, optarg);
270 strnlen(commands + last_cmd_end, MAX_COMMAND_LINE_LEN) + 1;
274 _logger_set_file(optarg);
279 int log_mode = LOG_MODE_NONE;
280 char *usr_ptr = NULL;
281 char *token = strtok_r(optarg, ",", &usr_ptr);
283 while (token != NULL) {
284 if (strncmp(token, "stderr", MAX_MSG_LEN) == 0) {
285 log_mode |= LOG_MODE_STDERR;
286 } else if (strncmp(token, "file", MAX_MSG_LEN) == 0) {
287 log_mode |= LOG_MODE_FILE;
289 } else if (strncmp(token, "dlog", MAX_MSG_LEN) == 0) {
290 log_mode |= LOG_MODE_DLOG;
292 _printf(CMD_COLOR_RED, "%s target is not supported! "
293 "Use one (or combination separated by coma) "
294 "from the list: dlog, stderr, and dlog.\n", token);
296 token = strtok_r(NULL, ", ", &usr_ptr);
299 if (log_mode != LOG_MODE_NONE)
300 _logger_set_logging_mode(log_mode);
313 if (do_print_usage != 0)
317 _logger_set_file(OUTPUT_LOG_FILE);
319 char *ccmd = commands;
321 while (ccmd[0] != '\0') {
322 if (_exec_cmd(ccmd) == UCMD) {
323 _printf(CMD_COLOR_RED,
324 "Unknown command! Type 'help' for command help!\n");
326 ccmd += strnlen(ccmd, MAX_COMMAND_LINE_LEN) + 1;
329 char cmd_line[MAX_COMMAND_LINE_LEN];
330 size_t cmd_line_len = 0;
332 while ((cmd_line_len = ts_getline(cmd_line))) {
333 if (cmd_line_len == 1)
336 /* Try to execute commands parsed from the line: */
337 int res = _exec_cmd(cmd_line);
342 _printf(CMD_COLOR_RED,
343 "Unknown command! Type 'help' for command help!\n");
345 add_cmd_to_history(cmd_line);