/* * read-ahead strategy * on second block, read RAGAP blocks, * thereafter, read RAGAP ahead of current pos */ Off dbufread(Iobuf *p, Dentry *d, Off a, Off ra, int uid) { Off addr; if(a == 0) return 1; if(a == 1 && ra == 1) { while(ra < a+RAGAP) { ra++; addr = rel2abs(p, d, ra, 0, 0, uid); if(!addr) return 0; preread(p->dev, addr); } return ra+1; } if(ra == a+RAGAP) { addr = rel2abs(p, d, ra, 0, 0, uid); if(!addr) return 0; preread(p->dev, addr); return ra+1; } return ra; }
/* * normalize: normalize path name * * i) path path name * i) root root of project (must be end with a '/') * i) cwd current directory * o) result normalized path name * i) size size of the result * r) ==NULL: error * !=NULL: result */ char * normalize(const char *path, const char *root, const char *cwd, char *result, const int size) { char *p, abs[MAXPATHLEN]; if (normalize_pathname(path, result, size) == NULL) goto toolong; if (isabspath(path)) { if (strlen(result) > MAXPATHLEN) goto toolong; strcpy(abs, result); } else { if (rel2abs(result, cwd, abs, sizeof(abs)) == NULL) goto toolong; } /* * Remove the root part of path and insert './'. * rootdir /a/b/ * path /a/b/c/d.c -> c/d.c -> ./c/d.c */ p = locatestring(abs, root, MATCH_AT_FIRST); if (p == NULL) return NULL; strlimcpy(result, "./", size); strlimcpy(result + 2, p, size - 2); return result; toolong: die("path name is too long."); }
static int getdatablock(Fs *fs, Dentry *d, int32_t a) { int32_t addr; if((addr = rel2abs(fs, d, a)) == 0) return -1; return getblocktag(fs, addr, Tfile, QPNONE); }
Iobuf* dnodebuf(Iobuf *p, Dentry *d, Off a, int tag, int uid) { Off addr; addr = rel2abs(p, d, a, tag, 0, uid); if(addr) return getbuf(p->dev, addr, Brd); return 0; }
Iobuf* dnodebuf(Iobuf *p, Dentry *d, long a, int tag) { long addr; addr = rel2abs(p, d, a, tag, 0); if(addr) return getbuf(p->dev, addr, Bread); return 0; }
static int readdentry(Fs *fs, Dentry *d, int n, Dentry *e) { int32_t addr, m; m = n/fs->kfs.DIRPERBUF; if((addr = rel2abs(fs, d, m)) <= 0) return addr; if(getblocktag(fs, addr, Tdir, d->qid.path) < 0) return -1; *e = *(Dentry*)(block+(n%fs->kfs.DIRPERBUF)*sizeof(Dentry)); return 1; }
/* * same as dnodebuf but it calls putbuf(p) * to reduce interference. */ Iobuf* dnodebuf1(Iobuf *p, Dentry *d, Off a, int tag, int uid) { Off addr; Device *dev; dev = p->dev; addr = rel2abs(p, d, a, tag, 1, uid); if(addr) return getbuf(dev, addr, Brd); return 0; }
/* * same as dnodebuf but it calls putpuf(p) * to reduce interference. */ Iobuf* dnodebuf1(Iobuf *p, Dentry *d, long a, int tag) { long addr; Device dev; dev = p->dev; addr = rel2abs(p, d, a, tag, 1); if(addr) return getbuf(dev, addr, Bread); return 0; }
struct string_t *arb_rel2abs(char *path, char *base) { size_t size = 100; char *buffer = (char*)malloc(size); if(!buffer) return NULL; if(rel2abs(path, base, buffer, size) == buffer) { struct string_t *string = malloc(sizeof(struct string_t)); string->text = buffer; return string; } while(1) { size *= 2; char *new_buffer = (char*)realloc(buffer, size); if(!new_buffer) { free(buffer); return NULL; } buffer = new_buffer; if(rel2abs(path, base, buffer, size) == buffer) { struct string_t *string = malloc(sizeof(struct string_t)); string->text = buffer; return string; } if(errno != ERANGE) return NULL; } }
void open_dialog(Vector2i pos, color_t color_index) { size_t height = (color_index == CIDX_DEFAULT) ? left_pos.y+2 : (color_index == CIDX_NEWCOLOR) ? delete_pos.y : DIALOG_WINDOW_HEIGHT; cidx = color_index; if (pos.x + DIALOG_WINDOW_WIDTH >= MENU_WINDOW_WIDTH) { pos.x += DIALOG_WINDOW_WIDTH - MENU_WINDOW_WIDTH - 2; } dialog_pos = rel2abs(pos, menu_pos); dialogw = newwin(height, DIALOG_WINDOW_WIDTH, dialog_pos.y, dialog_pos.x); keypad(dialogw, TRUE); nodelay(dialogw, TRUE); }
/** * @details * normalize: normalize path name * * @param[in] path path name * @param[in] root root of project (@STRONG{must be end with a '/'}) * @param[in] cwd current directory * @param[out] result normalized path name * @param[in] size size of the @a result * @return ==NULL: error <br> * !=NULL: @a result * * @note Calls die() if the result path name is too long (#MAXPATHLEN). */ char * normalize(const char *path, const char *root, const char *cwd, char *result, const int size) { char *p, abs[MAXPATHLEN]; if (normalize_pathname(path, result, size) == NULL) goto toolong; if (isabspath(path)) { if (strlen(result) > MAXPATHLEN) goto toolong; strcpy(abs, result); } else { if (rel2abs(result, cwd, abs, sizeof(abs)) == NULL) goto toolong; } /* * Remove the root part of path and insert './'. * rootdir /a/b/ * path /a/b/c/d.c -> c/d.c -> ./c/d.c */ p = locatestring(abs, root, MATCH_AT_FIRST); if (p == NULL) { p = locatestring(root, abs, MATCH_AT_FIRST); /* * abs == /usr/src should be considered to be equal to root == /usr/src/. */ if (p && !strcmp(p, "/")) result[0] = '\0'; else return NULL; } strlimcpy(result, "./", size); strlimcpy(result + 2, p, size - 2); return result; toolong: die("path name is too long."); }
int main(int argc, char **argv) { char c; const char *p, *browser = NULL, *definition = NULL; STRBUF *arg = strbuf_open(0); STRBUF *URL = strbuf_open(0); while (--argc > 0 && ((c = (++argv)[0][0]) == '-' || c == '+')) { if (argv[0][1] == '-') { if (!strcmp("--help", argv[0])) help(); else if (!strcmp("--version", argv[0])) show_version++; else if (!strcmp("--quiet", argv[0])) { qflag++; vflag = 0; } else if (!strcmp("--verbose", argv[0])) { vflag++; qflag = 0; } else usage(); continue; } if (c == '+') { linenumber = atoi(argv[0] + 1); continue; } p = argv[0] + 1; switch (*p) { case 'b': browser = argv[1]; --argc; ++argv; break; case 'd': definition = argv[1]; --argc; ++argv; break; case 'p': pflag++; break; case 'q': qflag++; setquiet(); break; case 'v': vflag++; setverbose(); break; default: usage(); } } if (show_version) version(progname, vflag); /* * Load aliases from .gozillarc. */ load_alias(); /* * Decide browser. */ if (!browser && getenv("BROWSER")) browser = getenv("BROWSER"); if (!browser && alias("BROWSER")) browser = alias("BROWSER"); /* * In DOS & Windows, let the file: association handle it. */ #if !(_WIN32 || __DJGPP__) if (!browser) browser = "mozilla"; #endif /* * Replace alias name. */ if (definition == NULL) { if (argc == 0) usage(); strbuf_puts(arg, argv[0]); /* * Replace with alias value. */ if ((p = alias(strbuf_value(arg))) != NULL) { strbuf_reset(arg); strbuf_puts(arg, p); } } /* * Get URL. */ { char *argument = strbuf_value(arg); /* * Protocol (xxx://...) */ if (!definition && isprotocol(argument)) { strbuf_puts(URL, argument); } else { const char *HTMLdir = NULL; if (setupdbpath(0) == 0) { cwd = get_cwd(); root = get_root(); dbpath = get_dbpath(); HTMLdir = locate_HTMLdir(); } /* * Make a URL of hypertext from the argument. */ if (HTMLdir != NULL) { if (definition) getdefinitionURL(definition, HTMLdir, URL); else getURL(argument, HTMLdir, URL); } /* * Make a file URL. */ else if (test("fr", argument) || test("dr", argument)) { char cwd[MAXPATHLEN]; char result[MAXPATHLEN]; if (getcwd(cwd, sizeof(cwd)) == NULL) die("cannot get current directory."); if (rel2abs(argument, cwd, result, sizeof(result)) == NULL) die("rel2abs failed."); strbuf_puts(URL, "file://"); strbuf_puts(URL, result); } else { die_with_code(1, "file '%s' not found.", argument); } } } if (pflag) { fprintf(stdout, "%s\n", strbuf_value(URL)); if (vflag) fprintf(stdout, "using browser '%s'.\n", browser); exit(0); } /* * Show URL's page. */ show_page_by_url(browser, strbuf_value(URL)); exit(0); }
int fffiles( char *name, char **buf ) { char pathbuf[ NFILEN ], tmpnam[ NFILEN ] ; char pathbufs[ NFILEN ], ff_namee[ NFILEN ] ; char *cp, *dirpart, *nampart, *buffer ; int n, len, size, dirpartlen, nampartlen, l ; HANDLE hFind ; WIN32_FIND_DATA find ; TCHAR findPath[ MAX_PATH ], unicode[ MAX_PATH ] ; #ifdef HOMEDIR char *home; int homelen; #endif #ifndef _WIN32_WCE if (name[1] == ':' && name[2] == '\0') { return -1; } #endif #ifdef HOMEDIR if (name[0] == '~' && (name[1]=='/' || name[1]=='\\') && (home = getenv("HOME"))) { homelen = strlen(home)-1; strncpy(pathbuf, home, sizeof(pathbuf)); pathbuf[NFILEN-1] = '\0'; strncat(pathbuf, &name[1], sizeof(pathbuf)-strlen(pathbuf)-1); } else { home = NULL; homelen = 0; strncpy(pathbuf, name, sizeof(pathbuf)); pathbuf[NFILEN-1] = '\0'; } #else strncpy(pathbuf, name, sizeof(pathbuf)); pathbuf[NFILEN-1] = '\0'; #endif dirpart = NULL ; for ( cp = pathbuf ; *cp ; cp ++ ) { if ( *cp == '/' ) { *cp = '\\' ; dirpart = cp ; } else if ( *cp == '\\' ) { dirpart = cp ; } else if ( dirpart == NULL && *cp == ':' ) { dirpart = cp ; } } if ( dirpart ) { *++dirpart = '\0' ; dirpartlen = dirpart - pathbuf ; } else { strcpy( pathbuf, ".\\" ) ; /* 90.05.30 by A.Shirahashi */ dirpartlen = 0 ; } #ifdef HOMEDIR nampart = name + dirpartlen - homelen; #else nampart = name + dirpartlen; #endif nampartlen = strlen( nampart ) ; buffer = malloc( MALLOC_STEP ) ; if ( buffer == NULL ) { return -1 ; } size = MALLOC_STEP ; len = 0 ; n = 0 ; (VOID) strcat( pathbuf, "*.*" ) ; strcpy( pathbufs, pathbuf ) ; #ifdef KANJI bufetos( pathbufs, strlen(pathbufs) + 1 ) ; #endif /* Convert the search path to UNICODE and get absolute path */ sjis2unicode( (LPBYTE) pathbufs, unicode, sizeof unicode ) ; rel2abs( findPath, g_szCurDir, unicode ) ; /* Find first file */ hFind = FindFirstFile( findPath, &find ) ; if ( hFind == INVALID_HANDLE_VALUE ) { *buf = buffer ; buffer[0] = '\0' ; return 0 ; } do { if ( !lstrcmp( find.cFileName, TEXT(".") ) ) { continue ; } else if ( !lstrcmp( find.cFileName, TEXT("..") ) ) { continue ; } unicode2sjis( find.cFileName, (LPBYTE) ff_namee, sizeof ff_namee ) ; #ifdef KANJI bufstoe( ff_namee, strlen(ff_namee) + 1 ) ; #endif if ( strnicmp( nampart, ff_namee, nampartlen ) ) { continue ; /* no-case-sensitive comparison */ } strncpy( tmpnam, pathbuf, dirpartlen ) ; strcpy( tmpnam + dirpartlen, ff_namee ) ; if ( find.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) { strcat( tmpnam, "\\" ) ; } l = strlen(tmpnam) + 1 ; /* 90.05.30 by A.Shirahashi */ if ( l > 5 && (stricmp( &tmpnam[l-5], ".OBJ" ) == 0 || stricmp( &tmpnam[l-5], ".EXE" ) == 0 || stricmp( &tmpnam[l-5], ".COM" ) == 0 ) ) { /* 90.05.30 by A.Shirahashi */ continue ; } if ( l + len >= size ) { /* make room for double null */ if ( ( buffer = realloc( buffer, size += MALLOC_STEP ) ) == NULL ) { FindClose(hFind); return -1 ; } } /* 90.06.08 by A.Shirahashi: to */ /* 00.12.28 by amura.. contributed by sahf */ #ifdef HOMEDIR if(home) { strcpy(buffer+len, "~"); strcat(buffer+len, tmpnam+homelen+1); l -= homelen; } else #endif strcpy( buffer + len, tmpnam ) ; len += l ; n ++ ; } while ( FindNextFile( hFind, &find ) ) ; FindClose(hFind); *buf = buffer ; buffer[len] = '\0' ; return n ; }
// create a path that is relative to the given base directory // path and base will first be resolved against cwd to make them absolute std::string abs2rel(const std::string& uri, const std::string& base, const std::string& cwd) { std::string absolute_uri = rel2abs(uri, cwd); std::string absolute_base = rel2abs(base, cwd); size_t proto = 0; // check if we have a protocol if (uri[proto] && Prelexer::is_alpha(uri[proto])) { // skip over all alphanumeric characters while (uri[proto] && Prelexer::is_alnum(uri[proto++])) {} // then skip over the mandatory colon if (proto && uri[proto] == ':') ++ proto; } // distinguish between windows absolute paths and valid protocols // we assume that protocols must at least have two chars to be valid if (proto && uri[proto++] == '/' && proto > 3) return uri; #ifdef _WIN32 // absolute link must have a drive letter, and we know that we // can only create relative links if both are on the same drive if (absolute_base[0] != absolute_uri[0]) return absolute_uri; #endif std::string stripped_uri = ""; std::string stripped_base = ""; size_t index = 0; size_t minSize = std::min(absolute_uri.size(), absolute_base.size()); for (size_t i = 0; i < minSize; ++i) { #ifdef FS_CASE_SENSITIVE if (absolute_uri[i] != absolute_base[i]) break; #else // compare the charactes in a case insensitive manner // windows fs is only case insensitive in ascii ranges if (tolower(absolute_uri[i]) != tolower(absolute_base[i])) break; #endif if (absolute_uri[i] == '/') index = i + 1; } for (size_t i = index; i < absolute_uri.size(); ++i) { stripped_uri += absolute_uri[i]; } for (size_t i = index; i < absolute_base.size(); ++i) { stripped_base += absolute_base[i]; } size_t left = 0; size_t directories = 0; for (size_t right = 0; right < stripped_base.size(); ++right) { if (stripped_base[right] == '/') { if (stripped_base.substr(left, 2) != "..") { ++directories; } else if (directories > 1) { --directories; } else { directories = 0; } left = right + 1; } } std::string result = ""; for (size_t i = 0; i < directories; ++i) { result += "../"; } result += stripped_uri; return result; }
int main(int argc, char **argv) { const char *av = NULL; int db; int optchar; int option_index = 0; int status = 0; /* * get path of following directories. * o current directory * o root of source tree * o dbpath directory * * if GTAGS not found, exit with an error message. */ status = setupdbpath(0); if (status == 0) { cwd = get_cwd(); root = get_root(); dbpath = get_dbpath(); } /* * Setup GTAGSCONF and GTAGSLABEL environment variable * according to the --gtagsconf and --gtagslabel option. */ preparse_options(argc, argv); /* * Open configuration file. */ openconf(root); setenv_from_config(); logging_arguments(argc, argv); while ((optchar = getopt_long(argc, argv, "acde:EifFgGIlL:MnoOpPqrsS:tTuvVx", long_options, &option_index)) != EOF) { switch (optchar) { case 0: break; case 'a': aflag++; break; case 'c': cflag++; setcom(optchar); break; case 'd': dflag++; break; case 'e': av = optarg; break; case 'E': Gflag = 0; break; case 'f': fflag++; xflag++; setcom(optchar); break; case 'F': Tflag = 0; break; case 'g': gflag++; setcom(optchar); break; case 'G': Gflag++; break; case 'i': iflag++; break; case 'I': Iflag++; setcom(optchar); break; case 'l': Sflag++; scope = "."; break; case 'L': file_list = optarg; break; case 'M': Mflag++; iflag = 0; break; case 'n': nflag++; if (optarg) { if (!strcmp(optarg, "sort")) nofilter |= SORT_FILTER; else if (!strcmp(optarg, "path")) nofilter |= PATH_FILTER; } else { nofilter = BOTH_FILTER; } break; case 'o': oflag++; break; case 'O': Oflag++; break; case 'p': pflag++; setcom(optchar); break; case 'P': Pflag++; setcom(optchar); break; case 'q': qflag++; setquiet(); break; case 'r': rflag++; break; case 's': sflag++; break; case 'S': Sflag++; scope = optarg; break; case 't': tflag++; break; case 'T': Tflag++; break; case 'u': uflag++; setcom(optchar); break; case 'v': vflag++; setverbose(); break; case 'V': Vflag++; break; case 'x': xflag++; break; case OPT_USE_COLOR: if (optarg) { if (!strcmp(optarg, "never")) use_color = 0; else if (!strcmp(optarg, "always")) use_color = 1; else if (!strcmp(optarg, "auto")) use_color = 2; else die_with_code(2, "unknown color type."); } else { use_color = 2; } break; case OPT_ENCODE_PATH: encode_chars = optarg; break; case OPT_FROM_HERE: { char *p = optarg; const char *usage = "usage: global --from-here=lineno:path."; context_lineno = p; while (*p && isdigit(*p)) p++; if (*p != ':') die_with_code(2, usage); *p++ = '\0'; if (!*p) die_with_code(2, usage); context_file = p; } break; case OPT_GTAGSCONF: case OPT_GTAGSLABEL: /* These options are already parsed in preparse_options() */ break; case OPT_MATCH_PART: if (!strcmp(optarg, "first")) match_part = MATCH_PART_FIRST; else if (!strcmp(optarg, "last")) match_part = MATCH_PART_LAST; else if (!strcmp(optarg, "all")) match_part = MATCH_PART_ALL; else die_with_code(2, "unknown part type for the --match-part option."); break; case OPT_PATH_CONVERT: do_path = 1; if (!strcmp("absolute", optarg)) convert_type = PATH_ABSOLUTE; else if (!strcmp("relative", optarg)) convert_type = PATH_RELATIVE; else if (!strcmp("through", optarg)) convert_type = PATH_THROUGH; else die("Unknown path type."); break; case OPT_PATH_STYLE: path_style = optarg; break; case OPT_RESULT: if (!strcmp(optarg, "ctags-x")) format = FORMAT_CTAGS_X; else if (!strcmp(optarg, "ctags-xid")) format = FORMAT_CTAGS_XID; else if (!strcmp(optarg, "ctags")) format = FORMAT_CTAGS; else if (!strcmp(optarg, "ctags-mod")) format = FORMAT_CTAGS_MOD; else if (!strcmp(optarg, "path")) format = FORMAT_PATH; else if (!strcmp(optarg, "grep")) format = FORMAT_GREP; else if (!strcmp(optarg, "cscope")) format = FORMAT_CSCOPE; else die_with_code(2, "unknown format type for the --result option."); break; case OPT_SINGLE_UPDATE: single_update = optarg; break; default: usage(); break; } } if (qflag) vflag = 0; if (show_version) version(av, vflag); if (show_help) help(); if (dbpath == NULL) die_with_code(-status, gtags_dbpath_error); /* * decide format. * The --result option is given to priority more than the -t and -x option. */ if (format == 0) { if (tflag) { /* ctags format */ format = FORMAT_CTAGS; } else if (xflag) { /* print details */ format = FORMAT_CTAGS_X; } else { /* print just a file name */ format = FORMAT_PATH; } } /* * GTAGSBLANKENCODE will be used in less(1). */ switch (format) { case FORMAT_CTAGS_X: case FORMAT_CTAGS_XID: if (encode_chars == NULL && getenv("GTAGSBLANKENCODE")) encode_chars = " \t"; break; } if (encode_chars) { if (strlen(encode_chars) > 255) die("too many encode chars."); if (strchr(encode_chars, '/') || strchr(encode_chars, '.')) warning("cannot encode '/' and '.' in the path. Ignored."); set_encode_chars((unsigned char *)encode_chars); } if (getenv("GTAGSTHROUGH")) Tflag++; if (use_color) { #if defined(_WIN32) && !defined(__CYGWIN__) if (!(getenv("ANSICON") || LoadLibrary("ANSI32.dll")) && use_color == 2) use_color = 0; #endif if (use_color == 2 && !isatty(1)) use_color = 0; if (Vflag) use_color = 0; } argc -= optind; argv += optind; /* * Path filter */ if (do_path) { /* * This code is needed for globash.rc. * This code extract path name from tag line and * replace it with the relative or the absolute path name. * * By default, if we are in src/ directory, the output * should be converted like follows: * * main 10 ./src/main.c main(argc, argv)\n * main 22 ./libc/func.c main(argc, argv)\n * v * main 10 main.c main(argc, argv)\n * main 22 ../libc/func.c main(argc, argv)\n * * Similarly, the --path-convert=absolute option specified, then * v * main 10 /prj/xxx/src/main.c main(argc, argv)\n * main 22 /prj/xxx/libc/func.c main(argc, argv)\n */ STRBUF *ib = strbuf_open(MAXBUFLEN); CONVERT *cv; char *ctags_x; if (argc < 3) die("global --path-convert: 3 arguments needed."); cv = convert_open(convert_type, FORMAT_CTAGS_X, argv[0], argv[1], argv[2], stdout, NOTAGS); while ((ctags_x = strbuf_fgets(ib, stdin, STRBUF_NOCRLF)) != NULL) convert_put(cv, ctags_x); convert_close(cv); strbuf_close(ib); exit(0); } /* * At first, we pickup pattern from -e option. If it is not found * then use argument which is not option. */ if (!av) { av = *argv; /* * global -g pattern [files ...] * av argv */ if (gflag && av) argv++; } if (single_update) { if (command == 0) { uflag++; command = 'u'; } else if (command != 'u') { ; /* ignored */ } } /* * only -c, -u, -P and -p allows no argument. */ if (!av) { switch (command) { case 'c': case 'u': case 'p': case 'P': break; case 'f': if (file_list) break; default: usage(); break; } } /* * -u and -p cannot have any arguments. */ if (av) { switch (command) { case 'u': case 'p': usage(); default: break; } } if (tflag) xflag = 0; if (nflag > 1) nosource = 1; /* to keep compatibility */ if (print0) set_print0(); if (cflag && match_part == 0) match_part = MATCH_PART_ALL; /* * remove leading blanks. */ if (!Iflag && !gflag && av) for (; *av == ' ' || *av == '\t'; av++) ; if (cflag && !Pflag && av && isregex(av)) die_with_code(2, "only name char is allowed with -c option."); /* * print dbpath or rootdir. */ if (pflag) { fprintf(stdout, "%s\n", (rflag) ? root : dbpath); exit(0); } /* * incremental update of tag files. */ if (uflag) { STRBUF *sb = strbuf_open(0); char *gtags_path = usable("gtags"); if (!gtags_path) die("gtags command not found."); if (chdir(root) < 0) die("cannot change directory to '%s'.", root); #if defined(_WIN32) && !defined(__CYGWIN__) /* * Get around CMD.EXE's weird quoting rules by sticking another * perceived whitespace in front (also works with Take Command). */ strbuf_putc(sb, ';'); #endif strbuf_puts(sb, quote_shell(gtags_path)); strbuf_puts(sb, " -i"); if (vflag) strbuf_puts(sb, " -v"); if (single_update) { if (!isabspath(single_update)) { static char regular_path_name[MAXPATHLEN]; if (rel2abs(single_update, cwd, regular_path_name, sizeof(regular_path_name)) == NULL) die("rel2abs failed."); single_update = regular_path_name; } strbuf_puts(sb, " --single-update "); strbuf_puts(sb, quote_shell(single_update)); } strbuf_putc(sb, ' '); strbuf_puts(sb, quote_shell(dbpath)); if (system(strbuf_value(sb))) exit(1); strbuf_close(sb); exit(0); } /* * decide tag type. */ if (context_file) { if (isregex(av)) die_with_code(2, "regular expression is not allowed with the --from-here option."); db = decide_tag_by_context(av, context_file, atoi(context_lineno)); } else { if (dflag) db = GTAGS; else if (rflag && sflag) db = GRTAGS + GSYMS; else db = (rflag) ? GRTAGS : ((sflag) ? GSYMS : GTAGS); } /* * complete function name */ if (cflag) { if (Iflag) completion_idutils(dbpath, root, av); else if (Pflag) completion_path(dbpath, av); else completion(dbpath, root, av, db); exit(0); } /* * make local prefix. * local prefix must starts with './' and ends with '/'. */ if (Sflag) { STRBUF *sb = strbuf_open(0); static char buf[MAXPATHLEN]; const char *path = scope; /* * normalize the path of scope directory. */ if (!test("d", path)) die("'%s' not found or not a directory.", scope); if (!isabspath(path)) path = makepath(cwd, path, NULL); if (realpath(path, buf) == NULL) die("cannot get real path of '%s'.", scope); if (!in_the_project(buf)) die("'%s' is out of the source project.", scope); scope = buf; /* * make local prefix. */ strbuf_putc(sb, '.'); if (strcmp(root, scope) != 0) { const char *p = scope + strlen(root); if (*p != '/') strbuf_putc(sb, '/'); strbuf_puts(sb, p); } strbuf_putc(sb, '/'); localprefix = check_strdup(strbuf_value(sb)); strbuf_close(sb); #ifdef DEBUG fprintf(stderr, "root=%s\n", root); fprintf(stderr, "cwd=%s\n", cwd); fprintf(stderr, "localprefix=%s\n", localprefix); #endif } /* * convert the file-list path into an absolute path. */ if (file_list && strcmp(file_list, "-") && !isabspath(file_list)) { static char buf[MAXPATHLEN]; if (realpath(file_list, buf) == NULL) die("'%s' not found.", file_list); file_list = buf; } /* * decide path conversion type. */ if (nofilter & PATH_FILTER) type = PATH_THROUGH; else if (aflag) type = PATH_ABSOLUTE; else type = PATH_RELATIVE; if (path_style) { if (!strcmp(path_style, "relative")) type = PATH_RELATIVE; else if (!strcmp(path_style, "absolute")) type = PATH_ABSOLUTE; else if (!strcmp(path_style, "through")) type = PATH_THROUGH; else if (!strcmp(path_style, "shorter")) type = PATH_SHORTER; else if (!strcmp(path_style, "abslib")) { type = PATH_RELATIVE; abslib++; } else die("invalid path style."); } /* * exec lid(idutils). */ if (Iflag) { chdir(root); idutils(av, dbpath); } /* * search pattern (regular expression). */ else if (gflag) { chdir(root); grep(av, argv, dbpath); } /* * locate paths including the pattern. */ else if (Pflag) { chdir(root); pathlist(av, dbpath); } /* * parse source files. */ else if (fflag) { chdir(root); parsefile(argv, cwd, root, dbpath, db); } /* * tag search. */ else { tagsearch(av, cwd, root, dbpath, db); } return 0; }