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.
26 #define KEY_CODE_ESCAPE 27
27 #define KEY_CODE_BACKSPACE 127
28 #define KEY_CODE_TAB 9
29 #define KEY_CODE_ARROW_UP 65
30 #define KEY_CODE_ARROW_DOWN 66
31 #define KEY_CODE_ARROW_RIGHT 67
32 #define KEY_CODE_ARROW_LEFT 68
34 /* The list data structure to keep history of the test suite commands */
35 typedef struct __cmd_history_s {
36 struct __cmd_history_s *prev;
37 struct __cmd_history_s *next;
38 char cmd[MAX_COMMAND_LINE_LEN];
41 static _cmd_history_t *_cmd_history_tail = NULL;
42 static _cmd_history_t *_cmd_history_curp = NULL;
43 static char OUTPUT_LOG_FILE[MAX_PATH_LEN] = "out.log";
46 printf( "Usage: sound_pool_test [options] \n");
47 printf( "Test Suite for testing Tizen SoundPool module \n");
48 printf( "-h, --help - shows this help; \n");
49 printf( "-s, --script=SCRIPT - executes commands from the text file \n"
50 " directly after start; \n");
51 printf( "-t, --target=TARGET(S) - selects the target or targets to \n"
52 " output logs. Possible targets are: \n"
53 " stderr, dlog, file. You can also \n"
54 " select multiple targets using coma. \n"
56 " > sound_pool_test -t stderr,file \n"
57 " will output both in standard \n"
58 " error and file; \n");
59 printf( "-f, --file=FILEPATH - selects file for file output logging.\n"
60 " Works only in -t argument value \n"
61 " includes 'file' target; \n");
64 _cmd_history_t *add_cmd_to_history(const char *cmd)
69 if (!_cmd_history_tail) {
70 _cmd_history_tail = malloc(sizeof(_cmd_history_t));
71 if (!_cmd_history_tail)
73 _cmd_history_tail->prev = NULL;
74 _cmd_history_tail->next = NULL;
76 _cmd_history_tail->next = malloc(sizeof(_cmd_history_t));
77 if (!_cmd_history_tail->next)
79 _cmd_history_tail->next->prev = _cmd_history_tail;
80 _cmd_history_tail->next->next = NULL;
81 _cmd_history_tail = _cmd_history_tail->next;
84 strncpy(_cmd_history_tail->cmd, cmd, MAX_COMMAND_LINE_LEN - 1);
85 _cmd_history_tail->cmd[MAX_COMMAND_LINE_LEN - 1] = '\0';
86 _cmd_history_curp = _cmd_history_tail;
87 return _cmd_history_tail;
90 const char *pop_up_curp_from_cmd_history()
92 if (!_cmd_history_curp)
95 const char *curp_cmd = _cmd_history_curp->cmd;
96 if (_cmd_history_curp->prev)
97 _cmd_history_curp = _cmd_history_curp->prev;
101 const char *pop_down_curp_from_cmd_history()
103 if (!_cmd_history_curp)
106 const char *curp_cmd = _cmd_history_curp->cmd;
107 if (_cmd_history_curp->next)
108 _cmd_history_curp = _cmd_history_curp->next;
112 /* Searches the same part of two strings from the start and returns the length
113 of this part. For example, for the strings "Big Troll" and "Big troll" value
114 4 will be returned (the same part is "Big "). */
115 size_t get_identical_start_len(const char *str1, const char *str2)
117 size_t len1 = strnlen(str1, MAX_COMMAND_LINE_LEN);
118 size_t len2 = strnlen(str2, MAX_COMMAND_LINE_LEN);
120 while(idx < len1 && idx < len2) {
121 if (str1[idx] != str2[idx])
128 size_t auto_fill(const char *cmd_start, char fill_hint[MAX_COMMAND_LINE_LEN])
131 size_t cmd_start_len = strnlen(cmd_start, MAX_COMMAND_LINE_LEN);
133 char auto_fill[MAX_COMMAND_LINE_LEN] = { '\0' };
134 size_t fill_found = 0;
136 for (; idx < CMD_COUNT; ++idx) {
137 if (strncmp(cmd_start, cmd_list[idx], cmd_start_len) == 0) {
139 strncpy(auto_fill, cmd_list[idx], MAX_COMMAND_LINE_LEN);
140 fill_found = strnlen(auto_fill, MAX_COMMAND_LINE_LEN);
142 fill_found = get_identical_start_len(auto_fill, cmd_list[idx]);
143 auto_fill[fill_found] = '\0';
149 strncpy(fill_hint, cmd_start, MAX_COMMAND_LINE_LEN);
151 strncpy(fill_hint, auto_fill, MAX_COMMAND_LINE_LEN);
156 size_t print_cmd_prompt()
158 const char *prompt = "sound-pool-ts-cmd > ";
159 printf("%s", prompt);
160 /* Return the length of comand prompt c-string */
161 return strnlen(prompt, MAX_COMMAND_LINE_LEN);
166 struct termios oldattr, newattr;
168 tcgetattr(STDIN_FILENO, &oldattr);
170 newattr.c_lflag &= ~(ICANON | ECHO);
171 tcsetattr(STDIN_FILENO, TCSANOW, &newattr);
173 tcsetattr(STDIN_FILENO, TCSANOW, &oldattr);
177 size_t ts_getline(char *cmd_line)
184 /* Read whole line */
188 while ((c = getch()) != EOF && (cc = (char)c) != '\n' &&
189 ci < MAX_COMMAND_LINE_LEN - 1) {
190 if (cc == KEY_CODE_ESCAPE) { /* Arrow keys */
195 cc = (char)c; /* Here is particular arrow code */
196 const char *curp_cmd = NULL;
197 if (cc == KEY_CODE_ARROW_UP) {
198 if ((curp_cmd = pop_up_curp_from_cmd_history())) {
201 printf("%s", curp_cmd);
202 strncpy(cmd_line, curp_cmd, MAX_COMMAND_LINE_LEN);
203 ci = strnlen(curp_cmd, MAX_COMMAND_LINE_LEN);
205 } else if (cc == KEY_CODE_ARROW_DOWN) {
206 if ((curp_cmd = pop_down_curp_from_cmd_history())) {
209 printf("%s", curp_cmd);
210 strncpy(cmd_line, curp_cmd, MAX_COMMAND_LINE_LEN);
211 ci = strnlen(curp_cmd, MAX_COMMAND_LINE_LEN);
216 if (cc == KEY_CODE_BACKSPACE) { /* Backspace key */
219 cmd_line[ci--] = '\0';
223 if (cc == KEY_CODE_TAB) { /* Tab key */
224 size_t hint_len = auto_fill(cmd_line, cmd_line);
225 while (ci < hint_len)
226 printf("%c", cmd_line[ci++]);
240 int main(int argc, char* argv[])
242 _logger_set_log_tag("TIZEN_SOUND_POOL_TEST_SUITE");
243 _logger_set_logging_mode(LOG_MODE_STDERR | LOG_MODE_DLOG);
245 # define OPTIONS "s:f:t:h"
246 struct option options[] = {
247 { "script", required_argument, NULL, 's' },
248 { "logfile", required_argument, NULL, 'f' },
249 { "target", required_argument, NULL, 't' },
250 { "help", no_argument, NULL, 'h' },
254 char commands[MAX_COMMAND_LINE_LEN] = { '\0' };
255 size_t last_cmd_end = 0;
258 int do_print_usage = 0;
260 while ((opt = getopt_long(argc, argv, OPTIONS, options, NULL)) != -1) {
263 snprintf(commands + last_cmd_end, MAX_COMMAND_LINE_LEN,
264 "%s %s\n", CMD_EXECUTE_SCRIPT, optarg);
266 strnlen(commands + last_cmd_end, MAX_COMMAND_LINE_LEN) + 1;
270 _logger_set_file(optarg);
275 int log_mode = LOG_MODE_NONE;
276 char *token = strtok(optarg, ",");
278 while (token != NULL) {
279 if (strncmp(token, "stderr", MAX_MSG_LEN) == 0) {
280 log_mode |= LOG_MODE_STDERR;
281 } else if (strncmp(token, "file", MAX_MSG_LEN) == 0) {
282 log_mode |= LOG_MODE_FILE;
284 } else if (strncmp(token, "dlog", MAX_MSG_LEN) == 0) {
285 log_mode |= LOG_MODE_DLOG;
287 _printf(CMD_COLOR_RED, "%s target is not supported! "
288 "Use one (or combination separated by coma) "
289 "from the list: dlog, stderr, and dlog.\n", token);
291 token = strtok(NULL, ", ");
294 if (log_mode != LOG_MODE_NONE)
295 _logger_set_logging_mode(log_mode);
308 if (do_print_usage != 0)
312 _logger_set_file(OUTPUT_LOG_FILE);
314 char *ccmd = commands;
316 while (ccmd[0] != '\0') {
317 if (_exec_cmd(ccmd) == UCMD) {
318 _printf(CMD_COLOR_RED,
319 "Unknown command! Type 'help' for command help!\n");
321 ccmd += strnlen(ccmd, MAX_COMMAND_LINE_LEN) + 1;
324 char cmd_line[MAX_COMMAND_LINE_LEN];
325 size_t cmd_line_len = 0;
327 while ((cmd_line_len = ts_getline(cmd_line))) {
328 if (cmd_line_len == 1)
331 /* Try to execute commands parsed from the line: */
332 int res = _exec_cmd(cmd_line);
337 _printf(CMD_COLOR_RED,
338 "Unknown command! Type 'help' for command help!\n");
340 add_cmd_to_history(cmd_line);