root/gtags-cscope/gtags-cscope.c(188.html)

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. help
  2. check_dbpath
  3. get_global_path
  4. main
  5. get_line
  6. update
  7. print_case_distinction
  8. include_pattern
  9. command_help
  10. command_loop
  11. execute_command
  12. search

/*
 * Copyright (c) 2006, 2008
 *      Tama Communications Corporation
 *
 * This file is part of GNU GLOBAL.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifdef HAVE_CONFIG_H #include <config.h> #endif #include <sys/types.h> #include <sys/stat.h> #include <errno.h> #include <ctype.h> #include <stdio.h> #ifdef STDC_HEADERS #include <stdlib.h> #endif #ifdef HAVE_STRING_H #include <string.h> #else #include <strings.h> #endif #ifdef HAVE_UNISTD_H #include <unistd.h> #endif #include "getopt.h" #include "global.h" #include "const.h" /* static void usage(void); */
static void help(void); static void check_dbpath(void); static void get_global_path(void); int main(int, char **); static char *get_line(void); static void update(void); static void print_case_distinction(void); static char *include_pattern(const char *); static void command_help(void); static void command_loop(void); static int execute_command(STRBUF *, const int, const int, const char *); static void search(int, const char *); int show_version; int show_help; int qflag; int vflag; #define NA -1 /* static void usage(void) { fputs(usage_const, stderr); exit(2); } */
static void help(void) { fputs(usage_const, stdout); fputs(help_const, stdout); exit(0); } static struct option const long_options[] = { {"ignore-case", no_argument, NULL, 'C'}, {"quiet", no_argument, NULL, 'q'}, {"verbose", no_argument, NULL, 'v'}, {"version", no_argument, &show_version, 1}, {"help", no_argument, &show_help, 1}, { 0 } }; char global_path[MAXFILLEN]; int ignore_case; /* * Check whether or not GTAGS exist. * * If GTAGS not found, this function abort with a message. */
static void check_dbpath(void) { char cwd[MAXPATHLEN+1]; char root[MAXPATHLEN+1]; char dbpath[MAXPATHLEN+1]; getdbpath(cwd, root, dbpath, vflag); } /* * Get global(1)'s path. */
static void get_global_path(void) { const char *p; if (!(p = usable("global"))) die("global command required but not found."); strlimcpy(global_path, p, sizeof(global_path)); } int main(int argc, char **argv) { const char *av = NULL; int optchar; int option_index = 0; while ((optchar = getopt_long(argc, argv, "bCcdeF:f:hI:i:kLlp:qRs:TUuVv0123456789", long_options, &option_index)) != EOF) { switch (optchar) { case 0: break; case 'C': ignore_case = 1; break; case 'q': qflag++; break; case 'v': vflag++; break; default: break; } } if (show_help) help(); argc -= optind; argv += optind; if (!av) av = (argc > 0) ? *argv : NULL; if (show_version) version(av, vflag); /* * Get global(1)'s path. If not found, abort with a message. */
get_global_path(); /* * Check dbpath. If dbpath not found, abort with a message. */
check_dbpath(); /* * Command loop */
command_loop(); return 0; } /* * Read line with a prompt. * * This is part of cscope protocol. */
static char * get_line(void) { STATIC_STRBUF(sb); /* Prompt */
fputs(">> ", stdout); fflush(stdout); if (strbuf_fgets(sb, stdin, STRBUF_NOCRLF) == NULL) return NULL; return strbuf_value(sb); } /* * Update tag files. */
static void update(void) { STATIC_STRBUF(command); strbuf_clear(command); strbuf_sprintf(command, "%s -u", global_path); if (vflag) { strbuf_putc(command, 'v'); fprintf(stderr, "gscope: %s\n", strbuf_value(command)); } system(strbuf_value(command)); } /* * print verbose message about case distinction. */
static void print_case_distinction(void) { if (vflag) { const char *msg = ignore_case ? "ignore letter case when searching" : "use letter case when searching"; fprintf(stderr, "gscope: %s\n", msg); } } /* * get pattern which match to #include lines. * * i) arg include file name * r) pattern which match to #include lines */
static char * include_pattern(const char *arg) { #if defined(_WIN32) #define INCLUDE "^[ \t]*#[ \t]*include[ \t].*[\\\"\"</\\]%s[\\\"\">]" #elif defined(__DJGPP__) #define INCLUDE "^[ \t]*#[ \t]*include[ \t].*[\"</\\]%s[\">]" #else #define INCLUDE "^[ \t]*#[ \t]*include[ \t].*[\"</]%s[\">]" #endif STATIC_STRBUF(pat); strbuf_clear(pat); strbuf_sprintf(pat, INCLUDE, quote_string(arg)); return strbuf_value(pat); } /* * show help message. */
static void command_help(void) { fprintf(stdout, "0<arg>: Find this C symbol\n"); fprintf(stdout, "1<arg>: Find this definition\n"); fprintf(stdout, "2<arg>: Find functions called by this function\n"); fprintf(stdout, " (Not implemented yet.)\n"); fprintf(stdout, "3<arg>: Find functions calling this function\n"); fprintf(stdout, "4<arg>: Find this text string\n"); fprintf(stdout, "6<arg>: Find this egrep pattern\n"); fprintf(stdout, "7<arg>: Find this file\n"); fprintf(stdout, "8<arg>: Find files #including this file\n"); fprintf(stdout, "c: Toggle ignore/use letter case\n"); fprintf(stdout, "r: Rebuild the database\n"); fprintf(stdout, "q: Quit the session\n"); fprintf(stdout, "h: Show help\n"); } /* * command loop. * * This is the main body of gtags-cscope. */
void command_loop(void) { int com = 0; char *line; print_case_distinction(); while ((line = get_line()) != NULL) { switch (com = *line++) { /* * Control command */
case 'c': /* c: ignore case or not */
ignore_case ^= 1; print_case_distinction(); break; case 'q': /* q: quit the program */
return; case 'r': /* r: update tag file */
update(); break; case 'h': /* h: show help */
command_help(); break; /* * Search command */
case '0': case '1': case '2': case '3': case '4': case '6': case '7': case '8': search(com, line); break; default: fputs("cscope: 0 lines\n", stdout); fflush(stdout); break; } } } /* * Execute global(1) and write the output to the 'sb' string buffer. * * o) sb output * i) com cscope command (0-8) * i) opt option for global(1) * i) arg argument for global(1) * r) number of output */
static int execute_command(STRBUF *sb, const int com, const int opt, const char *arg) { #ifdef _WIN32 #define QUOTE '"' #else #define QUOTE '\'' #endif STATIC_STRBUF(command); STATIC_STRBUF(ib); FILE *ip; int count = 0; strbuf_clear(command); strbuf_puts(command, global_path); strbuf_puts(command, " --result=cscope"); if (opt || ignore_case) { strbuf_putc(command, ' '); strbuf_putc(command, '-'); if (opt) strbuf_putc(command, opt); if (ignore_case) strbuf_putc(command, 'i'); } strbuf_putc(command, ' '); strbuf_putc(command, QUOTE); strbuf_puts(command, arg); strbuf_putc(command, QUOTE); if (!(ip = popen(strbuf_value(command), "r"))) die("cannot execute '%s'.", strbuf_value(command)); if (vflag) fprintf(stderr, "gscope: %s\n", strbuf_value(command)); /* * Copy records with little modification. */
strbuf_clear(ib); while (strbuf_fgets(ib, ip, 0)) { count++; if (opt == 0) { strbuf_puts(sb, strbuf_value(ib)); } else { char *p = strbuf_value(ib); /* path name */
while (*p && *p != ' ') strbuf_putc(sb, *p++); if (*p != ' ') die("illegal cscope format. (%s)", strbuf_value(ib)); strbuf_putc(sb, *p++); /* replace pattern with "<unknown>" or "<global>" */
while (*p && *p != ' ') p++; if (*p != ' ') die("illegal cscope format. (%s)", strbuf_value(ib)); if (com == '8') strbuf_puts(sb, "<global>"); else strbuf_puts(sb, "<unknown>"); strbuf_putc(sb, *p++); /* line number */
while (*p && *p != ' ') strbuf_putc(sb, *p++); if (*p != ' ') die("illegal cscope format. (%s)", strbuf_value(ib)); strbuf_putc(sb, *p++); /* line image */
if (*p == '\n') strbuf_puts(sb, "<unknown>\n"); else strbuf_puts(sb, p); } } if (pclose(ip) < 0) die("terminated abnormally."); return count; } /* * Execute retrieval command. * * i) command 0: Find this C symbol * 1: Find this definition * 2: Find functions called by this function (not supported) * 3: Find functions calling this function * 4: Find this text string * 6: Find this egrep pattern * 7: Find this file * 8: Find files #including this file * i) arg argument * * Unsupported command prints "cscope: 0 lines\n". */
static void search(int com, const char *arg) { static STRBUF *sb; char buf[1024]; int count = 0, opt = 0; if (sb == NULL) sb = strbuf_open(1024 * 1024); else strbuf_reset(sb); /* * Convert from cscope command to global command. */
switch (com) { case '0': /* Find this C symbol */
case '1': /* Find this definition */
break; case '2': /* Find functions called by this function */
opt = NA; break; case '3': /* Find functions calling this function */
opt = 'r'; break; case '4': /* Find this text string */
opt = 'g'; strlimcpy(buf, quote_string(arg), sizeof(buf)); arg = buf; break; case '5': /* Change this text string */
opt = NA; break; case '6': /* Find this egrep pattern */
opt = 'g'; break; case '7': /* Find this file */
opt = 'P'; break; case '8': /* Find files #including this file */
opt = 'g'; arg = include_pattern(arg); break; } /* * Execute global(1). */
if (opt == NA) { fprintf(stdout, "cscope: 0 lines\n"); return; } if (com == '0') { count += execute_command(sb, com, 0, arg); count += execute_command(sb, com, (count > 0) ? 'r' : 's', arg); } else { count += execute_command(sb, com, opt, arg); } /* * Output format: * cscope: <n> lines * ****************** ... 1 * ****************** ... 2 * ... * ****************** ... n * * Example: * cscope: 3 lines * global/global.c main 158 main(int argc, char **argv) * gozilla/gozilla.c main 155 main(int argc, char **argv) * gscope/gscope.c main 108 main(int argc, char **argv) */
fprintf(stdout, "cscope: %d lines\n", count); if (count > 0) fwrite(strbuf_value(sb), 1, strbuf_getlen(sb), stdout); fflush(stdout); }

/* [<][>][^][v][top][bottom][index][help] */