1 -: 0:Source:readline.c 2 -: 1:/* readline.c -- functions to control the behaviour of readline, 3 -: 2: * specially completions. It also introduces the suggestions system 4 -: 3: * via my_rl_getc function */ 5 -: 4: 6 -: 5:/* 7 -: 6: * This file is part of CliFM 8 -: 7: * 9 -: 8: * Copyright (C) 2016-2021, L. Abramovich <johndoe.arch@outlook.com> 10 -: 9: * All rights reserved. 11 -: 10: 12 -: 11: * CliFM is free software; you can redistribute it and/or modify 13 -: 12: * it under the terms of the GNU General Public License as published by 14 -: 13: * the Free Software Foundation; either version 2 of the License, or 15 -: 14: * (at your option) any later version. 16 -: 15: * 17 -: 16: * CliFM is distributed in the hope that it will be useful, 18 -: 17: * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 -: 18: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 -: 19: * GNU General Public License for more details. 21 -: 20: * 22 -: 21: * You should have received a copy of the GNU General Public License 23 -: 22: * along with this program; if not, write to the Free Software 24 -: 23: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 25 -: 24: * MA 02110-1301, USA. 26 -: 25:*/ 27 -: 26: 28 -: 27:#include "helpers.h" 29 -: 28: 30 -: 29:#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) 31 -: 30:#include <sys/stat.h> 32 -: 31:#endif 33 -: 32:#include <dirent.h> 34 -: 33:#include <fcntl.h> 35 -: 34:#include <stdio.h> 36 -: 35:#include <string.h> 37 -: 36:#ifdef __OpenBSD__ 38 -: 37:#include <strings.h> 39 -: 38:#endif 40 -: 39:#include <unistd.h> 41 -: 40:#include <errno.h> 42 -: 41: 43 -: 42:#ifdef __OpenBSD__ 44 -: 43:typedef char *rl_cpvfunc_t; 45 -: 44:#include <ereadline/readline/readline.h> 46 -: 45:#include <ereadline/readline/history.h> 47 -: 46:#else 48 -: 47:#include <readline/readline.h> 49 -: 48:#include <readline/history.h> 50 -: 49:#endif 51 -: 50: 52 -: 51:#include "misc.h" 53 -: 52:#include "aux.h" 54 -: 53:#include "checks.h" 55 -: 54:#include "keybinds.h" 56 -: 55:#include "navigation.h" 57 -: 56:#include "readline.h" 58 -: 57:#ifndef _NO_SUGGESTIONS 59 -: 58:#include "suggestions.h" 60 -: 59:#endif 61 -: 60: 62 -: 61:#if !defined(_NO_SUGGESTIONS) && defined(__FreeBSD__) 63 -: 62:int freebsd_sc_console = 0; 64 -: 63:#endif /* __FreeBSD__ */ 65 -: 64: 66 -: 65:/* 67 -: 66:#ifndef _NO_HIGHLIGHT 68 -: 67:#define _SINGLE 0 69 -: 68:#define _DOUBLE 1 70 -: 69: 71 -: 70:static char * 72 -: 71:get_cur_color(const int point) 73 -: 72:{ 74 -: 73: int m = point; 75 -: 74: int sep = -1, sp = -1, t = -1; 76 -: 75: char *c = (char *)NULL; 77 -: 76: m--; 78 -: 77: 79 -: 78: 80 -: 79: while (m >= 0) { 81 -: 80: switch(rl_line_buffer[m]) { 82 -: 81: case ' ': sp = m; break; 83 -: 82: case '&': // fallthrough 84 -: 83: case '|': // fallthrough 85 -: 84: case ';': sep = m; break; 86 -: 85: case '\'': // fallthrough 87 -: 86: case '"': c = hq_c; t = m; break; 88 -: 87: case '-': c = hp_c; t = m; break; 89 -: 88: case '#': c = hc_c; t = m; break; 90 -: 89: case '$': c = hv_c; t = m; break; 91 -: 90: default: c = df_c; break; 92 -: 91: } 93 -: 92: 94 -: 93: if (t != -1) 95 -: 94: break; 96 -: 95: 97 -: 96: --m; 98 -: 97: } 99 -: 98: 100 -: 99: if (t != -1) { 101 -: 100: if (c == hc_c || c == hq_c) { 102 -: 101: if (t > sep) 103 -: 102: return c; 104 -: 103: else 105 -: 104: return df_c; 106 -: 105: } else { 107 -: 106: if (t > sep && t > sp) 108 -: 107: return c; 109 -: 108: else 110 -: 109: return df_c; 111 -: 110: } 112 -: 111: } 113 -: 112: 114 -: 113: return df_c; 115 -: 114:} 116 -: 115: 117 -: 116:static char * 118 -: 117:get_highlight_color(const char c, const size_t *qn, const int point) 119 -: 118:{ 120 -: 119: if (c >= '0' && c <= '9') 121 -: 120: return hn_c; 122 -: 121: 123 -: 122: char *cl = cur_color; 124 -: 123: char *p = (char *)NULL; 125 -: 124: static int open_quote = 0; 126 -: 125: 127 -: 126: switch(c) { 128 -: 127: case '{': // fallthrough 129 -: 128: case '}': // fallthrough 130 -: 129: case '(': // fallthrough 131 -: 130: case ')': // fallthrough 132 -: 131: case '[': // fallthrough 133 -: 132: case ']': p = hb_c; break; 134 -: 133: 135 -: 134: case '#': p = hc_c; break; 136 -: 135: case '~': // fallthrough 137 -: 136: case '*': p = he_c; break; 138 -: 137: case '-': p = hp_c; break; 139 -: 138: 140 -: 139: case '\'': 141 -: 140: case '"': 142 -: 141: if ((qn[(c == '\'' ? _SINGLE : _DOUBLE)] + 1) % 2 == 0) { 143 -: 142: open_quote = 0; 144 -: 143: p = df_c; 145 -: 144: } else { 146 -: 145: p = hq_c; 147 -: 146: open_quote = 1; 148 -: 147: } 149 -: 148: break; 150 -: 149: 151 -: 150: case '>': p = hr_c; break; 152 -: 151: case '|': // fallthrough 153 -: 152: case ';': // fallthrough 154 -: 153: case '&': p = hs_c; break; 155 -: 154: case '$': p = hv_c; break; 156 -: 155: 157 -: 156: case ENTER: p = df_c; break; 158 -: 157: 159 -: 158: case ' ': return (char *)NULL; 160 -: 159: // It works, but open_quote should be !open_quote 161 -: 160: if (open_quote && cl != hc_c) 162 -: 161: p = df_c; 163 -: 162: break; 164 -: 163: 165 -: 164: default: 166 -: 165: if (point < rl_end) 167 -: 166: p = get_cur_color(point); 168 -: 167: else if (open_quote && cl != hv_c && cl != hp_c && cl != hc_c) 169 -: 168: p = df_c; 170 -: 169: break; 171 -: 170: } 172 -: 171: 173 -: 172: return p; 174 -: 173:} 175 -: 174: 176 -: 175:static void 177 -: 176:rl_highlight(const char c) 178 -: 177:{ 179 -: 178: if (rl_readline_state & RL_STATE_MOREINPUT) 180 -: 179: return; 181 -: 180: 182 -: 181: if (c < 32 && c != BS && c != ENTER) 183 -: 182: return; 184 -: 183: 185 -: 184: if (rl_end == 1 && (c == BS || c == 127)) { 186 -: 185: cur_color = df_c; 187 -: 186: return; 188 -: 187: } 189 -: 188: 190 -: 189: int m = rl_point; 191 -: 190: size_t qn[2] = {0}; 192 -: 191: m--; 193 -: 192: 194 -: 193: while (m >= 0) { 195 -: 194: if (rl_line_buffer[m] == '\'') 196 -: 195: qn[_SINGLE]++; 197 -: 196: else if (rl_line_buffer[m] == '"') 198 -: 197: qn[_DOUBLE]++; 199 -: 198: --m; 200 -: 199: } 201 -: 200: 202 -: 201: char *p = rl_line_buffer; 203 -: 202: char *cl = (char *)NULL; 204 -: 203: int bk = rl_point; 205 -: 204: rl_point = 0; 206 -: 205: 207 -: 206: for (rl_point = 0; p[rl_point]; rl_point++) 208 -: 207: cl = get_highlight_color(p[rl_point], qn, bk); 209 -: 208: 210 -: 209: cl = get_highlight_color(c, qn, bk); 211 -: 210: 212 -: 211: rl_point = bk; 213 -: 212: 214 -: 213: int skip = 0; 215 -: 214: if ((c == '\'' && qn[_SINGLE] % 2 != 0) 216 -: 215: || (c == '"' && qn[_DOUBLE] % 2 != 0)) 217 -: 216: skip = 1; 218 -: 217: 219 -: 218: if (!skip && cl) { 220 -: 219: cur_color = cl; 221 -: 220: fputs(cl, stdout); 222 -: 221: } 223 -: 222: 224 -: 223: return; 225 -: 224:} */ 226 -: 225: 227 -: 226:/* 228 -: 227:static void 229 -: 228:rl_highlight(const char ch) 230 -: 229:{ 231 -: 230: char *c = cur_color; 232 -: 231: static int skip = 0, open_quote = 0; 233 -: 232: int d = 0; 234 -: 233: 235 -: 234: if (rl_readline_state & RL_STATE_MOREINPUT) 236 -: 235: return; 237 -: 236: 238 -: 237: if (ch < 32 && ch != BS && ch != ENTER) 239 -: 238: return; 240 -: 239: 241 -: 240: if (rl_point == rl_end) { 242 -: 241: if (ch >= '0' && ch <= '9') { 243 -: 242: fputs(hn_c, stdout); 244 -: 243: fflush(stdout); 245 -: 244: cur_color = hn_c; 246 -: 245: return; 247 -: 246: } 248 -: 247: 249 -: 248: switch(ch) { 250 -: 249: case '(': // fallthrough 251 -: 250: case ')': // fallthrough 252 -: 251: case '[': // fallthrough 253 -: 252: case ']': // fallthrough 254 -: 253: case '{': // fallthrough 255 -: 254: case '}': c = hb_c; skip = 0; d = 2; break; 256 -: 255: 257 -: 256: case '#': c = hc_c; d = 1; skip = 0; break; 258 -: 257: 259 -: 258: case '-': c = hp_c; d = 1; skip = 0; break; 260 -: 259: 261 -: 260: case '"': // fallthrough 262 -: 261: case '\'': 263 -: 262: c = hq_c; 264 -: 263: size_t n = 0; 265 -: 264: char *p = rl_line_buffer; 266 -: 265: while (*p) { 267 -: 266: if (*p == ch) 268 -: 267: n++; 269 -: 268: p++; 270 -: 269: } 271 -: 270: if (++n % 2 != 0) { // Opening quote 272 -: 271: // Keep color until closing quote is entered 273 -: 272: skip = 0; 274 -: 273: d = 1; 275 -: 274: open_quote = 1; 276 -: 275: } else { // Closing quote 277 -: 276: // Reset to default color 278 -: 277: c = df_c; 279 -: 278: skip = 1; 280 -: 279: d = 2; 281 -: 280: open_quote = 0; 282 -: 281: } 283 -: 282: break; 284 -: 283: 285 -: 284: case '~': // fallthrough 286 -: 285: case '*': c = he_c; skip = 0; d = 2; break; 287 -: 286: 288 -: 287: case '$': c = hv_c; d = 1; skip = 0; break; 289 -: 288: 290 -: 289: case '>': c = hr_c; skip = 0; d = 2; break; 291 -: 290: 292 -: 291: case '&': // fallthrough 293 -: 292: case ';': // fallthrough 294 -: 293: case '|': c = hs_c; skip = 0; d = 2; break; 295 -: 294: 296 -: 295: case ENTER: c = df_c; skip = 0; break; 297 -: 296: case ' ': 298 -: 297: if (!open_quote && c != hc_c) { 299 -: 298: c = df_c; 300 -: 299: skip = 0; 301 -: 300: } 302 -: 301: break; 303 -: 302: default: 304 -: 303: if (c != hv_c && !open_quote) 305 -: 304: c = df_c; 306 -: 305: break; 307 -: 306: } 308 -: 307: 309 -: 308: if (rl_end == 1 && (ch == BS || ch == 127)) 310 -: 309: c = df_c; 311 -: 310: 312 -: 311: goto END; 313 -: 312: } 314 -: 313: 315 -: 314: int m = rl_point; 316 -: 315: int separator = -1; 317 -: 316: int t = -1; 318 -: 317: size_t q_count[2] = {0}, single = 0, _double = 1; 319 -: 318: skip = 0; 320 -: 319: m--; 321 -: 320: 322 -: 321: while (m >= 0) { 323 -: 322: if (rl_line_buffer[m] == '\'') 324 -: 323: q_count[single]++; 325 -: 324: if (rl_line_buffer[m] == '"') 326 -: 325: q_count[_double]++; 327 -: 326: --m; 328 -: 327: } 329 -: 328: 330 -: 329: m = rl_point; 331 -: 330: if (rl_line_buffer[m] != '"' && rl_line_buffer[m] != '\'') 332 -: 331: --m; 333 -: 332: while (m >= 0) { 334 -: 333: switch(rl_line_buffer[m]) { 335 -: 334: case ' ': separator = m; break; 336 -: 335: 337 -: 336: case '&': // fallthrough 338 -: 337: case ';': // fallthrough 339 -: 338: case '|': d = 1; c = df_c; break; 340 -: 339: 341 -: 340: case '#': c = hc_c; d = 1; t = m; break; 342 -: 341: case '\'': 343 -: 342: if (q_count[single] % 2 != 0) { 344 -: 343: c = hq_c; 345 -: 344: d = 1; 346 -: 345: t = m; 347 -: 346: } 348 -: 347: break; 349 -: 348: case '"': 350 -: 349: if (q_count[_double] % 2 != 0) { 351 -: 350: c = hq_c; 352 -: 351: d = 1; 353 -: 352: t = m; 354 -: 353: } 355 -: 354: break; 356 -: 355: case '$': c = hv_c; d = 1; t = m; break; 357 -: 356: case '-': c = hp_c; d = 1; t = m; break; 358 -: 357: default: c = df_c; break; 359 -: 358: } 360 -: 359: --m; 361 -: 360: 362 -: 361: if (d && c != hc_c && c != hq_c && separator > t) { 363 -: 362: c = df_c; 364 -: 363: continue; 365 -: 364: } 366 -: 365: 367 -: 366: if (d) 368 -: 367: break; 369 -: 368: } 370 -: 369: 371 -: 370: if (rl_end == 1 && (ch == BS || ch == 127)) 372 -: 371: c = df_c; 373 -: 372: 374 -: 373: if (t != -1) 375 -: 374: goto END; 376 -: 375: 377 -: 376: d = 0; 378 -: 377: switch(ch) { 379 -: 378: case '0': // fallthrough 380 -: 379: case '1': // fallthrough 381 -: 380: case '2': // fallthrough 382 -: 381: case '3': // fallthrough 383 -: 382: case '4': // fallthrough 384 -: 383: case '5': // fallthrough 385 -: 384: case '6': // fallthrough 386 -: 385: case '7': // fallthrough 387 -: 386: case '8': // fallthrough 388 -: 387: case '9': c = hn_c; skip = 0; d = 2; break; 389 -: 388: case ' ': return; 390 -: 389: case '(': // fallthrough 391 -: 390: case ')': // fallthrough 392 -: 391: case '[': // fallthrough 393 -: 392: case ']': // fallthrough 394 -: 393: case '{': // fallthrough 395 -: 394: case '}': c = hb_c; skip = 0; d = 2; break; 396 -: 395: case '~': // fallthrough 397 -: 396: case '*': c = he_c; skip = 0; d = 2; break; 398 -: 397: case '>': c = hr_c; skip = 0; d = 2; break; 399 -: 398: case '&': // fallthrough 400 -: 399: case ';': // fallthrough 401 -: 400: case '|': c = hs_c; skip = 0; d = 2; break; 402 -: 401: } 403 -: 402: 404 -: 403: if (rl_end == 1 && (ch == BS || ch == 127)) 405 -: 404: c = df_c; 406 -: 405: 407 -: 406:END: 408 -: 407: if (!skip) { 409 -: 408: fputs(c, stdout); 410 -: 409: fflush(stdout); 411 -: 410: } 412 -: 411: 413 -: 412: if (d == 1) { 414 -: 413: skip = 1; 415 -: 414: } else if (d == 2) { 416 -: 415: skip = 0; 417 -: 416: c = df_c; 418 -: 417: } 419 -: 418: 420 -: 419: cur_color = c; 421 -: 420: return; 422 -: 421:} 423 -: 422:#endif */ 424 -: 423: 425 -: 424:/* This function is automatically called by readline() to handle input. 426 -: 425: * Taken from Bash 1.14.7 and modified to fit our needs. Used 427 -: 426: * to introduce the suggestions system */ 428 -: 427:static int 429function my_rl_getc called 2984 returned 100% blocks executed 34% 430 3004: 428:my_rl_getc(FILE *stream) 431 -: 429:{ 432 -: 430: int result; 433 -: 431: unsigned char c; 434 -: 432: 435 -: 433:#if defined(__GO32__) 436 -: 434: if (isatty(0)) 437 -: 435: return (getkey() & 0x7F); 438 -: 436:#endif /* __GO32__ */ 439 -: 437: 440 -: 438: while(1) { 441 3004: 439: result = (int)read(fileno(stream), &c, sizeof(unsigned char)); 442 3004: 439-block 0 443call 0 returned 3004 444call 1 returned 3004 445 3004: 440: if (result == sizeof(unsigned char)) { 446branch 0 taken 3004 (fallthrough) 447branch 1 taken 0 448 -: 441:/*#ifndef _NO_HIGHLIGHT 449 -: 442: if (highlight) 450 -: 443: rl_highlight(c); 451 -: 444:#endif // _NO_HIGHLIGHT */ 452 -: 445: 453 -: 446:#ifndef _NO_SUGGESTIONS 454 3004: 447: if (suggestions) { 455 3004: 447-block 0 456branch 0 taken 2893 (fallthrough) 457branch 1 taken 111 458 -: 448: /* rl_suggestions returns -1 is C was inserted before 459 -: 449: * the end of the current line, in which case we don't 460 -: 450: * want to return it here (otherwise, it would be added 461 -: 451: * to rl_line_buffer) */ 462 -: 452:#ifdef __FreeBSD__ 463 -: 453: /* For the time being, suggestions do not work on the FreeBSD 464 -: 454: * console (vt). The escape code to retrieve the current cursor 465 -: 455: * position doesn't seem to work. Switching the console to 'sc' 466 -: 456: * solves the issue */ 467 -: 457: if (flags & GUI) { 468 -: 458: if (rl_suggestions(c) == -1) { 469 -: 459: rl_redisplay(); 470 -: 460: continue; 471 -: 461: } 472 -: 462: } else if (freebsd_sc_console && rl_suggestions(c) == -1) { 473 -: 463: rl_redisplay(); 474 -: 464: continue; 475 -: 465: } 476 -: 466:#else 477 2893: 467: if (rl_suggestions(c) == -1) { 478 2893: 467-block 0 479call 0 returned 2893 480branch 1 taken 20 (fallthrough) 481branch 2 taken 2873 482 20: 468: rl_redisplay(); 483 20: 468-block 0 484call 0 returned 20 485 20: 469: continue; 486unconditional 0 taken 20 487 -: 470: } 488 -: 471:#endif /* __FreeBSD__ */ 489 -: 472: } 490 -: 473:#endif /* _NO_SUGGESTIONS */ 491 2984: 474: return (c); 492 2984: 474-block 0 493unconditional 0 taken 2984 494 -: 475: } 495 -: 476: /* If zero characters are returned, then the file that we are 496 -: 477: reading from is empty! Return EOF in that case. */ 497 #####: 478: if (result == 0) 498 %%%%%: 478-block 0 499branch 0 never executed 500branch 1 never executed 501 #####: 479: return (EOF); 502 %%%%%: 479-block 0 503unconditional 0 never executed 504 -: 480: 505 -: 481:#if defined(EWOULDBLOCK) 506 #####: 482: if (errno == EWOULDBLOCK) { 507 %%%%%: 482-block 0 508branch 0 never executed 509branch 1 never executed 510 -: 483: int xflags; 511 -: 484: 512 #####: 485: if ((xflags = fcntl(fileno(stream), F_GETFL, 0)) < 0) 513 %%%%%: 485-block 0 514call 0 never executed 515call 1 never executed 516branch 2 never executed 517branch 3 never executed 518 #####: 486: return (EOF); 519 %%%%%: 486-block 0 520unconditional 0 never executed 521 #####: 487: if (xflags & O_NDELAY) { 522 %%%%%: 487-block 0 523branch 0 never executed 524branch 1 never executed 525 -: 488:/* xflags &= ~O_NDELAY; */ 526 #####: 489: fcntl(fileno(stream), F_SETFL, flags); 527 %%%%%: 489-block 0 528call 0 never executed 529call 1 never executed 530 #####: 490: continue; 531unconditional 0 never executed 532 -: 491: } 533 #####: 492: continue; 534 %%%%%: 492-block 0 535unconditional 0 never executed 536 -: 493: } 537 -: 494:#endif /* EWOULDBLOCK */ 538 -: 495: 539 -: 496:#if defined(_POSIX_VERSION) && defined(EAGAIN) && defined(O_NONBLOCK) 540 #####: 497: if (errno == EAGAIN) { 541 %%%%%: 497-block 0 542branch 0 never executed 543branch 1 never executed 544 -: 498: int xflags; 545 -: 499: 546 #####: 500: if ((xflags = fcntl(fileno(stream), F_GETFL, 0)) < 0) 547 %%%%%: 500-block 0 548call 0 never executed 549call 1 never executed 550branch 2 never executed 551branch 3 never executed 552 #####: 501: return (EOF); 553 %%%%%: 501-block 0 554unconditional 0 never executed 555 #####: 502: if (xflags & O_NONBLOCK) { 556 %%%%%: 502-block 0 557branch 0 never executed 558branch 1 never executed 559 -: 503:// xflags &= ~O_NONBLOCK; 560 #####: 504: fcntl(fileno(stream), F_SETFL, flags); 561 %%%%%: 504-block 0 562call 0 never executed 563call 1 never executed 564 #####: 505: continue; 565unconditional 0 never executed 566 -: 506: } 567 -: 507: } 568 -: 508:#endif /* _POSIX_VERSION && EAGAIN && O_NONBLOCK */ 569 -: 509: 570 -: 510:#if !defined(__GO32__) 571 -: 511: /* If the error that we received was SIGINT, then try again, 572 -: 512: this is simply an interrupted system call to read (). 573 -: 513: Otherwise, some error ocurred, also signifying EOF. */ 574 #####: 514: if (errno != EINTR) 575 %%%%%: 514-block 0 576branch 0 never executed 577branch 1 never executed 578 #####: 515: return (EOF); 579 %%%%%: 515-block 0 580unconditional 0 never executed 581 -: 516:#endif /* !__GO32__ */ 582 -: 517: } 583 -: 518:} 584 -: 519: 585 -: 520:/* Simply check a single chartacter (c) against the quoting characters 586 -: 521: * list defined in the qc global array (which takes its values from 587 -: 522: * rl_filename_quote_characters */ 588 -: 523:int 589function is_quote_char called 2622 returned 100% blocks executed 89% 590 2622: 524:is_quote_char(const char c) 591 -: 525:{ 592 2622: 526: if (c == '\0' || !qc) 593 2622: 526-block 0 594branch 0 taken 2622 (fallthrough) 595branch 1 taken 0 596 2622: 526-block 1 597branch 2 taken 0 (fallthrough) 598branch 3 taken 2622 599 #####: 527: return -1; 600 %%%%%: 527-block 0 601unconditional 0 never executed 602 -: 528: 603 2622: 529: char *p = qc; 604 -: 530: 605 70785: 531: while (*p) { 606 2622: 531-block 0 607unconditional 0 taken 2622 608 70785: 531-block 1 609branch 1 taken 68164 610branch 2 taken 2621 (fallthrough) 611 68164: 532: if (c == *(p++)) 612 68164: 532-block 0 613branch 0 taken 1 (fallthrough) 614branch 1 taken 68163 615 1: 533: return 1; 616 1: 533-block 0 617unconditional 0 taken 1 618 -: 534: } 619 -: 535: 620 2621: 536: return 0; 621 2621: 536-block 0 622unconditional 0 taken 2621 623 -: 537:} 624 -: 538: 625 -: 539:char * 626function rl_no_hist called 37 returned 100% blocks executed 79% 627 37: 540:rl_no_hist(const char *prompt) 628 -: 541:{ 629 37: 542: int bk = suggestions; 630 37: 543: suggestions = 0; 631 37: 544: stifle_history(0); /* Prevent readline from using the history 632 37: 544-block 0 633call 0 returned 37 634 -: 545: setting */ 635 37: 546: char *input = readline(prompt); 636call 0 returned 37 637 37: 547: unstifle_history(); /* Reenable history */ 638call 0 returned 37 639 37: 548: read_history(hist_file); /* Reload history lines from file */ 640call 0 returned 37 641 37: 549: suggestions = bk; 642 -: 550: 643 37: 551: if (input) { 644branch 0 taken 37 (fallthrough) 645branch 1 taken 0 646 -: 552: /* Make sure input isn't empty string */ 647 37: 553: if (!*input) { 648 37: 553-block 0 649branch 0 taken 0 (fallthrough) 650branch 1 taken 37 651 #####: 554: free(input); 652 #####: 555: return (char *)NULL; 653 %%%%%: 555-block 0 654unconditional 0 never executed 655 -: 556: } 656 -: 557: 657 -: 558: /* Check we have some non-blank char */ 658 37: 559: int no_blank = 0; 659 37: 560: char *p = input; 660 -: 561: 661 37: 562: while (*p) { 662 37: 562-block 0 663unconditional 0 taken 37 664 37: 562-block 1 665branch 1 taken 37 666branch 2 taken 0 (fallthrough) 667 37: 563: if (*p != ' ' && *p != '\n' && *p != '\t') { 668 37: 563-block 0 669branch 0 taken 37 (fallthrough) 670branch 1 taken 0 671 37: 563-block 1 672branch 2 taken 37 (fallthrough) 673branch 3 taken 0 674 37: 563-block 2 675branch 4 taken 37 (fallthrough) 676branch 5 taken 0 677 37: 564: no_blank = 1; 678 37: 565: break; 679 37: 565-block 0 680unconditional 0 taken 37 681 -: 566: } 682 #####: 567: p++; 683 %%%%%: 567-block 0 684unconditional 0 never executed 685 -: 568: } 686 -: 569: 687 37: 570: if (!no_blank) { 688 37: 570-block 0 689branch 0 taken 0 (fallthrough) 690branch 1 taken 37 691 #####: 571: free(input); 692 #####: 572: return (char *)NULL; 693 %%%%%: 572-block 0 694unconditional 0 never executed 695 -: 573: } 696 -: 574: 697 37: 575: return input; 698 37: 575-block 0 699unconditional 0 taken 37 700 -: 576: } 701 -: 577: 702 #####: 578: return (char *)NULL; 703 %%%%%: 578-block 0 704unconditional 0 never executed 705 -: 579:} 706 -: 580: 707 -: 581:/* Used by readline to check if a char in the string being completed is 708 -: 582: * quoted or not */ 709 -: 583:static int 710function quote_detector called 0 returned 0% blocks executed 0% 711 #####: 584:quote_detector(char *line, int index) 712 -: 585:{ 713 #####: 586: if (index > 0 && line[index - 1] == '\\' && !quote_detector(line, index - 1)) 714 %%%%%: 586-block 0 715branch 0 never executed 716branch 1 never executed 717 %%%%%: 586-block 1 718branch 2 never executed 719branch 3 never executed 720 %%%%%: 586-block 2 721call 4 never executed 722branch 5 never executed 723branch 6 never executed 724 #####: 587: return 1; 725 %%%%%: 587-block 0 726unconditional 0 never executed 727 -: 588: 728 #####: 589: return 0; 729 %%%%%: 589-block 0 730unconditional 0 never executed 731 -: 590:} 732 -: 591: 733 -: 592:/* Performs bash-style filename quoting for readline (put a backslash 734 -: 593: * before any char listed in rl_filename_quote_characters. 735 -: 594: * Modified version of: 736 -: 595: * https://utcc.utoronto.ca/~cks/space/blog/programming/ReadlineQuotingExample*/ 737 -: 596:static char * 738function my_rl_quote called 0 returned 0% blocks executed 0% 739 #####: 597:my_rl_quote(char *text, int mt, char *qp) 740 -: 598:{ 741 -: 599: /* NOTE: mt and qp arguments are not used here, but are required by 742 -: 600: * rl_filename_quoting_function */ 743 -: 601: UNUSED(mt); UNUSED(qp); 744 -: 602: 745 -: 603: /* 746 -: 604: * How it works: P and R are pointers to the same memory location 747 -: 605: * initialized (calloced) twice as big as the line that needs to be 748 -: 606: * quoted (in case all chars in the line need to be quoted); TP is a 749 -: 607: * pointer to TEXT, which contains the string to be quoted. We move 750 -: 608: * through TP to find all chars that need to be quoted ("a's" becomes 751 -: 609: * "a\'s", for example). At this point we cannot return P, since this 752 -: 610: * pointer is at the end of the string, so that we return R instead, 753 -: 611: * which is at the beginning of the same string pointed to by P. 754 -: 612: * */ 755 #####: 613: char *r = (char *)NULL, *p = (char *)NULL, *tp = (char *)NULL; 756 -: 614: 757 #####: 615: size_t text_len = strlen(text); 758 -: 616: /* Worst case: every character of text needs to be escaped. In this 759 -: 617: * case we need 2x text's bytes plus the NULL byte. */ 760 #####: 618: p = (char *)xnmalloc((text_len * 2) + 1, sizeof(char)); 761 %%%%%: 618-block 0 762call 0 never executed 763 #####: 619: r = p; 764 -: 620: 765 #####: 621: if (r == NULL) 766branch 0 never executed 767branch 1 never executed 768 #####: 622: return (char *)NULL; 769 %%%%%: 622-block 0 770unconditional 0 never executed 771 -: 623: 772 -: 624: /* Escape whatever char that needs to be escaped */ 773 #####: 625: for (tp = text; *tp; tp++) { 774 %%%%%: 625-block 0 775unconditional 0 never executed 776 %%%%%: 625-block 1 777branch 1 never executed 778branch 2 never executed 779 #####: 626: if (is_quote_char(*tp)) 780 %%%%%: 626-block 0 781call 0 never executed 782branch 1 never executed 783branch 2 never executed 784 #####: 627: *p++ = '\\'; 785 %%%%%: 627-block 0 786unconditional 0 never executed 787 -: 628: 788 #####: 629: *p++ = *tp; 789 %%%%%: 629-block 0 790unconditional 0 never executed 791 -: 630: } 792 -: 631: 793 -: 632: /* Add a final null byte to the string */ 794 #####: 633: *p = '\0'; 795 #####: 634: return r; 796 %%%%%: 634-block 0 797unconditional 0 never executed 798 -: 635:} 799 -: 636: 800 -: 637:/* This is the filename_completion_function() function of an old Bash 801 -: 638: * release (1.14.7) modified to fit CliFM needs */ 802 -: 639:static char * 803function my_rl_path_completion called 4523 returned 100% blocks executed 48% 804 4523: 640:my_rl_path_completion(const char *text, int state) 805 -: 641:{ 806 4523: 642: if (!text || !*text) 807 4523: 642-block 0 808branch 0 taken 4523 (fallthrough) 809branch 1 taken 0 810 4523: 642-block 1 811branch 2 taken 9 (fallthrough) 812branch 3 taken 4514 813 9: 643: return (char *)NULL; 814 9: 643-block 0 815unconditional 0 taken 9 816 -: 644: /* state is zero before completion, and 1 ... n after getting 817 -: 645: * possible completions. Example: 818 -: 646: * cd Do[TAB] -> state 0 819 -: 647: * cuments/ -> state 1 820 -: 648: * wnloads/ -> state 2 821 -: 649: * */ 822 -: 650: 823 -: 651: /* Dequote string to be completed (text), if necessary */ 824 -: 652: static char *tmp_text = (char *)NULL; 825 -: 653: 826 4514: 654: if (strchr(text, '\\')) { 827 4514: 654-block 0 828branch 0 taken 0 (fallthrough) 829branch 1 taken 4514 830 #####: 655: char *p = savestring(text, strlen(text)); 831 %%%%%: 655-block 0 832call 0 never executed 833 #####: 656: tmp_text = dequote_str(p, 0); 834call 0 never executed 835 #####: 657: free(p); 836 #####: 658: p = (char *)NULL; 837 #####: 659: if (!tmp_text) 838branch 0 never executed 839branch 1 never executed 840 #####: 660: return (char *)NULL; 841 %%%%%: 660-block 0 842unconditional 0 never executed 843 -: 661: } 844 -: 662: 845 4514: 663: if (*text == '.' && text[1] == '.' && text[2] == '.') { 846 4514: 663-block 0 847branch 0 taken 6 (fallthrough) 848branch 1 taken 4508 849 6: 663-block 1 850branch 2 taken 2 (fallthrough) 851branch 3 taken 4 852 2: 663-block 2 853branch 4 taken 2 (fallthrough) 854branch 5 taken 0 855 2: 664: char *p = savestring(text, strlen(text)); 856 2: 664-block 0 857call 0 returned 2 858 2: 665: tmp_text = fastback(p); 859call 0 returned 2 860 -: 666: 861 2: 667: free(p); 862 2: 668: p = (char *)NULL; 863 -: 669: 864 2: 670: if (!tmp_text) 865branch 0 taken 0 (fallthrough) 866branch 1 taken 2 867 #####: 671: return (char *)NULL; 868 %%%%%: 671-block 0 869unconditional 0 never executed 870 -: 672: } 871 -: 673: 872 -: 674:/* int rl_complete_with_tilde_expansion = 0; */ 873 -: 675: /* ~/Doc -> /home/user/Doc */ 874 -: 676: 875 -: 677: static DIR *directory; 876 -: 678: static char *filename = (char *)NULL; 877 -: 679: static char *dirname = (char *)NULL; 878 -: 680: static char *users_dirname = (char *)NULL; 879 -: 681: static size_t filename_len; 880 -: 682: static int match, ret; 881 4514: 683: struct dirent *ent = (struct dirent *)NULL; 882 -: 684: static int exec = 0, exec_path = 0; 883 -: 685: static char *dir_tmp = (char *)NULL; 884 -: 686: static char tmp[PATH_MAX]; 885 -: 687: 886 -: 688: /* If we don't have any state, then do some initialization. */ 887 4514: 689: if (!state) { 888 4514: 689-block 0 889branch 0 taken 401 (fallthrough) 890branch 1 taken 4113 891 -: 690: char *temp; 892 -: 691: 893 401: 692: if (dirname) 894 401: 692-block 0 895branch 0 taken 0 (fallthrough) 896branch 1 taken 401 897 #####: 693: free(dirname); 898 %%%%%: 693-block 0 899unconditional 0 never executed 900 401: 694: if (filename) 901 401: 694-block 0 902branch 0 taken 0 (fallthrough) 903branch 1 taken 401 904 #####: 695: free(filename); 905 %%%%%: 695-block 0 906unconditional 0 never executed 907 401: 696: if (users_dirname) 908 401: 696-block 0 909branch 0 taken 0 (fallthrough) 910branch 1 taken 401 911 #####: 697: free(users_dirname); 912 %%%%%: 697-block 0 913unconditional 0 never executed 914 -: 698: 915 -: 699: /* tmp_text is true whenever text was dequoted */ 916 401: 700: size_t text_len = strlen((tmp_text) ? tmp_text : text); 917 401: 700-block 0 918branch 0 taken 1 (fallthrough) 919branch 1 taken 400 920 1: 700-block 1 921unconditional 2 taken 1 922 400: 700-block 2 923unconditional 3 taken 400 924 401: 701: if (text_len) 925 401: 701-block 0 926branch 0 taken 401 (fallthrough) 927branch 1 taken 0 928 401: 702: filename = savestring((tmp_text) ? tmp_text : text, text_len); 929 401: 702-block 0 930branch 0 taken 1 (fallthrough) 931branch 1 taken 400 932 1: 702-block 1 933unconditional 2 taken 1 934 400: 702-block 2 935unconditional 3 taken 400 936 401: 702-block 3 937call 4 returned 401 938unconditional 5 taken 401 939 -: 703: else 940 #####: 704: filename = savestring("", 1); 941 %%%%%: 704-block 0 942call 0 never executed 943unconditional 1 never executed 944 -: 705: 945 401: 706: if (!*text) 946 401: 706-block 0 947branch 0 taken 0 (fallthrough) 948branch 1 taken 401 949 #####: 707: text = "."; 950 %%%%%: 707-block 0 951unconditional 0 never executed 952 -: 708: 953 401: 709: if (text_len) 954 401: 709-block 0 955branch 0 taken 401 (fallthrough) 956branch 1 taken 0 957 401: 710: dirname = savestring((tmp_text) ? tmp_text : text, text_len); 958 401: 710-block 0 959branch 0 taken 1 (fallthrough) 960branch 1 taken 400 961 1: 710-block 1 962unconditional 2 taken 1 963 400: 710-block 2 964unconditional 3 taken 400 965 401: 710-block 3 966call 4 returned 401 967unconditional 5 taken 401 968 -: 711: else 969 #####: 712: dirname = savestring("", 1); 970 %%%%%: 712-block 0 971call 0 never executed 972unconditional 1 never executed 973 -: 713: 974 401: 714: if (dirname[0] == '.' && dirname[1] == '/') 975 401: 714-block 0 976branch 0 taken 3 (fallthrough) 977branch 1 taken 398 978 3: 714-block 1 979branch 2 taken 0 (fallthrough) 980branch 3 taken 3 981 #####: 715: exec = 1; 982 %%%%%: 715-block 0 983unconditional 0 never executed 984 -: 716: else 985 401: 717: exec = 0; 986 401: 717-block 0 987unconditional 0 taken 401 988 -: 718: 989 -: 719: /* Get everything after last slash */ 990 401: 720: temp = strrchr(dirname, '/'); 991 -: 721: 992 401: 722: if (temp) { 993 401: 722-block 0 994branch 0 taken 40 (fallthrough) 995branch 1 taken 361 996 40: 723: strcpy(filename, ++temp); 997 40: 724: *temp = '\0'; 998 40: 724-block 0 999unconditional 0 taken 40 1000 -: 725: } else { 1001 361: 726: strcpy(dirname, "."); 1002 361: 726-block 0 1003unconditional 0 taken 361 1004 -: 727: } 1005 -: 728: 1006 -: 729: /* We aren't done yet. We also support the "~user" syntax. */ 1007 -: 730: 1008 -: 731: /* Save the version of the directory that the user typed. */ 1009 401: 732: size_t dirname_len = strlen(dirname); 1010 -: 733: 1011 401: 734: users_dirname = savestring(dirname, dirname_len); 1012 401: 734-block 0 1013call 0 returned 401 1014 -: 735: /* { */ 1015 -: 736: char *temp_dirname; 1016 -: 737: int replace_dirname; 1017 -: 738: 1018 401: 739: temp_dirname = tilde_expand(dirname); 1019call 0 returned 401 1020 401: 740: free(dirname); 1021 401: 741: dirname = temp_dirname; 1022 -: 742: 1023 401: 743: replace_dirname = 0; 1024 -: 744: 1025 401: 745: if (rl_directory_completion_hook) 1026branch 0 taken 0 (fallthrough) 1027branch 1 taken 401 1028 #####: 746: replace_dirname = (*rl_directory_completion_hook)(&dirname); 1029 %%%%%: 746-block 0 1030call 0 never executed 1031unconditional 1 never executed 1032 -: 747: 1033 401: 748: if (replace_dirname) { 1034 401: 748-block 0 1035branch 0 taken 0 (fallthrough) 1036branch 1 taken 401 1037 #####: 749: free(users_dirname); 1038 #####: 750: users_dirname = savestring(dirname, dirname_len); 1039 %%%%%: 750-block 0 1040call 0 never executed 1041unconditional 1 never executed 1042 -: 751: } 1043 -: 752: /* } */ 1044 401: 753: directory = opendir(dirname); 1045 401: 753-block 0 1046call 0 returned 401 1047 401: 754: filename_len = strlen(filename); 1048 -: 755: 1049 401: 756: rl_filename_completion_desired = 1; 1050unconditional 0 taken 401 1051 -: 757: } 1052 -: 758: 1053 4514: 759: if (tmp_text) { 1054 4514: 759-block 0 1055branch 0 taken 2 (fallthrough) 1056branch 1 taken 4512 1057 2: 760: free(tmp_text); 1058 2: 761: tmp_text = (char *)NULL; 1059 2: 761-block 0 1060unconditional 0 taken 2 1061 -: 762: } 1062 -: 763: 1063 -: 764: /* Now that we have some state, we can read the directory. If we found 1064 -: 765: * a match among files in dir, break the loop and print the match */ 1065 -: 766: 1066 4514: 767: match = 0; 1067 -: 768: 1068 4514: 769: size_t dirname_len = 0; 1069 4514: 770: if (dirname) 1070 4514: 770-block 0 1071branch 0 taken 4514 (fallthrough) 1072branch 1 taken 0 1073 4514: 771: dirname_len = strlen(dirname); 1074 4514: 771-block 0 1075unconditional 0 taken 4514 1076 -: 772: 1077 -: 773: /* This block is used only in case of "/path/./" to remove the 1078 -: 774: * ending "./" from dirname and to be able to perform thus the 1079 -: 775: * executable check via access() */ 1080 4514: 776: exec_path = 0; 1081 -: 777: 1082 4514: 778: if (dirname_len > 2) { 1083 4514: 778-block 0 1084branch 0 taken 4118 (fallthrough) 1085branch 1 taken 396 1086 -: 779: 1087 4118*: 780: if (dirname[dirname_len - 3] == '/' && dirname[dirname_len - 2] == '.' 1088 4118: 780-block 0 1089branch 0 taken 0 (fallthrough) 1090branch 1 taken 4118 1091 %%%%%: 780-block 1 1092branch 2 never executed 1093branch 3 never executed 1094 #####: 781: && dirname[dirname_len - 1] == '/') { 1095 %%%%%: 781-block 0 1096branch 0 never executed 1097branch 1 never executed 1098 #####: 782: dir_tmp = savestring(dirname, dirname_len); 1099 %%%%%: 782-block 0 1100call 0 never executed 1101 -: 783: 1102 #####: 784: if (dir_tmp) { 1103branch 0 never executed 1104branch 1 never executed 1105 #####: 785: dir_tmp[dirname_len - 2] = '\0'; 1106 #####: 786: exec_path = 1; 1107 %%%%%: 786-block 0 1108unconditional 0 never executed 1109 -: 787: } 1110 -: 788: } 1111 -: 789: } 1112 -: 790: 1113 -: 791: /* ############### COMPLETION FILTER ################## */ 1114 -: 792: /* # This is the heart of the function # 1115 -: 793: * #################################################### */ 1116 -: 794: mode_t type; 1117 -: 795: 1118 75929: 796: while (directory && (ent = readdir(directory))) { 1119 4514: 796-block 0 1120unconditional 0 taken 4514 1121 75929: 796-block 1 1122branch 1 taken 75923 (fallthrough) 1123branch 2 taken 6 1124 75923: 796-block 2 1125call 3 returned 75923 1126branch 4 taken 75528 1127branch 5 taken 395 (fallthrough) 1128 -: 797:#if !defined(_DIRENT_HAVE_D_TYPE) 1129 -: 798: struct stat attr; 1130 -: 799: if (!dirname || (*dirname == '.' && !*(dirname + 1))) 1131 -: 800: xstrsncpy(tmp, ent->d_name, PATH_MAX); 1132 -: 801: else 1133 -: 802: snprintf(tmp, PATH_MAX, "%s%s", dirname, ent->d_name); 1134 -: 803: 1135 -: 804: if (lstat(tmp, &attr) == -1) { 1136 -: 805: continue; 1137 -: 806: } 1138 -: 807: 1139 -: 808: switch (attr.st_mode & S_IFMT) { 1140 -: 809: case S_IFBLK: type = DT_BLK; break; 1141 -: 810: case S_IFCHR: type = DT_CHR; break; 1142 -: 811: case S_IFDIR: type = DT_DIR; break; 1143 -: 812: case S_IFIFO: type = DT_FIFO; break; 1144 -: 813: case S_IFLNK: type = DT_LNK; break; 1145 -: 814: case S_IFREG: type = DT_REG; break; 1146 -: 815: case S_IFSOCK: type = DT_SOCK; break; 1147 -: 816: default: type = DT_UNKNOWN; break; 1148 -: 817: } 1149 -: 818:#else 1150 75528: 819: type = ent->d_type; 1151 -: 820:#endif /* !_DIRENT_HAVE_D_TYPE */ 1152 -: 821: 1153 -: 822: /* If the user entered nothing before TAB (ex: "cd [TAB]") */ 1154 75528: 823: if (!filename_len) { 1155 75528: 823-block 0 1156branch 0 taken 3561 (fallthrough) 1157branch 1 taken 71967 1158 -: 824: /* Exclude "." and ".." as possible completions */ 1159 3561: 825: if (SELFORPARENT(ent->d_name)) 1160 3561: 825-block 0 1161branch 0 taken 2 (fallthrough) 1162branch 1 taken 3559 1163 2: 825-block 1 1164branch 2 taken 1 (fallthrough) 1165branch 3 taken 1 1166 1: 825-block 2 1167branch 4 taken 1 (fallthrough) 1168branch 5 taken 0 1169 1: 825-block 3 1170branch 6 taken 1 (fallthrough) 1171branch 7 taken 0 1172 2: 826: continue; 1173 2: 826-block 0 1174unconditional 0 taken 2 1175 -: 827: 1176 -: 828: /* If 'cd', match only dirs or symlinks to dir */ 1177 3559: 829: if (*rl_line_buffer == 'c' 1178 3559: 829-block 0 1179branch 0 taken 0 (fallthrough) 1180branch 1 taken 3559 1181 #####: 830: && strncmp(rl_line_buffer, "cd ", 3) == 0) { 1182 %%%%%: 830-block 0 1183branch 0 never executed 1184branch 1 never executed 1185 #####: 831: ret = -1; 1186 -: 832: 1187 #####: 833: switch (type) { 1188 %%%%%: 833-block 0 1189branch 0 never executed 1190branch 1 never executed 1191branch 2 never executed 1192 #####: 834: case DT_LNK: 1193 #####: 835: if (dirname[0] == '.' && !dirname[1]) { 1194 %%%%%: 835-block 0 1195branch 0 never executed 1196branch 1 never executed 1197 %%%%%: 835-block 1 1198branch 2 never executed 1199branch 3 never executed 1200 #####: 836: ret = get_link_ref(ent->d_name); 1201 %%%%%: 836-block 0 1202call 0 never executed 1203unconditional 1 never executed 1204 -: 837: } else { 1205 #####: 838: snprintf(tmp, PATH_MAX, "%s%s", dirname, ent->d_name); 1206 #####: 839: ret = get_link_ref(tmp); 1207 %%%%%: 839-block 0 1208call 0 never executed 1209unconditional 1 never executed 1210 -: 840: } 1211 -: 841: 1212 #####: 842: if (ret == S_IFDIR) 1213 %%%%%: 842-block 0 1214branch 0 never executed 1215branch 1 never executed 1216 #####: 843: match = 1; 1217 %%%%%: 843-block 0 1218unconditional 0 never executed 1219 -: 844: 1220 #####: 845: break; 1221 %%%%%: 845-block 0 1222unconditional 0 never executed 1223 -: 846: 1224 #####: 847: case DT_DIR: 1225 #####: 848: match = 1; 1226 #####: 849: break; 1227 %%%%%: 849-block 0 1228unconditional 0 never executed 1229 -: 850: 1230 #####: 851: default: 1231 #####: 852: break; 1232 %%%%%: 852-block 0 1233unconditional 0 never executed 1234 -: 853: } 1235 -: 854: } 1236 -: 855: 1237 -: 856: /* If 'open', allow only reg files, dirs, and symlinks */ 1238 3559: 857: else if (*rl_line_buffer == 'o' 1239 3559: 857-block 0 1240branch 0 taken 0 (fallthrough) 1241branch 1 taken 3559 1242 #####: 858: && (strncmp(rl_line_buffer, "o ", 2) == 0 1243 %%%%%: 858-block 0 1244branch 0 never executed 1245branch 1 never executed 1246 #####: 859: || strncmp(rl_line_buffer, "open ", 5) == 0)) { 1247 %%%%%: 859-block 0 1248branch 0 never executed 1249branch 1 never executed 1250 #####: 860: ret = -1; 1251 -: 861: 1252 #####: 862: switch (type) { 1253 %%%%%: 862-block 0 1254branch 0 never executed 1255branch 1 never executed 1256branch 2 never executed 1257 #####: 863: case DT_LNK: 1258 #####: 864: if (dirname[0] == '.' && !dirname[1]) { 1259 %%%%%: 864-block 0 1260branch 0 never executed 1261branch 1 never executed 1262 %%%%%: 864-block 1 1263branch 2 never executed 1264branch 3 never executed 1265 #####: 865: ret = get_link_ref(ent->d_name); 1266 %%%%%: 865-block 0 1267call 0 never executed 1268unconditional 1 never executed 1269 -: 866: } else { 1270 #####: 867: snprintf(tmp, PATH_MAX, "%s%s", dirname, ent->d_name); 1271 #####: 868: ret = get_link_ref(tmp); 1272 %%%%%: 868-block 0 1273call 0 never executed 1274unconditional 1 never executed 1275 -: 869: } 1276 -: 870: 1277 #####: 871: if (ret == S_IFDIR || ret == S_IFREG) 1278 %%%%%: 871-block 0 1279branch 0 never executed 1280branch 1 never executed 1281 %%%%%: 871-block 1 1282branch 2 never executed 1283branch 3 never executed 1284 #####: 872: match = 1; 1285 %%%%%: 872-block 0 1286unconditional 0 never executed 1287 -: 873: 1288 #####: 874: break; 1289 %%%%%: 874-block 0 1290unconditional 0 never executed 1291 -: 875: 1292 #####: 876: case DT_REG: /* fallthrough */ 1293 #####: 877: case DT_DIR: match = 1; break; 1294 %%%%%: 877-block 0 1295unconditional 0 never executed 1296 -: 878: 1297 #####: 879: default: break; 1298 %%%%%: 879-block 0 1299unconditional 0 never executed 1300 -: 880: } 1301 -: 881: } 1302 -: 882: 1303 -: 883: /* If 'trash', allow only reg files, dirs, symlinks, pipes 1304 -: 884: * and sockets. You should not trash a block or a character 1305 -: 885: * device */ 1306 3559: 886: else if (*rl_line_buffer == 't' 1307 3559: 886-block 0 1308branch 0 taken 0 (fallthrough) 1309branch 1 taken 3559 1310 #####: 887: && (strncmp(rl_line_buffer, "t ", 2) == 0 1311 %%%%%: 887-block 0 1312branch 0 never executed 1313branch 1 never executed 1314 #####: 888: || strncmp(rl_line_buffer, "tr ", 2) == 0 1315 %%%%%: 888-block 0 1316branch 0 never executed 1317branch 1 never executed 1318 #####: 889: || strncmp(rl_line_buffer, "trash ", 6) == 0)) { 1319 %%%%%: 889-block 0 1320branch 0 never executed 1321branch 1 never executed 1322 -: 890: 1323 #####: 891: if (type != DT_BLK && type != DT_CHR) 1324 %%%%%: 891-block 0 1325branch 0 never executed 1326branch 1 never executed 1327 %%%%%: 891-block 1 1328branch 2 never executed 1329branch 3 never executed 1330 #####: 892: match = 1; 1331 %%%%%: 892-block 0 1332unconditional 0 never executed 1333 -: 893: } 1334 -: 894: 1335 -: 895: /* If "./", list only executable regular files */ 1336 3559: 896: else if (exec) { 1337 3559: 896-block 0 1338branch 0 taken 0 (fallthrough) 1339branch 1 taken 3559 1340 #####: 897: if (type == DT_REG && access(ent->d_name, X_OK) == 0) 1341 %%%%%: 897-block 0 1342branch 0 never executed 1343branch 1 never executed 1344 %%%%%: 897-block 1 1345call 2 never executed 1346branch 3 never executed 1347branch 4 never executed 1348 #####: 898: match = 1; 1349 %%%%%: 898-block 0 1350unconditional 0 never executed 1351 -: 899: } 1352 -: 900: 1353 -: 901: /* If "/path/./", list only executable regular files */ 1354 3559: 902: else if (exec_path) { 1355 3559: 902-block 0 1356branch 0 taken 0 (fallthrough) 1357branch 1 taken 3559 1358 #####: 903: if (type == DT_REG) { 1359 %%%%%: 903-block 0 1360branch 0 never executed 1361branch 1 never executed 1362 -: 904: /* dir_tmp is dirname less "./", already 1363 -: 905: * allocated before the while loop */ 1364 #####: 906: snprintf(tmp, PATH_MAX, "%s%s", dir_tmp, ent->d_name); 1365 -: 907: 1366 #####: 908: if (access(tmp, X_OK) == 0) 1367 %%%%%: 908-block 0 1368call 0 never executed 1369branch 1 never executed 1370branch 2 never executed 1371 #####: 909: match = 1; 1372 %%%%%: 909-block 0 1373unconditional 0 never executed 1374 -: 910: } 1375 -: 911: } 1376 -: 912: 1377 -: 913: /* No filter for everything else. Just print whatever is 1378 -: 914: * there */ 1379 -: 915: else 1380 3559: 916: match = 1; 1381 3559: 916-block 0 1382unconditional 0 taken 3559 1383 -: 917: } 1384 -: 918: 1385 -: 919: /* If there is at least one char to complete (ex: "cd .[TAB]") */ 1386 -: 920: else { 1387 -: 921: /* Check if possible completion match up to the length of 1388 -: 922: * filename. */ 1389 71967: 923: if (case_sens_path_comp) { 1390 71967: 923-block 0 1391branch 0 taken 7 (fallthrough) 1392branch 1 taken 71960 1393 7: 924: if (*ent->d_name != *filename 1394 7: 924-block 0 1395branch 0 taken 0 (fallthrough) 1396branch 1 taken 7 1397 #####: 925: || (strncmp(filename, ent->d_name, filename_len) != 0)) 1398 %%%%%: 925-block 0 1399branch 0 never executed 1400branch 1 never executed 1401 7: 926: continue; 1402 7: 926-block 0 1403unconditional 0 taken 7 1404 -: 927: } else { 1405 71960: 928: if (TOUPPER(*ent->d_name) != TOUPPER(*filename) 1406 71960: 928-block 0 1407branch 0 taken 69903 (fallthrough) 1408branch 1 taken 2057 1409 69903: 928-block 1 1410branch 2 taken 69903 (fallthrough) 1411branch 3 taken 0 1412 69903: 928-block 2 1413unconditional 4 taken 69903 1414 2057: 928-block 3 1415unconditional 5 taken 2057 1416 71960: 928-block 4 1417branch 6 taken 60573 (fallthrough) 1418branch 7 taken 11387 1419 60573: 928-block 5 1420branch 8 taken 60573 (fallthrough) 1421branch 9 taken 0 1422 60573: 928-block 6 1423unconditional 10 taken 60573 1424 11387: 928-block 7 1425unconditional 11 taken 11387 1426 71960: 928-block 8 1427branch 12 taken 2049 (fallthrough) 1428branch 13 taken 69911 1429 2049: 929: || (strncasecmp(filename, ent->d_name, filename_len) != 0)) 1430 2049: 929-block 0 1431branch 0 taken 1495 (fallthrough) 1432branch 1 taken 554 1433 71406: 930: continue; 1434 71406: 930-block 0 1435unconditional 0 taken 71406 1436 -: 931: } 1437 -: 932: 1438 554: 933: if (*rl_line_buffer == 'c' 1439 554: 933-block 0 1440branch 0 taken 0 (fallthrough) 1441branch 1 taken 554 1442 #####: 934: && strncmp(rl_line_buffer, "cd ", 3) == 0) { 1443 %%%%%: 934-block 0 1444branch 0 never executed 1445branch 1 never executed 1446 #####: 935: ret = -1; 1447 -: 936: 1448 #####: 937: switch (type) { 1449 %%%%%: 937-block 0 1450branch 0 never executed 1451branch 1 never executed 1452branch 2 never executed 1453 #####: 938: case DT_LNK: 1454 #####: 939: if (dirname[0] == '.' && !dirname[1]) { 1455 %%%%%: 939-block 0 1456branch 0 never executed 1457branch 1 never executed 1458 %%%%%: 939-block 1 1459branch 2 never executed 1460branch 3 never executed 1461 #####: 940: ret = get_link_ref(ent->d_name); 1462 %%%%%: 940-block 0 1463call 0 never executed 1464unconditional 1 never executed 1465 -: 941: } else { 1466 #####: 942: snprintf(tmp, PATH_MAX, "%s%s", dirname, ent->d_name); 1467 #####: 943: ret = get_link_ref(tmp); 1468 %%%%%: 943-block 0 1469call 0 never executed 1470unconditional 1 never executed 1471 -: 944: } 1472 -: 945: 1473 #####: 946: if (ret == S_IFDIR) 1474 %%%%%: 946-block 0 1475branch 0 never executed 1476branch 1 never executed 1477 #####: 947: match = 1; 1478 %%%%%: 947-block 0 1479unconditional 0 never executed 1480 #####: 948: break; 1481 %%%%%: 948-block 0 1482unconditional 0 never executed 1483 -: 949: 1484 #####: 950: case DT_DIR: match = 1; break; 1485 %%%%%: 950-block 0 1486unconditional 0 never executed 1487 -: 951: 1488 #####: 952: default: break; 1489 %%%%%: 952-block 0 1490unconditional 0 never executed 1491 -: 953: } 1492 -: 954: } 1493 -: 955: 1494 554: 956: else if (*rl_line_buffer == 'o' 1495 554: 956-block 0 1496branch 0 taken 0 (fallthrough) 1497branch 1 taken 554 1498 #####: 957: && (strncmp(rl_line_buffer, "o ", 2) == 0 1499 %%%%%: 957-block 0 1500branch 0 never executed 1501branch 1 never executed 1502 #####: 958: || strncmp(rl_line_buffer, "open ", 5) == 0)) { 1503 %%%%%: 958-block 0 1504branch 0 never executed 1505branch 1 never executed 1506 #####: 959: ret = -1; 1507 -: 960: 1508 #####: 961: switch (type) { 1509 %%%%%: 961-block 0 1510branch 0 never executed 1511branch 1 never executed 1512branch 2 never executed 1513 #####: 962: case DT_REG: /* fallthrough */ 1514 #####: 963: case DT_DIR: match = 1; break; 1515 %%%%%: 963-block 0 1516unconditional 0 never executed 1517 -: 964: 1518 #####: 965: case DT_LNK: 1519 #####: 966: if (dirname[0] == '.' && !dirname[1]) { 1520 %%%%%: 966-block 0 1521branch 0 never executed 1522branch 1 never executed 1523 %%%%%: 966-block 1 1524branch 2 never executed 1525branch 3 never executed 1526 #####: 967: ret = get_link_ref(ent->d_name); 1527 %%%%%: 967-block 0 1528call 0 never executed 1529unconditional 1 never executed 1530 -: 968: } else { 1531 #####: 969: snprintf(tmp, PATH_MAX, "%s%s", dirname, ent->d_name); 1532 #####: 970: ret = get_link_ref(tmp); 1533 %%%%%: 970-block 0 1534call 0 never executed 1535unconditional 1 never executed 1536 -: 971: } 1537 -: 972: 1538 #####: 973: if (ret == S_IFDIR || ret == S_IFREG) 1539 %%%%%: 973-block 0 1540branch 0 never executed 1541branch 1 never executed 1542 %%%%%: 973-block 1 1543branch 2 never executed 1544branch 3 never executed 1545 #####: 974: match = 1; 1546 %%%%%: 974-block 0 1547unconditional 0 never executed 1548 #####: 975: break; 1549 %%%%%: 975-block 0 1550unconditional 0 never executed 1551 -: 976: 1552 #####: 977: default: break; 1553 %%%%%: 977-block 0 1554unconditional 0 never executed 1555 -: 978: } 1556 -: 979: } 1557 -: 980: 1558 554: 981: else if (*rl_line_buffer == 't' 1559 554: 981-block 0 1560branch 0 taken 0 (fallthrough) 1561branch 1 taken 554 1562 #####: 982: && (strncmp(rl_line_buffer, "t ", 2) == 0 1563 %%%%%: 982-block 0 1564branch 0 never executed 1565branch 1 never executed 1566 #####: 983: || strncmp(rl_line_buffer, "tr ", 3) == 0 1567 %%%%%: 983-block 0 1568branch 0 never executed 1569branch 1 never executed 1570 #####: 984: || strncmp(rl_line_buffer, "trash ", 6) == 0)) { 1571 %%%%%: 984-block 0 1572branch 0 never executed 1573branch 1 never executed 1574 #####: 985: if (type != DT_BLK && type != DT_CHR) 1575 %%%%%: 985-block 0 1576branch 0 never executed 1577branch 1 never executed 1578 %%%%%: 985-block 1 1579branch 2 never executed 1580branch 3 never executed 1581 #####: 986: match = 1; 1582 %%%%%: 986-block 0 1583unconditional 0 never executed 1584 -: 987: } 1585 -: 988: 1586 554: 989: else if (exec) { 1587 554: 989-block 0 1588branch 0 taken 0 (fallthrough) 1589branch 1 taken 554 1590 #####: 990: if (type == DT_REG && access(ent->d_name, X_OK) == 0) 1591 %%%%%: 990-block 0 1592branch 0 never executed 1593branch 1 never executed 1594 %%%%%: 990-block 1 1595call 2 never executed 1596branch 3 never executed 1597branch 4 never executed 1598 #####: 991: match = 1; 1599 %%%%%: 991-block 0 1600unconditional 0 never executed 1601 -: 992: } 1602 -: 993: 1603 554: 994: else if (exec_path) { 1604 554: 994-block 0 1605branch 0 taken 0 (fallthrough) 1606branch 1 taken 554 1607 #####: 995: if (type == DT_REG) { 1608 %%%%%: 995-block 0 1609branch 0 never executed 1610branch 1 never executed 1611 #####: 996: snprintf(tmp, PATH_MAX, "%s%s", dir_tmp, ent->d_name); 1612 #####: 997: if (access(tmp, X_OK) == 0) 1613 %%%%%: 997-block 0 1614call 0 never executed 1615branch 1 never executed 1616branch 2 never executed 1617 #####: 998: match = 1; 1618 %%%%%: 998-block 0 1619unconditional 0 never executed 1620 -: 999: } 1621 -: 1000: } 1622 -: 1001: 1623 -: 1002: else 1624 554: 1003: match = 1; 1625 554: 1003-block 0 1626unconditional 0 taken 554 1627 -: 1004: } 1628 -: 1005: 1629 4113: 1006: if (match) 1630 4113: 1006-block 0 1631branch 0 taken 4113 (fallthrough) 1632branch 1 taken 0 1633 4113: 1007: break; 1634 4113: 1007-block 0 1635unconditional 0 taken 4113 1636 -: 1008: } 1637 -: 1009: 1638 4514: 1010: if (dir_tmp) { /* == exec_path */ 1639 4514: 1010-block 0 1640branch 0 taken 0 (fallthrough) 1641branch 1 taken 4514 1642 #####: 1011: free(dir_tmp); 1643 #####: 1012: dir_tmp = (char *)NULL; 1644 %%%%%: 1012-block 0 1645unconditional 0 never executed 1646 -: 1013: } 1647 -: 1014: 1648 -: 1015: /* readdir() returns NULL on reaching the end of directory stream. 1649 -: 1016: * So that if entry is NULL, we have no matches */ 1650 -: 1017: 1651 4514: 1018: if (!ent) { /* == !match */ 1652 4514: 1018-block 0 1653branch 0 taken 401 (fallthrough) 1654branch 1 taken 4113 1655 401: 1019: if (directory) { 1656 401: 1019-block 0 1657branch 0 taken 395 (fallthrough) 1658branch 1 taken 6 1659 395: 1020: closedir(directory); 1660 395: 1020-block 0 1661call 0 returned 395 1662 395: 1021: directory = (DIR *)NULL; 1663unconditional 0 taken 395 1664 -: 1022: } 1665 -: 1023: 1666 401: 1024: if (dirname) { 1667 401: 1024-block 0 1668branch 0 taken 401 (fallthrough) 1669branch 1 taken 0 1670 401: 1025: free(dirname); 1671 401: 1026: dirname = (char *)NULL; 1672 401: 1026-block 0 1673unconditional 0 taken 401 1674 -: 1027: } 1675 -: 1028: 1676 401: 1029: if (filename) { 1677 401: 1029-block 0 1678branch 0 taken 401 (fallthrough) 1679branch 1 taken 0 1680 401: 1030: free(filename); 1681 401: 1031: filename = (char *)NULL; 1682 401: 1031-block 0 1683unconditional 0 taken 401 1684 -: 1032: } 1685 -: 1033: 1686 401: 1034: if (users_dirname) { 1687 401: 1034-block 0 1688branch 0 taken 401 (fallthrough) 1689branch 1 taken 0 1690 401: 1035: free(users_dirname); 1691 401: 1036: users_dirname = (char *)NULL; 1692 401: 1036-block 0 1693unconditional 0 taken 401 1694 -: 1037: } 1695 -: 1038: 1696 401: 1039: return (char *)NULL; 1697 401: 1039-block 0 1698unconditional 0 taken 401 1699 -: 1040: } 1700 -: 1041: 1701 -: 1042: /* We have a match */ 1702 -: 1043: else { 1703 4113: 1044: char *temp = (char *)NULL; 1704 -: 1045: 1705 -: 1046: /* dirname && (strcmp(dirname, ".") != 0) */ 1706 4113: 1047: if (dirname && (dirname[0] != '.' || dirname[1])) { 1707 4113: 1047-block 0 1708branch 0 taken 4113 (fallthrough) 1709branch 1 taken 0 1710 4113: 1047-block 1 1711branch 2 taken 4 (fallthrough) 1712branch 3 taken 4109 1713 4: 1047-block 2 1714branch 4 taken 1 (fallthrough) 1715branch 5 taken 3 1716 -: 1048:/* if (rl_complete_with_tilde_expansion && *users_dirname == '~') { 1717 -: 1049: size_t dirlen = strlen(dirname); 1718 -: 1050: temp = (char *)xnmalloc(dirlen + strlen(ent->d_name) + 2, 1719 -: 1051: sizeof(char)); 1720 -: 1052: strcpy(temp, dirname); 1721 -: 1053: // Canonicalization cuts off any final slash present. 1722 -: 1054: // We need to add it back. 1723 -: 1055: 1724 -: 1056: if (dirname[dirlen - 1] != '/') { 1725 -: 1057: temp[dirlen] = '/'; 1726 -: 1058: temp[dirlen + 1] = '\0'; 1727 -: 1059: } 1728 -: 1060: } else { */ 1729 4110: 1061: temp = (char *)xnmalloc(strlen(users_dirname) + 1730 4110: 1062: strlen(ent->d_name) + 1, sizeof(char)); 1731 4110: 1062-block 0 1732call 0 returned 4110 1733 4110: 1063: strcpy(temp, users_dirname); 1734 -: 1064:/* } */ 1735 4110: 1065: strcat(temp, ent->d_name); 1736unconditional 0 taken 4110 1737 -: 1066: } else { 1738 3: 1067: temp = savestring(ent->d_name, strlen(ent->d_name)); 1739 3: 1067-block 0 1740call 0 returned 3 1741unconditional 1 taken 3 1742 -: 1068: } 1743 -: 1069: 1744 4113: 1070: return (temp); 1745 4113: 1070-block 0 1746unconditional 0 taken 4113 1747 -: 1071: } 1748 -: 1072:} 1749 -: 1073: 1750 -: 1074:/* Used by bookmarks completion */ 1751 -: 1075:static char * 1752function bookmarks_generator called 41 returned 100% blocks executed 91% 1753 41: 1076:bookmarks_generator(const char *text, int state) 1754 -: 1077:{ 1755 41: 1078: if (!bookmark_names) 1756 41: 1078-block 0 1757branch 0 taken 0 (fallthrough) 1758branch 1 taken 41 1759 #####: 1079: return (char *)NULL; 1760 %%%%%: 1079-block 0 1761unconditional 0 never executed 1762 -: 1080: 1763 -: 1081: static int i; 1764 -: 1082: static size_t len; 1765 -: 1083: char *name; 1766 -: 1084: 1767 41: 1085: if (!state) { 1768 41: 1085-block 0 1769branch 0 taken 3 (fallthrough) 1770branch 1 taken 38 1771 3: 1086: i = 0; 1772 3: 1087: len = strlen(text); 1773 3: 1087-block 0 1774unconditional 0 taken 3 1775 -: 1088: } 1776 -: 1089: 1777 -: 1090: /* Look for bookmarks in bookmark names for a match */ 1778 60: 1091: while ((name = bookmark_names[i++]) != NULL) { 1779 41: 1091-block 0 1780unconditional 0 taken 41 1781 60: 1091-block 1 1782branch 1 taken 57 1783branch 2 taken 3 (fallthrough) 1784 57: 1092: if (strncmp(name, text, len) == 0) 1785 57: 1092-block 0 1786branch 0 taken 38 (fallthrough) 1787branch 1 taken 19 1788 38: 1093: return strdup(name); 1789 38: 1093-block 0 1790call 0 returned 38 1791unconditional 1 taken 38 1792 -: 1094: } 1793 -: 1095: 1794 3: 1096: return (char *)NULL; 1795 3: 1096-block 0 1796unconditional 0 taken 3 1797 -: 1097:} 1798 -: 1098: 1799 -: 1099:/* Used by history completion */ 1800 -: 1100:static char * 1801function hist_generator called 0 returned 0% blocks executed 0% 1802 #####: 1101:hist_generator(const char *text, int state) 1803 -: 1102:{ 1804 #####: 1103: if (!history) 1805 %%%%%: 1103-block 0 1806branch 0 never executed 1807branch 1 never executed 1808 #####: 1104: return (char *)NULL; 1809 %%%%%: 1104-block 0 1810unconditional 0 never executed 1811 -: 1105: 1812 -: 1106: static int i; 1813 -: 1107: static size_t len; 1814 -: 1108: char *name; 1815 -: 1109: 1816 #####: 1110: if (!state) { 1817 %%%%%: 1110-block 0 1818branch 0 never executed 1819branch 1 never executed 1820 #####: 1111: i = 0; 1821 #####: 1112: len = strlen(text); 1822 %%%%%: 1112-block 0 1823unconditional 0 never executed 1824 -: 1113: } 1825 -: 1114: 1826 -: 1115: /* Look for cmd history entries for a match */ 1827 #####: 1116: while ((name = history[i++]) != NULL) { 1828 %%%%%: 1116-block 0 1829unconditional 0 never executed 1830 %%%%%: 1116-block 1 1831branch 1 never executed 1832branch 2 never executed 1833 #####: 1117: if (strncmp(name, text, len) == 0) 1834 %%%%%: 1117-block 0 1835branch 0 never executed 1836branch 1 never executed 1837 #####: 1118: return strdup(name); 1838 %%%%%: 1118-block 0 1839call 0 never executed 1840unconditional 1 never executed 1841 -: 1119: } 1842 -: 1120: 1843 #####: 1121: return (char *)NULL; 1844 %%%%%: 1121-block 0 1845unconditional 0 never executed 1846 -: 1122:} 1847 -: 1123: 1848 -: 1124:/* Expand string into matching path in the jump database. Used by 1849 -: 1125: * j, jc, and jp commands */ 1850 -: 1126:static char * 1851function jump_generator called 18 returned 100% blocks executed 75% 1852 18: 1127:jump_generator(const char *text, int state) 1853 -: 1128:{ 1854 -: 1129: static int i; 1855 -: 1130: char *name; 1856 -: 1131: 1857 18: 1132: if (!state) 1858 18: 1132-block 0 1859branch 0 taken 1 (fallthrough) 1860branch 1 taken 17 1861 1: 1133: i = 0; 1862 1: 1133-block 0 1863unconditional 0 taken 1 1864 -: 1134: 1865 18: 1135: if (!jump_db) 1866 18: 1135-block 0 1867branch 0 taken 0 (fallthrough) 1868branch 1 taken 18 1869 #####: 1136: return (char *)NULL; 1870 %%%%%: 1136-block 0 1871unconditional 0 never executed 1872 -: 1137: 1873 -: 1138: /* Look for matches in the dirhist list */ 1874 48: 1139: while ((name = jump_db[i++].path) != NULL) { 1875 18: 1139-block 0 1876unconditional 0 taken 18 1877 48: 1139-block 1 1878branch 1 taken 47 1879branch 2 taken 1 (fallthrough) 1880 -: 1140: /* Exclude CWD */ 1881 47: 1141: if (name[1] == ws[cur_ws].path[1] && strcmp(name, ws[cur_ws].path) == 0) 1882 47: 1141-block 0 1883branch 0 taken 36 (fallthrough) 1884branch 1 taken 11 1885 36: 1141-block 1 1886branch 2 taken 1 (fallthrough) 1887branch 3 taken 35 1888 1: 1142: continue; 1889 1: 1142-block 0 1890unconditional 0 taken 1 1891 -: 1143: /* Filter by parent */ 1892 46: 1144: if (rl_line_buffer[1] == 'p') { 1893 46: 1144-block 0 1894branch 0 taken 0 (fallthrough) 1895branch 1 taken 46 1896 #####: 1145: if (!strstr(ws[cur_ws].path, name)) 1897 %%%%%: 1145-block 0 1898branch 0 never executed 1899branch 1 never executed 1900 #####: 1146: continue; 1901 %%%%%: 1146-block 0 1902unconditional 0 never executed 1903 -: 1147: } 1904 -: 1148: /* Filter by child */ 1905 46: 1149: else if (rl_line_buffer[1] == 'c') { 1906 46: 1149-block 0 1907branch 0 taken 0 (fallthrough) 1908branch 1 taken 46 1909 #####: 1150: if (!strstr(name, ws[cur_ws].path)) 1910 %%%%%: 1150-block 0 1911branch 0 never executed 1912branch 1 never executed 1913 #####: 1151: continue; 1914 %%%%%: 1151-block 0 1915unconditional 0 never executed 1916 -: 1152: } 1917 -: 1153: 1918 46: 1154: if (strstr(name, text)) 1919 46: 1154-block 0 1920branch 0 taken 17 (fallthrough) 1921branch 1 taken 29 1922 17: 1155: return strdup(name); 1923 17: 1155-block 0 1924call 0 returned 17 1925unconditional 1 taken 17 1926 -: 1156: } 1927 -: 1157: 1928 1: 1158: return (char *)NULL; 1929 1: 1158-block 0 1930unconditional 0 taken 1 1931 -: 1159:} 1932 -: 1160: 1933 -: 1161:/* Expand jump order number into the corresponding path. Used by the 1934 -: 1162: * jo command */ 1935 -: 1163:static char * 1936function jump_entries_generator called 0 returned 0% blocks executed 0% 1937 #####: 1164:jump_entries_generator(const char *text, int state) 1938 -: 1165:{ 1939 -: 1166: static size_t i; 1940 -: 1167: char *name; 1941 -: 1168: 1942 #####: 1169: if (!state) 1943 %%%%%: 1169-block 0 1944branch 0 never executed 1945branch 1 never executed 1946 #####: 1170: i = 0; 1947 %%%%%: 1170-block 0 1948unconditional 0 never executed 1949 -: 1171: 1950 #####: 1172: int num_text = atoi(text); 1951 -: 1173: 1952 -: 1174: /* Check list of jump entries for a match */ 1953 #####: 1175: while (i <= jump_n && (name = jump_db[i++].path) != NULL) 1954 %%%%%: 1175-block 0 1955unconditional 0 never executed 1956 %%%%%: 1175-block 1 1957branch 1 never executed 1958branch 2 never executed 1959 %%%%%: 1175-block 2 1960branch 3 never executed 1961branch 4 never executed 1962 #####: 1176: if (*name == *jump_db[num_text - 1].path && strcmp(name, 1963 %%%%%: 1176-block 0 1964branch 0 never executed 1965branch 1 never executed 1966 #####: 1177: jump_db[num_text - 1].path) == 0) 1967 %%%%%: 1177-block 0 1968branch 0 never executed 1969branch 1 never executed 1970 #####: 1178: return strdup(name); 1971 %%%%%: 1178-block 0 1972call 0 never executed 1973unconditional 1 never executed 1974 -: 1179: 1975 #####: 1180: return (char *)NULL; 1976 %%%%%: 1180-block 0 1977unconditional 0 never executed 1978 -: 1181:} 1979 -: 1182: 1980 -: 1183:static char * 1981function cschemes_generator called 21 returned 100% blocks executed 91% 1982 21: 1184:cschemes_generator(const char *text, int state) 1983 -: 1185:{ 1984 21: 1186: if (!color_schemes) 1985 21: 1186-block 0 1986branch 0 taken 0 (fallthrough) 1987branch 1 taken 21 1988 #####: 1187: return (char *)NULL; 1989 %%%%%: 1187-block 0 1990unconditional 0 never executed 1991 -: 1188: 1992 -: 1189: static int i; 1993 -: 1190: static size_t len; 1994 -: 1191: char *name; 1995 -: 1192: 1996 21: 1193: if (!state) { 1997 21: 1193-block 0 1998branch 0 taken 1 (fallthrough) 1999branch 1 taken 20 2000 1: 1194: i = 0; 2001 1: 1195: len = strlen(text); 2002 1: 1195-block 0 2003unconditional 0 taken 1 2004 -: 1196: } /* The state variable is zero only the first time the function is 2005 -: 1197: called, and a non-zero positive in later calls. This means that i 2006 -: 1198: and len will be necessarilly initialized the first time */ 2007 -: 1199: 2008 -: 1200: /* Look for color schemes in color_schemes for a match */ 2009 21: 1201: while ((name = color_schemes[i++]) != NULL) { 2010 21: 1201-block 0 2011unconditional 0 taken 21 2012 21: 1201-block 1 2013branch 1 taken 20 2014branch 2 taken 1 (fallthrough) 2015 20: 1202: if (strncmp(name, text, len) == 0) 2016 20: 1202-block 0 2017branch 0 taken 20 (fallthrough) 2018branch 1 taken 0 2019 20: 1203: return strdup(name); 2020 20: 1203-block 0 2021call 0 returned 20 2022unconditional 1 taken 20 2023 -: 1204: } 2024 -: 1205: 2025 1: 1206: return (char *)NULL; 2026 1: 1206-block 0 2027unconditional 0 taken 1 2028 -: 1207:} 2029 -: 1208: 2030 -: 1209:/* Used by profiles completion */ 2031 -: 1210:static char * 2032function profiles_generator called 8 returned 100% blocks executed 91% 2033 8: 1211:profiles_generator(const char *text, int state) 2034 -: 1212:{ 2035 8: 1213: if (!profile_names) 2036 8: 1213-block 0 2037branch 0 taken 0 (fallthrough) 2038branch 1 taken 8 2039 #####: 1214: return (char *)NULL; 2040 %%%%%: 1214-block 0 2041unconditional 0 never executed 2042 -: 1215: 2043 -: 1216: static int i; 2044 -: 1217: static size_t len; 2045 -: 1218: char *name; 2046 -: 1219: 2047 8: 1220: if (!state) { 2048 8: 1220-block 0 2049branch 0 taken 2 (fallthrough) 2050branch 1 taken 6 2051 2: 1221: i = 0; 2052 2: 1222: len = strlen(text); 2053 2: 1222-block 0 2054unconditional 0 taken 2 2055 -: 1223: } /* The state variable is zero only the first time the function is 2056 -: 1224: called, and a non-zero positive in later calls. This means that i 2057 -: 1225: and len will be necessarilly initialized the first time */ 2058 -: 1226: 2059 -: 1227: /* Look for profiles in profile_names for a match */ 2060 13: 1228: while ((name = profile_names[i++]) != NULL) { 2061 8: 1228-block 0 2062unconditional 0 taken 8 2063 13: 1228-block 1 2064branch 1 taken 11 2065branch 2 taken 2 (fallthrough) 2066 11: 1229: if (strncmp(name, text, len) == 0) 2067 11: 1229-block 0 2068branch 0 taken 6 (fallthrough) 2069branch 1 taken 5 2070 6: 1230: return strdup(name); 2071 6: 1230-block 0 2072call 0 returned 6 2073unconditional 1 taken 6 2074 -: 1231: } 2075 -: 1232: 2076 2: 1233: return (char *)NULL; 2077 2: 1233-block 0 2078unconditional 0 taken 2 2079 -: 1234:} 2080 -: 1235: 2081 -: 1236:/* Used by ELN expansion */ 2082 -: 1237:static char * 2083function filenames_gen_text called 7 returned 100% blocks executed 92% 2084 7: 1238:filenames_gen_text(const char *text, int state) 2085 -: 1239:{ 2086 -: 1240: static size_t i, len = 0; 2087 -: 1241: char *name; 2088 7: 1242: rl_filename_completion_desired = 1; 2089 -: 1243: /* According to the GNU readline documention: "If it is set to a 2090 -: 1244: * non-zero value, directory names have a slash appended and 2091 -: 1245: * Readline attempts to quote completed file names if they contain 2092 -: 1246: * any embedded word break characters." To make the quoting part 2093 -: 1247: * work I had to specify a custom quoting function (my_rl_quote) */ 2094 7: 1248: if (!state) { /* state is zero only the first time readline is 2095 7: 1248-block 0 2096branch 0 taken 4 (fallthrough) 2097branch 1 taken 3 2098 -: 1249: executed */ 2099 4: 1250: i = 0; 2100 4: 1251: len = strlen(text); 2101 4: 1251-block 0 2102unconditional 0 taken 4 2103 -: 1252: } 2104 -: 1253: 2105 -: 1254: /* Check list of currently displayed files for a match */ 2106 132: 1255: while (i < files && (name = file_info[i++].name) != NULL) 2107 7: 1255-block 0 2108unconditional 0 taken 7 2109 132: 1255-block 1 2110branch 1 taken 128 (fallthrough) 2111branch 2 taken 4 2112 128: 1255-block 2 2113branch 3 taken 128 2114branch 4 taken 0 (fallthrough) 2115 256*: 1256: if (case_sens_path_comp ? strncmp(name, text, len) == 0 2116 128: 1256-block 0 2117branch 0 taken 0 (fallthrough) 2118branch 1 taken 128 2119 %%%%%: 1256-block 1 2120unconditional 2 never executed 2121 128: 1256-block 2 2122branch 3 taken 3 (fallthrough) 2123branch 4 taken 125 2124 128: 1257: : strncasecmp(name, text, len) == 0) 2125 128: 1257-block 0 2126unconditional 0 taken 128 2127 3: 1258: return strdup(name); 2128 3: 1258-block 0 2129call 0 returned 3 2130unconditional 1 taken 3 2131 -: 1259: 2132 4: 1260: return (char *)NULL; 2133 4: 1260-block 0 2134unconditional 0 taken 4 2135 -: 1261:} 2136 -: 1262: 2137 -: 1263:/* Used by ELN expansion */ 2138 -: 1264:static char * 2139function filenames_gen_eln called 0 returned 0% blocks executed 0% 2140 #####: 1265:filenames_gen_eln(const char *text, int state) 2141 -: 1266:{ 2142 -: 1267: static size_t i; 2143 -: 1268: char *name; 2144 #####: 1269: rl_filename_completion_desired = 1; 2145 -: 1270: 2146 #####: 1271: if (!state) 2147 %%%%%: 1271-block 0 2148branch 0 never executed 2149branch 1 never executed 2150 #####: 1272: i = 0; 2151 %%%%%: 1272-block 0 2152unconditional 0 never executed 2153 -: 1273: 2154 #####: 1274: int num_text = atoi(text); 2155 -: 1275: 2156 -: 1276: /* Check list of currently displayed files for a match */ 2157 #####: 1277: while (i < files && (name = file_info[i++].name) != NULL) { 2158 %%%%%: 1277-block 0 2159unconditional 0 never executed 2160 %%%%%: 1277-block 1 2161branch 1 never executed 2162branch 2 never executed 2163 %%%%%: 1277-block 2 2164branch 3 never executed 2165branch 4 never executed 2166 #####: 1278: if (*name == *file_info[num_text - 1].name 2167 %%%%%: 1278-block 0 2168branch 0 never executed 2169branch 1 never executed 2170 #####: 1279: && strcmp(name, file_info[num_text - 1].name) == 0) { 2171 %%%%%: 1279-block 0 2172branch 0 never executed 2173branch 1 never executed 2174 -: 1280:#ifndef _NO_SUGGESTIONS 2175 #####: 1281: if (suggestion_buf) 2176 %%%%%: 1281-block 0 2177branch 0 never executed 2178branch 1 never executed 2179 #####: 1282: clear_suggestion(); 2180 %%%%%: 1282-block 0 2181call 0 never executed 2182unconditional 1 never executed 2183 -: 1283:#endif 2184 #####: 1284: return strdup(name); 2185 %%%%%: 1284-block 0 2186call 0 never executed 2187unconditional 1 never executed 2188 -: 1285: } 2189 -: 1286: } 2190 -: 1287: 2191 #####: 1288: return (char *)NULL; 2192 %%%%%: 1288-block 0 2193unconditional 0 never executed 2194 -: 1289:} 2195 -: 1290: 2196 -: 1291:/* Used by commands completion */ 2197 -: 1292:static char * 2198function bin_cmd_generator called 2 returned 100% blocks executed 92% 2199 2: 1293:bin_cmd_generator(const char *text, int state) 2200 -: 1294:{ 2201 2: 1295: if (!bin_commands) 2202 2: 1295-block 0 2203branch 0 taken 0 (fallthrough) 2204branch 1 taken 2 2205 #####: 1296: return (char *)NULL; 2206 %%%%%: 1296-block 0 2207unconditional 0 never executed 2208 -: 1297: 2209 -: 1298: static int i; 2210 -: 1299: static size_t len; 2211 -: 1300: char *name; 2212 -: 1301: 2213 2: 1302: if (!state) { 2214 2: 1302-block 0 2215branch 0 taken 1 (fallthrough) 2216branch 1 taken 1 2217 1: 1303: i = 0; 2218 1: 1304: len = strlen(text); 2219 1: 1304-block 0 2220unconditional 0 taken 1 2221 -: 1305: } 2222 -: 1306: 2223 3746: 1307: while ((name = bin_commands[i++]) != NULL) { 2224 2: 1307-block 0 2225unconditional 0 taken 2 2226 3746: 1307-block 1 2227branch 1 taken 3745 2228branch 2 taken 1 (fallthrough) 2229 3745: 1308: if (*text == *name && strncmp(name, text, len) == 0) 2230 3745: 1308-block 0 2231branch 0 taken 60 (fallthrough) 2232branch 1 taken 3685 2233 60: 1308-block 1 2234branch 2 taken 1 (fallthrough) 2235branch 3 taken 59 2236 1: 1309: return strdup(name); 2237 1: 1309-block 0 2238call 0 returned 1 2239unconditional 1 taken 1 2240 -: 1310: } 2241 -: 1311: 2242 1: 1312: return (char *)NULL; 2243 1: 1312-block 0 2244unconditional 0 taken 1 2245 -: 1313:} 2246 -: 1314: 2247 -: 1315:static char * 2248function sort_num_generator called 0 returned 0% blocks executed 0% 2249 #####: 1316:sort_num_generator(const char *text, int state) 2250 -: 1317:{ 2251 -: 1318: static size_t i; 2252 -: 1319: char *name; 2253 #####: 1320: rl_filename_completion_desired = 1; 2254 -: 1321: 2255 #####: 1322: if (!state) 2256 %%%%%: 1322-block 0 2257branch 0 never executed 2258branch 1 never executed 2259 #####: 1323: i = 0; 2260 %%%%%: 1323-block 0 2261unconditional 0 never executed 2262 -: 1324: 2263 #####: 1325: int num_text = atoi(text); 2264 -: 1326: static char *sorts[] = { 2265 -: 1327: "none", 2266 -: 1328: "name", 2267 -: 1329: "size", 2268 -: 1330: "atime", 2269 -: 1331: "btime", 2270 -: 1332: "ctime", 2271 -: 1333: "mtime", 2272 -: 1334: "version", 2273 -: 1335: "extension", 2274 -: 1336: "inode", 2275 -: 1337: "owner", 2276 -: 1338: "group", 2277 -: 1339: NULL 2278 -: 1340: }; 2279 -: 1341: 2280 -: 1342: /* Check list of currently displayed files for a match */ 2281 #####: 1343: while (i <= SORT_TYPES && (name = sorts[i++]) != NULL) { 2282 %%%%%: 1343-block 0 2283unconditional 0 never executed 2284 %%%%%: 1343-block 1 2285branch 1 never executed 2286branch 2 never executed 2287 %%%%%: 1343-block 2 2288branch 3 never executed 2289branch 4 never executed 2290 #####: 1344: if (*name == *sorts[num_text] 2291 %%%%%: 1344-block 0 2292branch 0 never executed 2293branch 1 never executed 2294 #####: 1345: && strcmp(name, sorts[num_text]) == 0) 2295 %%%%%: 1345-block 0 2296branch 0 never executed 2297branch 1 never executed 2298 #####: 1346: return strdup(name); 2299 %%%%%: 1346-block 0 2300call 0 never executed 2301unconditional 1 never executed 2302 -: 1347: } 2303 -: 1348: 2304 #####: 1349: return (char *)NULL; 2305 %%%%%: 1349-block 0 2306unconditional 0 never executed 2307 -: 1350:} 2308 -: 1351: 2309 -: 1352:static char * 2310function nets_generator called 0 returned 0% blocks executed 0% 2311 #####: 1353:nets_generator(const char *text, int state) 2312 -: 1354:{ 2313 #####: 1355: if (!remotes) 2314 %%%%%: 1355-block 0 2315branch 0 never executed 2316branch 1 never executed 2317 #####: 1356: return (char *)NULL; 2318 %%%%%: 1356-block 0 2319unconditional 0 never executed 2320 -: 1357: 2321 -: 1358: static int i; 2322 -: 1359: static size_t len; 2323 -: 1360: char *name; 2324 -: 1361: 2325 #####: 1362: if (!state) { 2326 %%%%%: 1362-block 0 2327branch 0 never executed 2328branch 1 never executed 2329 #####: 1363: i = 0; 2330 #####: 1364: len = strlen(text); 2331 %%%%%: 1364-block 0 2332unconditional 0 never executed 2333 -: 1365: } 2334 -: 1366: 2335 #####: 1367: while ((name = remotes[i++].name) != NULL) { 2336 %%%%%: 1367-block 0 2337unconditional 0 never executed 2338 %%%%%: 1367-block 1 2339branch 1 never executed 2340branch 2 never executed 2341 #####: 1368: if (strncmp(name, text, len) == 0) 2342 %%%%%: 1368-block 0 2343branch 0 never executed 2344branch 1 never executed 2345 #####: 1369: return strdup(name); 2346 %%%%%: 1369-block 0 2347call 0 never executed 2348unconditional 1 never executed 2349 -: 1370: } 2350 -: 1371: 2351 #####: 1372: return (char *)NULL; 2352 %%%%%: 1372-block 0 2353unconditional 0 never executed 2354 -: 1373:} 2355 -: 1374: 2356 -: 1375:static char * 2357function sort_name_generator called 0 returned 0% blocks executed 0% 2358 #####: 1376:sort_name_generator(const char *text, int state) 2359 -: 1377:{ 2360 -: 1378: static int i; 2361 -: 1379: static size_t len; 2362 -: 1380: char *name; 2363 -: 1381: 2364 #####: 1382: if (!state) { 2365 %%%%%: 1382-block 0 2366branch 0 never executed 2367branch 1 never executed 2368 #####: 1383: i = 0; 2369 #####: 1384: len = strlen(text); 2370 %%%%%: 1384-block 0 2371unconditional 0 never executed 2372 -: 1385: } 2373 -: 1386: 2374 -: 1387: static char *sorts[] = { 2375 -: 1388: "none", 2376 -: 1389: "name", 2377 -: 1390: "size", 2378 -: 1391: "atime", 2379 -: 1392: "btime", 2380 -: 1393: "ctime", 2381 -: 1394: "mtime", 2382 -: 1395: "version", 2383 -: 1396: "extension", 2384 -: 1397: "inode", 2385 -: 1398: "owner", 2386 -: 1399: "group", 2387 -: 1400: NULL}; 2388 -: 1401: 2389 #####: 1402: while ((name = sorts[i++]) != NULL) { 2390 %%%%%: 1402-block 0 2391unconditional 0 never executed 2392 %%%%%: 1402-block 1 2393branch 1 never executed 2394branch 2 never executed 2395 #####: 1403: if (*text == *name && strncmp(name, text, len) == 0) 2396 %%%%%: 1403-block 0 2397branch 0 never executed 2398branch 1 never executed 2399 %%%%%: 1403-block 1 2400branch 2 never executed 2401branch 3 never executed 2402 #####: 1404: return strdup(name); 2403 %%%%%: 1404-block 0 2404call 0 never executed 2405unconditional 1 never executed 2406 -: 1405: } 2407 -: 1406: 2408 #####: 1407: return (char *)NULL; 2409 %%%%%: 1407-block 0 2410unconditional 0 never executed 2411 -: 1408:} 2412 -: 1409: 2413 -: 1410:/* Generate entries from the jump database (not using the j function)*/ 2414 -: 1411:/*char * 2415 -: 1412:jump_gen(const char *text, int state) 2416 -: 1413:{ 2417 -: 1414: static int i; 2418 -: 1415: static size_t len; 2419 -: 1416: char *name; 2420 -: 1417: 2421 -: 1418: if (!state) { 2422 -: 1419: i = 0; 2423 -: 1420: len = strlen(text); 2424 -: 1421: } 2425 -: 1422: 2426 -: 1423: while ((name = jump_db[i++].path) != NULL) { 2427 -: 1424: if (case_sens_path_comp ? strncmp(name, text, len) == 0 2428 -: 1425: : strncasecmp(name, text, len) == 0) 2429 -: 1426: return strdup(name); 2430 -: 1427: } 2431 -: 1428: 2432 -: 1429: return (char *)NULL; 2433 -: 1430:} */ 2434 -: 1431: 2435 -: 1432:char ** 2436function my_rl_completion called 19 returned 100% blocks executed 49% 2437 19: 1433:my_rl_completion(const char *text, int start, int end) 2438 -: 1434:{ 2439 19: 1435: char **matches = (char **)NULL; 2440 -: 1436: 2441 19: 1437: if (start == 0) { /* Only for the first word entered in the prompt */ 2442 19: 1437-block 0 2443branch 0 taken 4 (fallthrough) 2444branch 1 taken 15 2445 -: 1438: /* Commands completion */ 2446 4: 1439: if (end == 0) { /* If text is empty, do nothing */ 2447 4: 1439-block 0 2448branch 0 taken 0 (fallthrough) 2449branch 1 taken 4 2450 -: 1440: /* Prevent readline from attempting path completion if 2451 -: 1441: * rl_completion matches returns NULL */ 2452 #####: 1442: rl_attempted_completion_over = 1; 2453 #####: 1443: return (char **)NULL; 2454 %%%%%: 1443-block 0 2455unconditional 0 never executed 2456 -: 1444: } 2457 -: 1445: 2458 -: 1446: /* History cmd completion */ 2459 4: 1447: if (*text == '!') 2460 4: 1447-block 0 2461branch 0 taken 0 (fallthrough) 2462branch 1 taken 4 2463 #####: 1448: matches = rl_completion_matches(text + 1, &hist_generator); 2464 %%%%%: 1448-block 0 2465call 0 never executed 2466unconditional 1 never executed 2467 -: 1449: 2468 -: 1450: /* If autocd or auto-open, try to expand ELN's first */ 2469 4*: 1451: if (!matches && (autocd || auto_open)) { 2470 4: 1451-block 0 2471branch 0 taken 4 (fallthrough) 2472branch 1 taken 0 2473 4: 1451-block 1 2474branch 2 taken 0 (fallthrough) 2475branch 3 taken 4 2476 %%%%%: 1451-block 2 2477branch 4 never executed 2478branch 5 never executed 2479 4: 1452: if (*text >= '1' && *text <= '9') { 2480 4: 1452-block 0 2481branch 0 taken 4 (fallthrough) 2482branch 1 taken 0 2483 4: 1452-block 1 2484branch 2 taken 0 (fallthrough) 2485branch 3 taken 4 2486 #####: 1453: int num_text = atoi(text); 2487 -: 1454: 2488 #####: 1455: if (is_number(text) && num_text > 0 && num_text <= (int)files) 2489 %%%%%: 1455-block 0 2490call 0 never executed 2491branch 1 never executed 2492branch 2 never executed 2493 %%%%%: 1455-block 1 2494branch 3 never executed 2495branch 4 never executed 2496 %%%%%: 1455-block 2 2497branch 5 never executed 2498branch 6 never executed 2499 #####: 1456: matches = rl_completion_matches(text, &filenames_gen_eln); 2500 %%%%%: 1456-block 0 2501call 0 never executed 2502unconditional 1 never executed 2503 -: 1457: } 2504 -: 1458: 2505 -: 1459: /* Compĺete with files in CWD */ 2506 4: 1460: if (!matches && *text != '/') 2507 4: 1460-block 0 2508branch 0 taken 4 (fallthrough) 2509branch 1 taken 0 2510 4: 1460-block 1 2511branch 2 taken 4 (fallthrough) 2512branch 3 taken 0 2513 4: 1461: matches = rl_completion_matches(text, &filenames_gen_text); 2514 4: 1461-block 0 2515call 0 returned 4 2516unconditional 1 taken 4 2517 -: 1462: 2518 -: 1463: /* Complete with entries in the jump database */ 2519 -: 1464:/* if (autocd && !matches) 2520 -: 1465: matches = rl_completion_matches(text, &jump_gen); */ 2521 -: 1466: } 2522 -: 1467: 2523 -: 1468: /* Bookmarks completion */ 2524 4*: 1469: if (!matches && (autocd || auto_open) && expand_bookmarks) 2525 4: 1469-block 0 2526branch 0 taken 1 (fallthrough) 2527branch 1 taken 3 2528 1: 1469-block 1 2529branch 2 taken 0 (fallthrough) 2530branch 3 taken 1 2531 %%%%%: 1469-block 2 2532branch 4 never executed 2533branch 5 never executed 2534 1: 1469-block 3 2535branch 6 taken 0 (fallthrough) 2536branch 7 taken 1 2537 #####: 1470: matches = rl_completion_matches(text, &bookmarks_generator); 2538 %%%%%: 1470-block 0 2539call 0 never executed 2540unconditional 1 never executed 2541 -: 1471: 2542 -: 1472: /* If neither autocd nor auto-open, try to complete with 2543 -: 1473: * command names */ 2544 4: 1474: if (!matches) 2545 4: 1474-block 0 2546branch 0 taken 1 (fallthrough) 2547branch 1 taken 3 2548 1: 1475: matches = rl_completion_matches(text, &bin_cmd_generator); 2549 1: 1475-block 0 2550call 0 returned 1 2551unconditional 1 taken 1 2552 -: 1476: } 2553 -: 1477: 2554 -: 1478: /* Second word or more */ 2555 -: 1479: else { 2556 -: 1480: /* #### ELN AND JUMP ORDER EXPANSION ### */ 2557 -: 1481: 2558 -: 1482: /* Perform this check only if the first char of the string to be 2559 -: 1483: * completed is a number in order to prevent an unnecessary call 2560 -: 1484: * to atoi */ 2561 15*: 1485: if (*text >= '0' && *text <= '9') { 2562 15: 1485-block 0 2563branch 0 taken 3 (fallthrough) 2564branch 1 taken 12 2565 3: 1485-block 1 2566branch 2 taken 0 (fallthrough) 2567branch 3 taken 3 2568 %%%%%: 1485-block 2 2569unconditional 4 never executed 2570 #####: 1486: int num_text = atoi(text); 2571 -: 1487: 2572 -: 1488: /* Dirjump: jo command */ 2573 #####: 1489: if (*rl_line_buffer == 'j' && rl_line_buffer[1] == 'o' 2574 %%%%%: 1489-block 0 2575branch 0 never executed 2576branch 1 never executed 2577 %%%%%: 1489-block 1 2578branch 2 never executed 2579branch 3 never executed 2580 #####: 1490: && rl_line_buffer[2] == ' ') { 2581 %%%%%: 1490-block 0 2582branch 0 never executed 2583branch 1 never executed 2584 #####: 1491: if (is_number(text) && num_text > 0 && num_text <= (int)jump_n) { 2585 %%%%%: 1491-block 0 2586call 0 never executed 2587branch 1 never executed 2588branch 2 never executed 2589 %%%%%: 1491-block 1 2590branch 3 never executed 2591branch 4 never executed 2592 %%%%%: 1491-block 2 2593branch 5 never executed 2594branch 6 never executed 2595 #####: 1492: matches = rl_completion_matches(text, 2596 %%%%%: 1492-block 0 2597call 0 never executed 2598unconditional 1 never executed 2599 -: 1493: &jump_entries_generator); 2600 -: 1494: } 2601 -: 1495: } 2602 -: 1496: 2603 -: 1497: /* Sort number expansion */ 2604 #####: 1498: else if (*rl_line_buffer == 's' 2605 %%%%%: 1498-block 0 2606branch 0 never executed 2607branch 1 never executed 2608 #####: 1499: && (strncmp(rl_line_buffer, "st ", 3) == 0 2609 %%%%%: 1499-block 0 2610branch 0 never executed 2611branch 1 never executed 2612 #####: 1500: || strncmp(rl_line_buffer, "sort ", 5) == 0) 2613 %%%%%: 1500-block 0 2614branch 0 never executed 2615branch 1 never executed 2616 #####: 1501: && is_number(text) && num_text >= 0 && num_text <= SORT_TYPES) 2617 %%%%%: 1501-block 0 2618call 0 never executed 2619branch 1 never executed 2620branch 2 never executed 2621 %%%%%: 1501-block 1 2622branch 3 never executed 2623branch 4 never executed 2624 %%%%%: 1501-block 2 2625branch 5 never executed 2626branch 6 never executed 2627 #####: 1502: matches = rl_completion_matches(text, &sort_num_generator); 2628 %%%%%: 1502-block 0 2629call 0 never executed 2630unconditional 1 never executed 2631 -: 1503: 2632 -: 1504: /* ELN expansion */ 2633 #####: 1505: else if (is_number(text) && num_text > 0 && num_text <= (int)files) 2634 %%%%%: 1505-block 0 2635call 0 never executed 2636branch 1 never executed 2637branch 2 never executed 2638 %%%%%: 1505-block 1 2639branch 3 never executed 2640branch 4 never executed 2641 %%%%%: 1505-block 2 2642branch 5 never executed 2643branch 6 never executed 2644 #####: 1506: matches = rl_completion_matches(text, &filenames_gen_eln); 2645 %%%%%: 1506-block 0 2646call 0 never executed 2647unconditional 1 never executed 2648 -: 1507: } 2649 -: 1508: 2650 -: 1509: /* ### DIRJUMP COMPLETION ### */ 2651 -: 1510: /* j, jc, jp commands */ 2652 15: 1511: else if (*rl_line_buffer == 'j' && (rl_line_buffer[1] == ' ' 2653 15: 1511-block 0 2654branch 0 taken 1 (fallthrough) 2655branch 1 taken 14 2656 1: 1511-block 1 2657branch 2 taken 0 (fallthrough) 2658branch 3 taken 1 2659 #####: 1512: || ((rl_line_buffer[1] == 'c' || rl_line_buffer[1] == 'p') 2660 %%%%%: 1512-block 0 2661branch 0 never executed 2662branch 1 never executed 2663 %%%%%: 1512-block 1 2664branch 2 never executed 2665branch 3 never executed 2666 #####: 1513: && rl_line_buffer[2] == ' ') 2667 %%%%%: 1513-block 0 2668branch 0 never executed 2669branch 1 never executed 2670 #####: 1514: || strncmp(rl_line_buffer, "jump ", 5) == 0)) 2671 %%%%%: 1514-block 0 2672branch 0 never executed 2673branch 1 never executed 2674 1: 1515: matches = rl_completion_matches(text, &jump_generator); 2675 1: 1515-block 0 2676call 0 returned 1 2677unconditional 1 taken 1 2678 -: 1516: 2679 -: 1517: /* ### BOOKMARKS COMPLETION ### */ 2680 -: 1518: 2681 14: 1519: else if (*rl_line_buffer == 'b' && (rl_line_buffer[1] == 'm' 2682 14: 1519-block 0 2683branch 0 taken 3 (fallthrough) 2684branch 1 taken 11 2685 3: 1519-block 1 2686branch 2 taken 0 (fallthrough) 2687branch 3 taken 3 2688 #####: 1520: || rl_line_buffer[1] == 'o') 2689 %%%%%: 1520-block 0 2690branch 0 never executed 2691branch 1 never executed 2692 3: 1521: && (strncmp(rl_line_buffer, "bm ", 3) == 0 2693 3: 1521-block 0 2694branch 0 taken 0 (fallthrough) 2695branch 1 taken 3 2696 #####: 1522: || strncmp(rl_line_buffer, "bookmarks ", 10) == 0)) { 2697 %%%%%: 1522-block 0 2698branch 0 never executed 2699branch 1 never executed 2700 -: 1523:#ifndef _NO_SUGGESTIONS 2701 3: 1524: if (suggestion.type != FILE_SUG) 2702 3: 1524-block 0 2703branch 0 taken 3 (fallthrough) 2704branch 1 taken 0 2705 3: 1525: rl_attempted_completion_over = 1; 2706 3: 1525-block 0 2707unconditional 0 taken 3 2708 -: 1526:#endif 2709 3: 1527: matches = rl_completion_matches(text, &bookmarks_generator); 2710 3: 1527-block 0 2711call 0 returned 3 2712unconditional 1 taken 3 2713 -: 1528: } 2714 -: 1529: 2715 -: 1530: /* ### COLOR SCHEMES COMPLETION ### */ 2716 11: 1531: else if (*rl_line_buffer == 'c' && ((rl_line_buffer[1] == 's' 2717 11: 1531-block 0 2718branch 0 taken 1 (fallthrough) 2719branch 1 taken 10 2720 1: 1531-block 1 2721branch 2 taken 1 (fallthrough) 2722branch 3 taken 0 2723 1: 1532: && rl_line_buffer[2] == ' ') 2724 1: 1532-block 0 2725branch 0 taken 0 (fallthrough) 2726branch 1 taken 1 2727 #####: 1533: || strncmp(rl_line_buffer, "colorschemes ", 13) == 0)) { 2728 %%%%%: 1533-block 0 2729branch 0 never executed 2730branch 1 never executed 2731 1: 1534: matches = rl_completion_matches(text, 2732 1: 1534-block 0 2733call 0 returned 1 2734unconditional 1 taken 1 2735 -: 1535: &cschemes_generator); 2736 -: 1536: } 2737 -: 1537: 2738 -: 1538: /* ### PROFILES COMPLETION ### */ 2739 -: 1539: 2740 10: 1540: else if (*rl_line_buffer == 'p' && (rl_line_buffer[1] == 'r' 2741 10: 1540-block 0 2742branch 0 taken 4 (fallthrough) 2743branch 1 taken 6 2744 4: 1540-block 1 2745branch 2 taken 4 (fallthrough) 2746branch 3 taken 0 2747 4: 1541: || rl_line_buffer[1] == 'f') 2748 4: 1541-block 0 2749branch 0 taken 4 (fallthrough) 2750branch 1 taken 0 2751 4: 1542: && (strncmp(rl_line_buffer, "pf set ", 7) == 0 2752 4: 1542-block 0 2753branch 0 taken 2 (fallthrough) 2754branch 1 taken 2 2755 2: 1543: || strncmp(rl_line_buffer, "profile set ", 12) == 0 2756 2: 1543-block 0 2757branch 0 taken 2 (fallthrough) 2758branch 1 taken 0 2759 2: 1544: || strncmp(rl_line_buffer, "pf del ", 7) == 0 2760 2: 1544-block 0 2761branch 0 taken 2 (fallthrough) 2762branch 1 taken 0 2763 2: 1545: || strncmp(rl_line_buffer, "profile del ", 12) == 0)) { 2764 2: 1545-block 0 2765branch 0 taken 0 (fallthrough) 2766branch 1 taken 2 2767 -: 1546:#ifndef _NO_SUGGESTIONS 2768 2: 1547: if (suggestion.type != FILE_SUG) 2769 2: 1547-block 0 2770branch 0 taken 2 (fallthrough) 2771branch 1 taken 0 2772 2: 1548: rl_attempted_completion_over = 1; 2773 2: 1548-block 0 2774unconditional 0 taken 2 2775 -: 1549:#endif /* _NO_SUGGESTIONS */ 2776 2: 1550: matches = rl_completion_matches(text, &profiles_generator); 2777 2: 1550-block 0 2778call 0 returned 2 2779unconditional 1 taken 2 2780 -: 1551: } 2781 -: 1552: 2782 8: 1553: else if (expand_bookmarks) { 2783 8: 1553-block 0 2784branch 0 taken 0 (fallthrough) 2785branch 1 taken 8 2786 #####: 1554: matches = rl_completion_matches(text, &bookmarks_generator); 2787 %%%%%: 1554-block 0 2788call 0 never executed 2789unconditional 1 never executed 2790 -: 1555: } 2791 -: 1556: 2792 8: 1557: else if (*rl_line_buffer == 's' 2793 8: 1557-block 0 2794branch 0 taken 0 (fallthrough) 2795branch 1 taken 8 2796 #####: 1558: && (strncmp(rl_line_buffer, "st ", 3) == 0 2797 %%%%%: 1558-block 0 2798branch 0 never executed 2799branch 1 never executed 2800 #####: 1559: || strncmp(rl_line_buffer, "sort ", 5) == 0)) 2801 %%%%%: 1559-block 0 2802branch 0 never executed 2803branch 1 never executed 2804 #####: 1560: matches = rl_completion_matches(text, &sort_name_generator); 2805 %%%%%: 1560-block 0 2806call 0 never executed 2807unconditional 1 never executed 2808 -: 1561: 2809 8: 1562: else if (*rl_line_buffer == 'n' 2810 8: 1562-block 0 2811branch 0 taken 0 (fallthrough) 2812branch 1 taken 8 2813 #####: 1563: && strncmp(rl_line_buffer, "net ", 4) == 0) 2814 %%%%%: 1563-block 0 2815branch 0 never executed 2816branch 1 never executed 2817 #####: 1564: matches = rl_completion_matches(text, &nets_generator); 2818 %%%%%: 1564-block 0 2819call 0 never executed 2820unconditional 1 never executed 2821 -: 1565: } 2822 -: 1566: 2823 -: 1567: /* ### PATH COMPLETION ### */ 2824 -: 1568: 2825 -: 1569: /* If none of the above, readline will attempt 2826 -: 1570: * path completion instead via my custom my_rl_path_completion() */ 2827 19: 1571: return matches; 2828 19: 1571-block 0 2829unconditional 0 taken 19 2830 -: 1572:} 2831 -: 1573: 2832 -: 1574:int 2833function initialize_readline called 4 returned 100% blocks executed 91% 2834 4: 1575:initialize_readline(void) 2835 -: 1576:{ 2836 -: 1577: /* #### INITIALIZE READLINE (what a hard beast to tackle!!) #### */ 2837 -: 1578: 2838 -: 1579: /* Set the name of the program using readline. Mostly used for 2839 -: 1580: * conditional constructs in the inputrc file */ 2840 4: 1581: rl_readline_name = argv_bk[0]; 2841 -: 1582: 2842 -: 1583:/* add_func_to_rl(); */ 2843 -: 1584: 2844 -: 1585: /* Load readline initialization file. Check order: 2845 -: 1586: * INPUTRC env var 2846 -: 1587: * ~/.config/clifm/readline.cfm 2847 -: 1588: * ~/.inputrc 2848 -: 1589: * /etc/inputrc */ 2849 4: 1590: char *p = getenv("INPUTRC"); 2850 4: 1590-block 0 2851call 0 returned 4 2852 4: 1591: if (p) { 2853branch 0 taken 0 (fallthrough) 2854branch 1 taken 4 2855 #####: 1592: rl_read_init_file(p); 2856 %%%%%: 1592-block 0 2857call 0 never executed 2858unconditional 1 never executed 2859 4: 1593: } else if (config_dir_gral) { 2860 4: 1593-block 0 2861branch 0 taken 4 (fallthrough) 2862branch 1 taken 0 2863 4: 1594: char *rl_file = (char *)xnmalloc(strlen(config_dir_gral) + 14, 2864 4: 1594-block 0 2865call 0 returned 4 2866 -: 1595: sizeof(char)); 2867 4: 1596: sprintf(rl_file, "%s/readline.cfm", config_dir_gral); 2868 4: 1597: rl_read_init_file(rl_file); 2869call 0 returned 4 2870 4: 1598: free(rl_file); 2871unconditional 0 taken 4 2872 -: 1599: } 2873 -: 1600: 2874 -: 1601: /* Enable tab auto-completion for commands (in PATH) in case of 2875 -: 1602: * first entered string (if autocd and/or auto-open are enabled, check 2876 -: 1603: * for paths as well). The second and later entered strings will 2877 -: 1604: * be autocompleted with paths instead, just like in Bash, or with 2878 -: 1605: * listed file names, in case of ELN's. I use a custom completion 2879 -: 1606: * function to add command and ELN completion, since readline's 2880 -: 1607: * internal completer only performs path completion */ 2881 -: 1608: 2882 -: 1609: /* Define a function for path completion. 2883 -: 1610: * NULL means to use filename_entry_function (), the default 2884 -: 1611: * filename completer. */ 2885 4: 1612: rl_completion_entry_function = my_rl_path_completion; 2886 -: 1613: 2887 -: 1614: /* Pointer to alternative function to create matches. 2888 -: 1615: * Function is called with TEXT, START, and END. 2889 -: 1616: * START and END are indices in RL_LINE_BUFFER saying what the 2890 -: 1617: * boundaries of TEXT are. 2891 -: 1618: * If this function exists and returns NULL then call the value of 2892 -: 1619: * rl_completion_entry_function to try to match, otherwise use the 2893 -: 1620: * array of strings returned. */ 2894 4: 1621: rl_attempted_completion_function = my_rl_completion; 2895 4: 1622: rl_ignore_completion_duplicates = 1; 2896 -: 1623: 2897 -: 1624: /* I'm using here a custom quoting function. If not specified, 2898 -: 1625: * readline uses the default internal function. */ 2899 4: 1626: rl_filename_quoting_function = my_rl_quote; 2900 -: 1627: 2901 -: 1628: /* Tell readline what char to use for quoting. This is only the 2902 -: 1629: * readline internal quoting function, and for custom ones, like the 2903 -: 1630: * one I use above. However, custom quoting functions, though they 2904 -: 1631: * need to define their own quoting chars, won't be called at all 2905 -: 1632: * if this variable isn't set. */ 2906 4: 1633: rl_completer_quote_characters = "\"'"; 2907 4: 1634: rl_completer_word_break_characters = " "; 2908 -: 1635: 2909 -: 1636: /* Whenever readline finds any of the following chars, it will call 2910 -: 1637: * the quoting function */ 2911 4: 1638: rl_filename_quote_characters = " \t\n\"\\'`@$><=,;|&{[()]}?!*^"; 2912 -: 1639: /* According to readline documentation, the following string is 2913 -: 1640: * the default and the one used by Bash: " \t\n\"\\'`@$><=;|&{(" */ 2914 -: 1641: 2915 -: 1642: /* Executed immediately before calling the completer function, it 2916 -: 1643: * tells readline if a space char, which is a word break character 2917 -: 1644: * (see the above rl_completer_word_break_characters variable) is 2918 -: 1645: * quoted or not. If it is, readline then passes the whole string 2919 -: 1646: * to the completer function (ex: "user\ file"), and if not, only 2920 -: 1647: * wathever it found after the space char (ex: "file") 2921 -: 1648: * Thanks to George Brocklehurst for pointing out this function: 2922 -: 1649: * https://thoughtbot.com/blog/tab-completion-in-gnu-readline*/ 2923 4: 1650: rl_char_is_quoted_p = quote_detector; 2924 -: 1651: 2925 -: 1652: /* Define a function to handle suggestions and syntax highlighting */ 2926 4: 1653: rl_getc_function = my_rl_getc; 2927 -: 1654: 2928 -: 1655: /* This function is executed inmediately before path completion. So, 2929 -: 1656: * if the string to be completed is, for instance, "user\ file" (see 2930 -: 1657: * the above comment), this function should return the dequoted 2931 -: 1658: * string so it won't conflict with system file names: you want 2932 -: 1659: * "user file", because "user\ file" does not exist, and, in this 2933 -: 1660: * latter case, readline won't find any matches */ 2934 4: 1661: rl_filename_dequoting_function = dequote_str; 2935 -: 1662: 2936 -: 1663: /* Initialize the keyboard bindings function */ 2937 4: 1664: readline_kbinds(); 2938 4: 1664-block 0 2939call 0 returned 4 2940 -: 1665: 2941 -: 1666: /* Copy the list of quote chars to a global variable to be used 2942 -: 1667: * later by some of the program functions like split_str(), 2943 -: 1668: * my_rl_quote(), is_quote_char(), and my_rl_dequote() */ 2944 4: 1669: qc = savestring(rl_filename_quote_characters, 2945call 0 returned 4 2946 -: 1670: strlen(rl_filename_quote_characters)); 2947 -: 1671: 2948 -: 1672:#if !defined(_NO_SUGGESTIONS) && defined(__FreeBSD__) 2949 -: 1673: if (!(flags & GUI) && getenv("CLIFM_FREEBSD_CONSOLE_SC")) 2950 -: 1674: freebsd_sc_console = 1; 2951 -: 1675:#endif 2952 -: 1676: 2953 4: 1677: return EXIT_SUCCESS; 2954unconditional 0 taken 4 2955 -: 1678:} 2956