static bool locateSharedLib(std::string libpath,std::string libname,std::string &result) { StringList pathlist(libpath.c_str()); pathlist.rewind(); char const *path; while( (path=pathlist.next()) ) { Directory d(path); d.Rewind(); char const *fname; while( (fname=d.Next()) ) { if( d.IsDirectory() ) continue; if( strncmp(fname,libname.c_str(),libname.size())==0 ) { size_t l = strlen(fname); if( l >= 2 && strcmp(&(fname[l-2]),".a")==0 ) { continue; // ignore this; it is a static lib } result = d.GetFullPath(); return true; } } } return false; }
int main( int argc, const char* argv[]) { int rt = 0; std::auto_ptr<strus::ErrorBufferInterface> errorBuffer( strus::createErrorBuffer_standard( 0, 2)); if (!errorBuffer.get()) { std::cerr << _TXT("failed to create error buffer") << std::endl; return -1; } strus::ProgramOptions opt; bool printUsageAndExit = false; try { opt = strus::ProgramOptions( argc, argv, 11, "h,help", "v,version", "license", "t,tokenizer:", "n,normalizer:", "m,module:", "M,moduledir:", "q,quot:", "p,plain", "R,resourcedir:", "T,trace:"); if (opt( "help")) printUsageAndExit = true; std::auto_ptr<strus::ModuleLoaderInterface> moduleLoader( strus::createModuleLoader( errorBuffer.get())); if (!moduleLoader.get()) throw strus::runtime_error(_TXT("failed to create module loader")); if (opt("moduledir")) { std::vector<std::string> modirlist( opt.list("moduledir")); std::vector<std::string>::const_iterator mi = modirlist.begin(), me = modirlist.end(); for (; mi != me; ++mi) { moduleLoader->addModulePath( *mi); } moduleLoader->addSystemModulePath(); } if (opt("module")) { std::vector<std::string> modlist( opt.list("module")); std::vector<std::string>::const_iterator mi = modlist.begin(), me = modlist.end(); for (; mi != me; ++mi) { if (!moduleLoader->loadModule( *mi)) { throw strus::runtime_error(_TXT("error failed to load module %s"), mi->c_str()); } } } if (opt("license")) { std::vector<std::string> licenses_3rdParty = moduleLoader->get3rdPartyLicenseTexts(); std::vector<std::string>::const_iterator ti = licenses_3rdParty.begin(), te = licenses_3rdParty.end(); if (ti != te) std::cout << _TXT("3rd party licenses:") << std::endl; for (; ti != te; ++ti) { std::cout << *ti << std::endl; } std::cerr << std::endl; if (!printUsageAndExit) return 0; } if (opt( "version")) { std::cout << _TXT("Strus utilities version ") << STRUS_UTILITIES_VERSION_STRING << std::endl; std::cout << _TXT("Strus module version ") << STRUS_MODULE_VERSION_STRING << std::endl; std::cout << _TXT("Strus rpc version ") << STRUS_RPC_VERSION_STRING << std::endl; std::cout << _TXT("Strus trace version ") << STRUS_TRACE_VERSION_STRING << std::endl; std::cout << _TXT("Strus analyzer version ") << STRUS_ANALYZER_VERSION_STRING << std::endl; std::cout << _TXT("Strus base version ") << STRUS_BASE_VERSION_STRING << std::endl; std::vector<std::string> versions_3rdParty = moduleLoader->get3rdPartyVersionTexts(); std::vector<std::string>::const_iterator vi = versions_3rdParty.begin(), ve = versions_3rdParty.end(); if (vi != ve) std::cout << _TXT("3rd party versions:") << std::endl; for (; vi != ve; ++vi) { std::cout << *vi << std::endl; } if (!printUsageAndExit) return 0; } else if (!printUsageAndExit) { if (opt.nofargs() > 1) { std::cerr << _TXT("too many arguments") << std::endl; printUsageAndExit = true; rt = 1; } if (opt.nofargs() < 1) { std::cerr << _TXT("too few arguments") << std::endl; printUsageAndExit = true; rt = 2; } } if (printUsageAndExit) { std::cout << _TXT("usage:") << " strusAnalyze [options] <phrasepath>" << std::endl; std::cout << "<phrasepath> = " << _TXT("path to phrase to analyze ('-' for stdin)") << std::endl; std::cout << "description: " << _TXT("tokenizes and normalizes a text segment") << std::endl; std::cout << " " << _TXT("and prints the result to stdout.") << std::endl; std::cout << _TXT("options:") << std::endl; std::cout << "-h|--help" << std::endl; std::cout << " " << _TXT("Print this usage and do nothing else") << std::endl; std::cout << "-v|--version" << std::endl; std::cout << " " << _TXT("Print the program version and do nothing else") << std::endl; std::cout << "--license" << std::endl; std::cout << " " << _TXT("Print 3rd party licences requiring reference") << std::endl; std::cout << "-m|--module <MOD>" << std::endl; std::cout << " " << _TXT("Load components from module <MOD>") << std::endl; std::cout << "-M|--moduledir <DIR>" << std::endl; std::cout << " " << _TXT("Search modules to load first in <DIR>") << std::endl; std::cout << "-R|--resourcedir <DIR>" << std::endl; std::cout << " " << _TXT("Search resource files for analyzer first in <DIR>") << std::endl; std::cout << "-t|--tokenizer <CALL>" << std::endl; std::cout << " " << _TXT("Use the tokenizer <CALL> (default 'content')") << std::endl; std::cout << "-n|--normalizer <CALL>" << std::endl; std::cout << " " << _TXT("Use the normalizer <CALL> (default 'orig')") << std::endl; std::cout << "-q|--quot <STR>" << std::endl; std::cout << " " << _TXT("Use the string <STR> as quote for the result (default \"\'\")") << std::endl; std::cout << "-p|--plain" << std::endl; std::cout << " " << _TXT("Do not print position and define default quotes as empty") << std::endl; std::cout << "-T|--trace <CONFIG>" << std::endl; std::cout << " " << _TXT("Print method call traces configured with <CONFIG>") << std::endl; std::cout << " " << strus::string_format( _TXT("Example: %s"), "-T \"log=dump;file=stdout\"") << std::endl; return rt; } // Declare trace proxy objects: typedef strus::Reference<strus::TraceProxy> TraceReference; std::vector<TraceReference> trace; if (opt("trace")) { std::vector<std::string> tracecfglist( opt.list("trace")); std::vector<std::string>::const_iterator ti = tracecfglist.begin(), te = tracecfglist.end(); for (; ti != te; ++ti) { trace.push_back( new strus::TraceProxy( moduleLoader.get(), *ti, errorBuffer.get())); } } std::string resultQuot = "'"; bool resultPlain = false; if (opt( "plain")) { resultPlain = true; resultQuot.clear(); } if (opt( "quot")) { resultQuot = opt[ "quot"]; } std::string docpath = opt[0]; std::string tokenizer( "content"); if (opt( "tokenizer")) { tokenizer = opt[ "tokenizer"]; } std::string normalizer( "orig"); if (opt( "normalizer")) { normalizer = opt[ "normalizer"]; } // Set paths for locating resources: if (opt("resourcedir")) { std::vector<std::string> pathlist( opt.list("resourcedir")); std::vector<std::string>::const_iterator pi = pathlist.begin(), pe = pathlist.end(); for (; pi != pe; ++pi) { moduleLoader->addResourcePath( *pi); } } // Create root object for analyzer: std::auto_ptr<strus::AnalyzerObjectBuilderInterface> analyzerBuilder( moduleLoader->createAnalyzerObjectBuilder()); if (!analyzerBuilder.get()) throw strus::runtime_error(_TXT("failed to create analyzer object builder")); // Create proxy objects if tracing enabled: { std::vector<TraceReference>::const_iterator ti = trace.begin(), te = trace.end(); for (; ti != te; ++ti) { strus::AnalyzerObjectBuilderInterface* proxy = (*ti)->createProxy( analyzerBuilder.get()); analyzerBuilder.release(); analyzerBuilder.reset( proxy); } } // Create objects for analyzer: std::auto_ptr<strus::QueryAnalyzerInterface> analyzer( analyzerBuilder->createQueryAnalyzer()); if (!analyzer.get()) throw strus::runtime_error(_TXT("failed to create analyzer")); const strus::TextProcessorInterface* textproc = analyzerBuilder->getTextProcessor(); if (!textproc) throw strus::runtime_error(_TXT("failed to get text processor")); // Create phrase type (tokenizer and normalizer): std::string phraseType; if (!strus::loadQueryAnalyzerPhraseType( *analyzer, textproc, phraseType, "", normalizer, tokenizer, errorBuffer.get())) { throw strus::runtime_error(_TXT("failed to load analyze phrase type")); } // Load the phrase: std::string phrase; if (docpath == "-") { unsigned int ec = strus::readStdin( phrase); if (ec) throw strus::runtime_error( _TXT( "error reading input from stdin (errno %u)"), ec); } else { unsigned int ec = strus::readFile( docpath, phrase); if (ec) throw strus::runtime_error( _TXT( "error reading input file '%s' (errno %u)"), docpath.c_str(), ec); } // Analyze the phrase and print the result: std::vector<strus::analyzer::Term> terms = analyzer->analyzePhrase( phraseType, phrase); std::sort( terms.begin(), terms.end(), TermOrder()); std::vector<strus::analyzer::Term>::const_iterator ti = terms.begin(), te = terms.end(); for (; ti != te; ++ti) { if (!resultPlain) { std::cout << ti->pos() << " "; } std::cout << resultQuot << ti->value() << resultQuot << std::endl; } if (errorBuffer->hasError()) { throw strus::runtime_error(_TXT("error in analyze phrase")); } return 0; } catch (const std::bad_alloc&) { std::cerr << _TXT("ERROR ") << _TXT("out of memory") << std::endl; } catch (const std::runtime_error& e) { const char* errormsg = errorBuffer->fetchError(); if (errormsg) { std::cerr << _TXT("ERROR ") << e.what() << ": " << errormsg << std::endl; } else { std::cerr << _TXT("ERROR ") << e.what() << std::endl; } } catch (const std::exception& e) { std::cerr << _TXT("EXCEPTION ") << e.what() << std::endl; } return -1; }
int main(int argc, char **argv) { const char *av = NULL; int db; int optchar; int option_index = 0; while ((optchar = getopt_long(argc, argv, "ace:ifgGIlL:noOpPqrstTuvVx", long_options, &option_index)) != EOF) { switch (optchar) { case 0: break; case 'a': aflag++; break; case 'c': cflag++; setcom(optchar); break; case 'e': av = optarg; break; case 'f': fflag++; xflag++; setcom(optchar); break; case 'g': gflag++; setcom(optchar); break; case 'G': Gflag++; break; case 'i': iflag++; break; case 'I': Iflag++; setcom(optchar); break; case 'l': lflag++; break; case 'L': file_list = optarg; 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 't': tflag++; break; case 'T': Tflag++; break; case 'u': uflag++; setcom(optchar); break; case 'v': vflag++; break; case 'V': Vflag++; break; case 'x': xflag++; break; case ENCODE_PATH: if (strlen(optarg) > 255) die("too many encode chars."); if (strchr(optarg, '/') || strchr(optarg, '.')) die("cannot encode '/' and '.' in the path."); set_encode_chars((unsigned char *)optarg); break; case 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 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, "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; default: usage(); break; } } if (qflag) vflag = 0; if (show_help) help(); argc -= optind; argv += optind; /* * 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 (show_version) version(av, vflag); /* * 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(); /* * remove leading blanks. */ if (!Iflag && !gflag && av) for (; *av == ' ' || *av == '\t'; av++) ; if (cflag && av && isregex(av)) die_with_code(2, "only name char is allowed with -c option."); /* * get path of following directories. * o current directory * o root of source tree * o dbpath directory * * if GTAGS not found, getdbpath doesn't return. */ getdbpath(cwd, root, dbpath, (pflag && vflag)); /* * 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 = usable("gtags"); if (!gtags) die("gtags command not found."); if (chdir(root) < 0) die("cannot change directory to '%s'.", root); strbuf_puts(sb, gtags); strbuf_puts(sb, " -i"); if (vflag) strbuf_putc(sb, 'v'); strbuf_putc(sb, ' '); strbuf_puts(sb, dbpath); if (system(strbuf_value(sb))) exit(1); strbuf_close(sb); exit(0); } /* * complete function name */ if (cflag) { if (Iflag) completion_idutils(dbpath, root, av); else completion(dbpath, root, av); exit(0); } /* * make local prefix. * local prefix must starts with './' and ends with '/'. */ if (lflag) { STRBUF *sb = strbuf_open(0); strbuf_putc(sb, '.'); if (strcmp(root, cwd) != 0) { char *p = cwd + 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 } /* * 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 (rflag && sflag) db = GRTAGS + GSYMS; else db = (rflag) ? GRTAGS : ((sflag) ? GSYMS : GTAGS); } /* * 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; } } /* * decide path conversion type. */ if (nofilter & PATH_FILTER) type = PATH_THROUGH; else if (aflag) type = PATH_ABSOLUTE; else type = PATH_RELATIVE; /* * 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; }
int main( int argc, const char* argv[]) { int rt = 0; strus::DebugTraceInterface* dbgtrace = strus::createDebugTrace_standard( 2); if (!dbgtrace) { std::cerr << _TXT("failed to create debug trace") << std::endl; return -1; } strus::local_ptr<strus::ErrorBufferInterface> errorBuffer( strus::createErrorBuffer_standard( 0, 2, dbgtrace/*passed with ownership*/)); if (!errorBuffer.get()) { std::cerr << _TXT("failed to create error buffer") << std::endl; return -1; } try { bool printUsageAndExit = false; strus::ProgramOptions opt( errorBuffer.get(), argc, argv, 13, "h,help", "v,version", "license", "G,debug:", "t,tokenizer:", "n,normalizer:", "m,module:", "M,moduledir:", "q,quot:", "P,plain", "F,fileinput", "R,resourcedir:", "T,trace:"); if (errorBuffer->hasError()) { throw strus::runtime_error(_TXT("failed to parse program arguments")); } if (opt( "help")) printUsageAndExit = true; // Enable debugging selected with option 'debug': { std::vector<std::string> dbglist = opt.list( "debug"); std::vector<std::string>::const_iterator gi = dbglist.begin(), ge = dbglist.end(); for (; gi != ge; ++gi) { if (!dbgtrace->enable( *gi)) { throw strus::runtime_error(_TXT("failed to enable debug '%s'"), gi->c_str()); } } } strus::local_ptr<strus::ModuleLoaderInterface> moduleLoader( strus::createModuleLoader( errorBuffer.get())); if (!moduleLoader.get()) throw std::runtime_error( _TXT("failed to create module loader")); if (opt("moduledir")) { std::vector<std::string> modirlist( opt.list("moduledir")); std::vector<std::string>::const_iterator mi = modirlist.begin(), me = modirlist.end(); for (; mi != me; ++mi) { moduleLoader->addModulePath( *mi); } moduleLoader->addSystemModulePath(); } if (opt("module")) { std::vector<std::string> modlist( opt.list("module")); std::vector<std::string>::const_iterator mi = modlist.begin(), me = modlist.end(); for (; mi != me; ++mi) { if (!moduleLoader->loadModule( *mi)) { throw strus::runtime_error(_TXT("error failed to load module %s"), mi->c_str()); } } } if (opt("license")) { std::vector<std::string> licenses_3rdParty = moduleLoader->get3rdPartyLicenseTexts(); std::vector<std::string>::const_iterator ti = licenses_3rdParty.begin(), te = licenses_3rdParty.end(); if (ti != te) std::cout << _TXT("3rd party licenses:") << std::endl; for (; ti != te; ++ti) { std::cout << *ti << std::endl; } std::cout << std::endl; if (!printUsageAndExit) return 0; } if (opt( "version")) { std::cout << _TXT("Strus utilities version ") << STRUS_UTILITIES_VERSION_STRING << std::endl; std::cout << _TXT("Strus module version ") << STRUS_MODULE_VERSION_STRING << std::endl; std::cout << _TXT("Strus rpc version ") << STRUS_RPC_VERSION_STRING << std::endl; std::cout << _TXT("Strus trace version ") << STRUS_TRACE_VERSION_STRING << std::endl; std::cout << _TXT("Strus analyzer version ") << STRUS_ANALYZER_VERSION_STRING << std::endl; std::cout << _TXT("Strus base version ") << STRUS_BASE_VERSION_STRING << std::endl; std::vector<std::string> versions_3rdParty = moduleLoader->get3rdPartyVersionTexts(); std::vector<std::string>::const_iterator vi = versions_3rdParty.begin(), ve = versions_3rdParty.end(); if (vi != ve) std::cout << _TXT("3rd party versions:") << std::endl; for (; vi != ve; ++vi) { std::cout << *vi << std::endl; } if (!printUsageAndExit) return 0; } else if (!printUsageAndExit) { if (opt.nofargs() > 1) { std::cerr << _TXT("too many arguments") << std::endl; printUsageAndExit = true; rt = 1; } if (opt.nofargs() < 1) { std::cerr << _TXT("too few arguments") << std::endl; printUsageAndExit = true; rt = 2; } } if (printUsageAndExit) { std::cout << _TXT("usage:") << " strusAnalyze [options] <phrase>" << std::endl; std::cout << "<phrase> = " << _TXT("path to phrase to analyze") << std::endl; std::cout << " " << _TXT("file or '-' for stdin if option -F is specified)") << std::endl; std::cout << "description: " << _TXT("tokenizes and normalizes a text segment") << std::endl; std::cout << " " << _TXT("and prints the result to stdout.") << std::endl; std::cout << _TXT("options:") << std::endl; std::cout << "-h|--help" << std::endl; std::cout << " " << _TXT("Print this usage and do nothing else") << std::endl; std::cout << "-v|--version" << std::endl; std::cout << " " << _TXT("Print the program version and do nothing else") << std::endl; std::cout << "--license" << std::endl; std::cout << " " << _TXT("Print 3rd party licences requiring reference") << std::endl; std::cout << "-G|--debug <COMP>" << std::endl; std::cout << " " << _TXT("Issue debug messages for component <COMP> to stderr") << std::endl; std::cout << "-m|--module <MOD>" << std::endl; std::cout << " " << _TXT("Load components from module <MOD>") << std::endl; std::cout << "-M|--moduledir <DIR>" << std::endl; std::cout << " " << _TXT("Search modules to load first in <DIR>") << std::endl; std::cout << "-R|--resourcedir <DIR>" << std::endl; std::cout << " " << _TXT("Search resource files for analyzer first in <DIR>") << std::endl; std::cout << "-t|--tokenizer <CALL>" << std::endl; std::cout << " " << _TXT("Use the tokenizer <CALL> (default 'content')") << std::endl; std::cout << "-n|--normalizer <CALL>" << std::endl; std::cout << " " << _TXT("Use the normalizer <CALL> (default 'orig')") << std::endl; std::cout << "-q|--quot <STR>" << std::endl; std::cout << " " << _TXT("Use the string <STR> as quote for the result (default \"\'\")") << std::endl; std::cout << "-P|--plain" << std::endl; std::cout << " " << _TXT("Print results without quotes and without an end of line for each result") << std::endl; std::cout << "-F|--fileinput" << std::endl; std::cout << " " << _TXT("Interpret phrase argument as a file name containing the input") << std::endl; std::cout << "-T|--trace <CONFIG>" << std::endl; std::cout << " " << _TXT("Print method call traces configured with <CONFIG>") << std::endl; std::cout << " " << strus::string_format( _TXT("Example: %s"), "-T \"log=dump;file=stdout\"") << std::endl; return rt; } // Declare trace proxy objects: typedef strus::Reference<strus::TraceProxy> TraceReference; std::vector<TraceReference> trace; if (opt("trace")) { std::vector<std::string> tracecfglist( opt.list("trace")); std::vector<std::string>::const_iterator ti = tracecfglist.begin(), te = tracecfglist.end(); for (; ti != te; ++ti) { trace.push_back( new strus::TraceProxy( moduleLoader.get(), *ti, errorBuffer.get())); } } std::string resultQuot = "'"; bool resultPlain = false; if (opt( "plain")) { resultPlain = true; resultQuot.clear(); } if (opt( "quot")) { resultQuot = opt[ "quot"]; } std::string phrasestring = opt[0]; std::string tokenizer( "content"); if (opt( "tokenizer")) { tokenizer = opt[ "tokenizer"]; } std::string normalizer( "orig"); if (opt( "normalizer")) { normalizer = opt[ "normalizer"]; } // Set paths for locating resources: if (opt("resourcedir")) { std::vector<std::string> pathlist( opt.list("resourcedir")); std::vector<std::string>::const_iterator pi = pathlist.begin(), pe = pathlist.end(); for (; pi != pe; ++pi) { moduleLoader->addResourcePath( *pi); } } // Create objects for analyzer: strus::local_ptr<strus::RpcClientMessagingInterface> messaging; strus::local_ptr<strus::RpcClientInterface> rpcClient; strus::local_ptr<strus::AnalyzerObjectBuilderInterface> analyzerBuilder; if (opt("rpc")) { messaging.reset( strus::createRpcClientMessaging( opt[ "rpc"], errorBuffer.get())); if (!messaging.get()) throw std::runtime_error( _TXT("failed to create rpc client messaging")); rpcClient.reset( strus::createRpcClient( messaging.get(), errorBuffer.get())); if (!rpcClient.get()) throw std::runtime_error( _TXT("failed to create rpc client")); (void)messaging.release(); analyzerBuilder.reset( rpcClient->createAnalyzerObjectBuilder()); if (!analyzerBuilder.get()) throw std::runtime_error( _TXT("failed to create rpc analyzer object builder")); } else { analyzerBuilder.reset( moduleLoader->createAnalyzerObjectBuilder()); if (!analyzerBuilder.get()) throw std::runtime_error( _TXT("failed to create analyzer object builder")); } // Create proxy objects if tracing enabled: { std::vector<TraceReference>::const_iterator ti = trace.begin(), te = trace.end(); for (; ti != te; ++ti) { strus::AnalyzerObjectBuilderInterface* proxy = (*ti)->createProxy( analyzerBuilder.get()); analyzerBuilder.release(); analyzerBuilder.reset( proxy); } } if (errorBuffer->hasError()) { throw std::runtime_error( _TXT("error in initialization")); } // Create objects for analyzer: strus::local_ptr<strus::QueryAnalyzerInstanceInterface> analyzer( analyzerBuilder->createQueryAnalyzer()); if (!analyzer.get()) throw std::runtime_error( _TXT("failed to create analyzer")); const strus::TextProcessorInterface* textproc = analyzerBuilder->getTextProcessor(); if (!textproc) throw std::runtime_error( _TXT("failed to get text processor")); std::string analyzerConfig = strus::string_format( "[Element]\nfeature = %s %s text", normalizer.c_str(), tokenizer.c_str()); // Create phrase type (tokenizer and normalizer): if (!strus::load_QueryAnalyzer_program_std( analyzer.get(), textproc, analyzerConfig, errorBuffer.get())) { throw strus::runtime_error( _TXT("failed to load query analyzer: %s"), errorBuffer->fetchError()); } // Load the phrase: bool queryIsFile = opt("fileinput"); if (queryIsFile) { int ec; std::string ps; if (phrasestring == "-") { ec = strus::readStdin( ps); if (ec) throw strus::runtime_error( _TXT("failed to read query from stdin (errno %u)"), ec); } else { ec = strus::readFile( phrasestring, ps); if (ec) throw strus::runtime_error(_TXT("failed to read query from file %s (errno %u)"), phrasestring.c_str(), ec); } phrasestring = ps; } // Analyze the phrase and print the result: strus::local_ptr<strus::QueryAnalyzerContextInterface> qryanactx( analyzer->createContext()); if (!qryanactx.get()) throw std::runtime_error( _TXT("failed to create query analyzer context")); qryanactx->putField( 1, "", phrasestring); strus::analyzer::QueryTermExpression qry = qryanactx->analyze(); if (errorBuffer->hasError()) throw std::runtime_error( _TXT("query analysis failed")); std::vector<strus::analyzer::QueryTerm> terms; std::vector<strus::analyzer::QueryTermExpression::Instruction>::const_iterator ii = qry.instructions().begin(), ie = qry.instructions().end(); for (int iidx=0; ii != ie; ++ii,++iidx) { if (ii->opCode() == strus::analyzer::QueryTermExpression::Instruction::Term) { const strus::analyzer::QueryTerm& term = qry.term( ii->idx()); if (resultPlain) { if (iidx) std::cout << " "; std::cout << term.value(); } else { std::cout << resultQuot << term.value() << resultQuot << std::endl; } } } if (errorBuffer->hasError()) { throw std::runtime_error( _TXT("error in analyze phrase")); } std::cerr << _TXT("done.") << std::endl; if (!dumpDebugTrace( dbgtrace, NULL/*filename ~ NULL = stderr*/)) { std::cerr << _TXT("failed to dump debug trace to file") << std::endl; } return 0; } catch (const std::bad_alloc&) { std::cerr << _TXT("ERROR ") << _TXT("out of memory") << std::endl; return -2; } catch (const std::runtime_error& e) { const char* errormsg = errorBuffer->fetchError(); if (errormsg) { std::cerr << _TXT("ERROR ") << e.what() << ": " << errormsg << std::endl; } else { std::cerr << _TXT("ERROR ") << e.what() << std::endl; } } catch (const std::exception& e) { std::cerr << _TXT("EXCEPTION ") << e.what() << std::endl; } if (!dumpDebugTrace( dbgtrace, NULL/*filename ~ NULL = stderr*/)) { std::cerr << _TXT("failed to dump debug trace to file") << std::endl; } return -1; }
int main( int argc_, const char* argv_[]) { int rt = 0; std::auto_ptr<strus::ErrorBufferInterface> errorBuffer( strus::createErrorBuffer_standard( 0, 2)); if (!errorBuffer.get()) { std::cerr << _TXT("failed to create error buffer") << std::endl; return -1; } strus::ProgramOptions opt; bool printUsageAndExit = false; try { opt = strus::ProgramOptions( argc_, argv_, 14, "h,help", "v,version", "license", "Q,quiet", "u,user:"******"N,nofranks:", "I,firstrank:", "D,time", "m,module:", "M,moduledir:", "R,resourcedir:", "s,storage:", "r,rpc:", "T,trace:"); if (opt( "help")) printUsageAndExit = true; std::auto_ptr<strus::ModuleLoaderInterface> moduleLoader( strus::createModuleLoader( errorBuffer.get())); if (!moduleLoader.get()) throw strus::runtime_error(_TXT("failed to create module loader")); if (opt("moduledir")) { if (opt("rpc")) throw strus::runtime_error(_TXT("specified mutual exclusive options %s and %s"), "--moduledir", "--rpc"); std::vector<std::string> modirlist( opt.list("moduledir")); std::vector<std::string>::const_iterator mi = modirlist.begin(), me = modirlist.end(); for (; mi != me; ++mi) { moduleLoader->addModulePath( *mi); } moduleLoader->addSystemModulePath(); } if (opt("module")) { if (opt("rpc")) throw strus::runtime_error(_TXT("specified mutual exclusive options %s and %s"), "--module", "--rpc"); std::vector<std::string> modlist( opt.list("module")); std::vector<std::string>::const_iterator mi = modlist.begin(), me = modlist.end(); for (; mi != me; ++mi) { if (!moduleLoader->loadModule( *mi)) { throw strus::runtime_error(_TXT("error failed to load module %s"), mi->c_str()); } } } if (opt("license")) { std::vector<std::string> licenses_3rdParty = moduleLoader->get3rdPartyLicenseTexts(); std::vector<std::string>::const_iterator ti = licenses_3rdParty.begin(), te = licenses_3rdParty.end(); if (ti != te) std::cout << _TXT("3rd party licenses:") << std::endl; for (; ti != te; ++ti) { std::cout << *ti << std::endl; } std::cerr << std::endl; if (!printUsageAndExit) return 0; } if (opt( "version")) { std::cout << _TXT("Strus utilities version ") << STRUS_UTILITIES_VERSION_STRING << std::endl; std::cout << _TXT("Strus module version ") << STRUS_MODULE_VERSION_STRING << std::endl; std::cout << _TXT("Strus rpc version ") << STRUS_RPC_VERSION_STRING << std::endl; std::cout << _TXT("Strus trace version ") << STRUS_TRACE_VERSION_STRING << std::endl; std::cout << _TXT("Strus analyzer version ") << STRUS_ANALYZER_VERSION_STRING << std::endl; std::cout << _TXT("Strus storage version ") << STRUS_STORAGE_VERSION_STRING << std::endl; std::cout << _TXT("Strus base version ") << STRUS_BASE_VERSION_STRING << std::endl; std::vector<std::string> versions_3rdParty = moduleLoader->get3rdPartyVersionTexts(); std::vector<std::string>::const_iterator vi = versions_3rdParty.begin(), ve = versions_3rdParty.end(); if (vi != ve) std::cout << _TXT("3rd party versions:") << std::endl; for (; vi != ve; ++vi) { std::cout << *vi << std::endl; } if (!printUsageAndExit) return 0; } else if (!printUsageAndExit) { if (opt.nofargs() > 3) { std::cerr << _TXT("too many arguments") << std::endl; printUsageAndExit = true; rt = 1; } if (opt.nofargs() < 3) { std::cerr << _TXT("too few arguments") << std::endl; printUsageAndExit = true; rt = 2; } } if (printUsageAndExit) { std::cout << _TXT("usage:") << " strusQuery [options] <anprg> <qeprg> <query>" << std::endl; std::cout << "<anprg> = " << _TXT("path of query analyzer program") << std::endl; std::cout << "<qeprg> = " << _TXT("path of query eval program") << std::endl; std::cout << "<query> = " << _TXT("path of query or '-' for stdin") << std::endl; std::cout << _TXT("description: Executes a query or a list of queries from a file.") << std::endl; std::cout << _TXT("options:") << std::endl; std::cout << "-h|--help" << std::endl; std::cout << " " << _TXT("Print this usage and do nothing else") << std::endl; std::cout << "-v|--version" << std::endl; std::cout << " " << _TXT("Print the program version and do nothing else") << std::endl; std::cout << "--license" << std::endl; std::cout << " " << _TXT("Print 3rd party licences requiring reference") << std::endl; std::cout << "-s|--storage <CONFIG>" << std::endl; std::cout << " " << _TXT("Define the storage configuration string as <CONFIG>") << std::endl; if (!opt("rpc")) { std::cout << _TXT(" <CONFIG> is a semicolon ';' separated list of assignments:") << std::endl; printStorageConfigOptions( std::cout, moduleLoader.get(), (opt("storage")?opt["storage"]:""), errorBuffer.get()); } std::cout << "-u|--user <NAME>" << std::endl; std::cout << " " << _TXT("Use user name <NAME> for the query") << std::endl; std::cout << "-N|--nofranks <N>" << std::endl; std::cout << " " << _TXT("Return maximum <N> ranks as query result") << std::endl; std::cout << "-I|--firstrank <N>" << std::endl; std::cout << " " << _TXT("Return the result starting with rank <N> as first rank") << std::endl; std::cout << "-Q|--quiet" << std::endl; std::cout << " " << _TXT("No output of results") << std::endl; std::cout << "-D|--time" << std::endl; std::cout << " " << _TXT("Do print duration of pure query evaluation") << std::endl; std::cout << "-m|--module <MOD>" << std::endl; std::cout << " " << _TXT("Load components from module <MOD>") << std::endl; std::cout << "-M|--moduledir <DIR>" << std::endl; std::cout << " " << _TXT("Search modules to load first in <DIR>") << std::endl; std::cout << "-R|--resourcedir <DIR>" << std::endl; std::cout << " " << _TXT("Search resource files for analyzer first in <DIR>") << std::endl; std::cout << "-r|--rpc <ADDR>" << std::endl; std::cout << " " << _TXT("Execute the command on the RPC server specified by <ADDR>") << std::endl; std::cout << "-T|--trace <CONFIG>" << std::endl; std::cout << " " << _TXT("Print method call traces configured with <CONFIG>") << std::endl; std::cout << " " << strus::string_format( _TXT("Example: %s"), "-T \"log=dump;file=stdout\"") << std::endl; return rt; } // Parse arguments: bool quiet = opt( "quiet"); bool measureDuration = opt( "time"); std::string username; std::size_t nofRanks = 20; std::size_t firstRank = 0; std::string storagecfg; if (opt("user")) { username = opt[ "user"]; } if (opt("nofranks")) { nofRanks = opt.asUint( "nofranks"); } if (opt("firstrank")) { firstRank = opt.asUint( "firstrank"); } if (opt("storage")) { if (opt("rpc")) throw strus::runtime_error(_TXT("specified mutual exclusive options %s and %s"), "--moduledir", "--rpc"); storagecfg = opt["storage"]; } std::string analyzerprg = opt[0]; std::string queryprg = opt[1]; std::string querypath = opt[2]; // Declare trace proxy objects: typedef strus::Reference<strus::TraceProxy> TraceReference; std::vector<TraceReference> trace; if (opt("trace")) { std::vector<std::string> tracecfglist( opt.list("trace")); std::vector<std::string>::const_iterator ti = tracecfglist.begin(), te = tracecfglist.end(); for (; ti != te; ++ti) { trace.push_back( new strus::TraceProxy( moduleLoader.get(), *ti, errorBuffer.get())); } } // Set paths for locating resources: if (opt("resourcedir")) { std::vector<std::string> pathlist( opt.list("resourcedir")); std::vector<std::string>::const_iterator pi = pathlist.begin(), pe = pathlist.end(); for (; pi != pe; ++pi) { moduleLoader->addResourcePath( *pi); } } std::string resourcepath; if (0!=strus::getParentPath( analyzerprg, resourcepath)) { throw strus::runtime_error( _TXT("failed to evaluate resource path")); } if (!resourcepath.empty()) { moduleLoader->addResourcePath( resourcepath); } // Create objects for query evaluation: std::auto_ptr<strus::RpcClientMessagingInterface> messaging; std::auto_ptr<strus::RpcClientInterface> rpcClient; std::auto_ptr<strus::AnalyzerObjectBuilderInterface> analyzerBuilder; std::auto_ptr<strus::StorageObjectBuilderInterface> storageBuilder; if (opt("rpc")) { messaging.reset( strus::createRpcClientMessaging( opt[ "rpc"], errorBuffer.get())); if (!messaging.get()) throw strus::runtime_error(_TXT("failed to create rpc client messaging")); rpcClient.reset( strus::createRpcClient( messaging.get(), errorBuffer.get())); if (!rpcClient.get()) throw strus::runtime_error(_TXT("failed to create rpc client")); (void)messaging.release(); analyzerBuilder.reset( rpcClient->createAnalyzerObjectBuilder()); if (!analyzerBuilder.get()) throw strus::runtime_error(_TXT("failed to create rpc analyzer object builder")); storageBuilder.reset( rpcClient->createStorageObjectBuilder()); if (!storageBuilder.get()) throw strus::runtime_error(_TXT("failed to create rpc storage object builder")); } else { analyzerBuilder.reset( moduleLoader->createAnalyzerObjectBuilder()); if (!analyzerBuilder.get()) throw strus::runtime_error(_TXT("failed to create analyzer object builder")); storageBuilder.reset( moduleLoader->createStorageObjectBuilder()); if (!storageBuilder.get()) throw strus::runtime_error(_TXT("failed to create storage object builder")); } // Create proxy objects if tracing enabled: std::vector<TraceReference>::const_iterator ti = trace.begin(), te = trace.end(); for (; ti != te; ++ti) { strus::AnalyzerObjectBuilderInterface* aproxy = (*ti)->createProxy( analyzerBuilder.get()); analyzerBuilder.release(); analyzerBuilder.reset( aproxy); strus::StorageObjectBuilderInterface* sproxy = (*ti)->createProxy( storageBuilder.get()); storageBuilder.release(); storageBuilder.reset( sproxy); } // Create objects: std::auto_ptr<strus::StorageClientInterface> storage( strus::createStorageClient( storageBuilder.get(), errorBuffer.get(), storagecfg)); if (!storage.get()) throw strus::runtime_error(_TXT("failed to create storage client")); strus::utils::ScopedPtr<strus::QueryAnalyzerInterface> analyzer( analyzerBuilder->createQueryAnalyzer()); if (!analyzer.get()) throw strus::runtime_error(_TXT("failed to create query analyzer")); strus::utils::ScopedPtr<strus::QueryEvalInterface> qeval( storageBuilder->createQueryEval()); if (!qeval.get()) throw strus::runtime_error(_TXT("failed to create query evaluation interface")); const strus::QueryProcessorInterface* qproc = storageBuilder->getQueryProcessor(); if (!qproc) throw strus::runtime_error(_TXT("failed to get query processor")); const strus::TextProcessorInterface* textproc = analyzerBuilder->getTextProcessor(); if (!textproc) throw strus::runtime_error(_TXT("failed to get text processor")); // Load query analyzer program: unsigned int ec; std::string analyzerProgramSource; ec = strus::readFile( analyzerprg, analyzerProgramSource); if (ec) throw strus::runtime_error(_TXT("failed to load analyzer program %s (errno %u)"), analyzerprg.c_str(), ec); if (!strus::loadQueryAnalyzerProgram( *analyzer, textproc, analyzerProgramSource, errorBuffer.get())) { throw strus::runtime_error(_TXT("failed to load query analyzer program")); } // Load query evaluation program: std::string qevalProgramSource; ec = strus::readFile( queryprg, qevalProgramSource); if (ec) throw strus::runtime_error(_TXT("failed to load query eval program %s (errno %u)"), queryprg.c_str(), ec); if (!strus::loadQueryEvalProgram( *qeval, qproc, qevalProgramSource, errorBuffer.get())) { throw strus::runtime_error(_TXT("failed to load query evaluation program")); } // Load query: std::string querystring; if (querypath == "-") { ec = strus::readStdin( querystring); if (ec) throw strus::runtime_error( _TXT("failed to read query string from stdin (errno %u)"), ec); } else { ec = strus::readFile( querypath, querystring); if (ec) throw strus::runtime_error(_TXT("failed to read query string from file %s (errno %u)"), querypath.c_str(), ec); } unsigned int nofQueries = 0; double startTime = 0.0; if (measureDuration) { startTime = getTimeStamp(); } std::string::const_iterator si = querystring.begin(), se = querystring.end(); std::string qs; while (strus::scanNextProgram( qs, si, se, errorBuffer.get())) { ++nofQueries; std::auto_ptr<strus::QueryInterface> query( qeval->createQuery( storage.get())); if (!query.get()) throw strus::runtime_error(_TXT("failed to create query object")); if (!strus::loadQuery( *query, analyzer.get(), qproc, qs, errorBuffer.get())) { throw strus::runtime_error(_TXT("failed to load query from source")); } query->setMaxNofRanks( nofRanks); query->setMinRank( firstRank); if (!username.empty()) { query->addUserName( username); } strus::QueryResult result = query->evaluate(); if (!quiet) { std::cout << strus::string_format( _TXT("evaluated till pass %u, got %u ranks (%u without restrictions applied):"), result.evaluationPass(), result.nofDocumentsRanked(), result.nofDocumentsVisited()) << std::endl; std::cout << strus::string_format( _TXT("ranked list (starting with rank %u, maximum %u results):"), firstRank, nofRanks) << std::endl; } std::vector<strus::ResultDocument>::const_iterator wi = result.ranks().begin(), we = result.ranks().end(); if (!quiet) { for (int widx=1; wi != we; ++wi,++widx) { std::cout << strus::string_format( _TXT( "[%u] %u score %f"), widx, wi->docno(), wi->weight()) << std::endl; std::vector<strus::SummaryElement>::const_iterator ai = wi->summaryElements().begin(), ae = wi->summaryElements().end(); for (; ai != ae; ++ai) { std::cout << "\t" << ai->name(); if (ai->index() >= 0) { std::cout << "[" << ai->index() << "]"; } std::cout << " = '" << ai->value() << "'"; std::cout << " " << ai->weight() << std::endl; } } } } if (measureDuration) { double endTime = getTimeStamp(); double duration = endTime - startTime; std::cerr << strus::string_format( _TXT("evaluated %u queries in %.4f seconds"), nofQueries, duration) << std::endl; } if (errorBuffer->hasError()) { throw strus::runtime_error(_TXT("unhandled error in command line query")); } return 0; } catch (const std::bad_alloc&) { std::cerr << _TXT("ERROR ") << _TXT("out of memory") << std::endl; } catch (const std::runtime_error& e) { const char* errormsg = errorBuffer->fetchError(); if (errormsg) { std::cerr << _TXT("ERROR ") << e.what() << ": " << errormsg << std::endl; } else { std::cerr << _TXT("ERROR ") << e.what() << std::endl; } } catch (const std::exception& e) { std::cerr << _TXT("EXCEPTION ") << e.what() << std::endl; } return -1; }
int main( int argc_, const char* argv_[]) { int rt = 0; strus::DebugTraceInterface* dbgtrace = strus::createDebugTrace_standard( 2); if (!dbgtrace) { std::cerr << _TXT("failed to create debug trace") << std::endl; return -1; } strus::local_ptr<strus::ErrorBufferInterface> errorBuffer( strus::createErrorBuffer_standard( 0, 2, dbgtrace/*passed with ownership*/)); if (!errorBuffer.get()) { delete dbgtrace; std::cerr << _TXT("failed to create error buffer") << std::endl; return -1; } try { bool printUsageAndExit = false; bool withDebugInfo = false; strus::ProgramOptions opt( errorBuffer.get(), argc_, argv_, 18, "h,help", "v,version", "license", "G,debug:", "Q,quiet", "u,user:"******"N,nofranks:", "I,firstrank:", "F,fileinput", "D,time", "m,module:", "M,moduledir:", "R,resourcedir:", "s,storage:", "S,configfile:", "r,rpc:", "T,trace:", "V,verbose"); if (errorBuffer->hasError()) { throw strus::runtime_error(_TXT("failed to parse program arguments")); } if (opt( "help")) printUsageAndExit = true; // Enable debugging selected with option 'debug': { std::vector<std::string> dbglist = opt.list( "debug"); std::vector<std::string>::const_iterator gi = dbglist.begin(), ge = dbglist.end(); for (; gi != ge; ++gi) { if (*gi == "weighting") { withDebugInfo = true; } if (!dbgtrace->enable( *gi)) { throw strus::runtime_error(_TXT("failed to enable debug '%s'"), gi->c_str()); } } } strus::local_ptr<strus::ModuleLoaderInterface> moduleLoader( strus::createModuleLoader( errorBuffer.get())); if (!moduleLoader.get()) throw std::runtime_error( _TXT("failed to create module loader")); if (opt("moduledir")) { if (opt("rpc")) throw strus::runtime_error(_TXT("specified mutual exclusive options %s and %s"), "--moduledir", "--rpc"); std::vector<std::string> modirlist( opt.list("moduledir")); std::vector<std::string>::const_iterator mi = modirlist.begin(), me = modirlist.end(); for (; mi != me; ++mi) { moduleLoader->addModulePath( *mi); } moduleLoader->addSystemModulePath(); } if (opt("module")) { if (opt("rpc")) throw strus::runtime_error(_TXT("specified mutual exclusive options %s and %s"), "--module", "--rpc"); std::vector<std::string> modlist( opt.list("module")); std::vector<std::string>::const_iterator mi = modlist.begin(), me = modlist.end(); for (; mi != me; ++mi) { if (!moduleLoader->loadModule( *mi)) { throw strus::runtime_error(_TXT("error failed to load module %s"), mi->c_str()); } } } if (opt("license")) { std::vector<std::string> licenses_3rdParty = moduleLoader->get3rdPartyLicenseTexts(); std::vector<std::string>::const_iterator ti = licenses_3rdParty.begin(), te = licenses_3rdParty.end(); if (ti != te) std::cout << _TXT("3rd party licenses:") << std::endl; for (; ti != te; ++ti) { std::cout << *ti << std::endl; } std::cout << std::endl; if (!printUsageAndExit) return 0; } if (opt( "version")) { std::cout << _TXT("Strus utilities version ") << STRUS_UTILITIES_VERSION_STRING << std::endl; std::cout << _TXT("Strus module version ") << STRUS_MODULE_VERSION_STRING << std::endl; std::cout << _TXT("Strus rpc version ") << STRUS_RPC_VERSION_STRING << std::endl; std::cout << _TXT("Strus trace version ") << STRUS_TRACE_VERSION_STRING << std::endl; std::cout << _TXT("Strus analyzer version ") << STRUS_ANALYZER_VERSION_STRING << std::endl; std::cout << _TXT("Strus storage version ") << STRUS_STORAGE_VERSION_STRING << std::endl; std::cout << _TXT("Strus base version ") << STRUS_BASE_VERSION_STRING << std::endl; std::vector<std::string> versions_3rdParty = moduleLoader->get3rdPartyVersionTexts(); std::vector<std::string>::const_iterator vi = versions_3rdParty.begin(), ve = versions_3rdParty.end(); if (vi != ve) std::cout << _TXT("3rd party versions:") << std::endl; for (; vi != ve; ++vi) { std::cout << *vi << std::endl; } if (!printUsageAndExit) return 0; } else if (!printUsageAndExit) { if (opt.nofargs() > 3) { std::cerr << _TXT("too many arguments") << std::endl; printUsageAndExit = true; rt = 1; } if (opt.nofargs() < 3) { std::cerr << _TXT("too few arguments") << std::endl; printUsageAndExit = true; rt = 2; } } if (printUsageAndExit) { std::cout << _TXT("usage:") << " strusQuery [options] <anprg> <qeprg> <query>" << std::endl; std::cout << "<anprg> = " << _TXT("path of query analyzer program") << std::endl; std::cout << "<qeprg> = " << _TXT("path of query eval program") << std::endl; std::cout << "<query> = " << _TXT("query string") << std::endl; std::cout << " " << _TXT("file or '-' for stdin if option -F is specified)") << std::endl; std::cout << _TXT("description: Executes a query or a list of queries from a file.") << std::endl; std::cout << _TXT("options:") << std::endl; std::cout << "-h|--help" << std::endl; std::cout << " " << _TXT("Print this usage and do nothing else") << std::endl; std::cout << "-v|--version" << std::endl; std::cout << " " << _TXT("Print the program version and do nothing else") << std::endl; std::cout << "--license" << std::endl; std::cout << " " << _TXT("Print 3rd party licences requiring reference") << std::endl; std::cout << "-s|--storage <CONFIG>" << std::endl; std::cout << " " << _TXT("Define the storage configuration string as <CONFIG>") << std::endl; if (!opt("rpc")) { std::cout << _TXT(" <CONFIG> is a semicolon ';' separated list of assignments:") << std::endl; printStorageConfigOptions( std::cout, moduleLoader.get(), (opt("storage")?opt["storage"]:""), errorBuffer.get()); } std::cout << "-S|--configfile <FILENAME>" << std::endl; std::cout << " " << _TXT("Define the storage configuration file as <FILENAME>") << std::endl; std::cout << " " << _TXT("<FILENAME> is a file containing the configuration string") << std::endl; std::cout << "-u|--user <NAME>" << std::endl; std::cout << " " << _TXT("Use user name <NAME> for the query") << std::endl; std::cout << "-N|--nofranks <N>" << std::endl; std::cout << " " << _TXT("Return maximum <N> ranks as query result") << std::endl; std::cout << "-I|--firstrank <N>" << std::endl; std::cout << " " << _TXT("Return the result starting with rank <N> as first rank") << std::endl; std::cout << "-Q|--quiet" << std::endl; std::cout << " " << _TXT("No output of results") << std::endl; std::cout << "-D|--time" << std::endl; std::cout << " " << _TXT("Do print duration of pure query evaluation") << std::endl; std::cout << "-F|--fileinput" << std::endl; std::cout << " " << _TXT("Interpret query argument as a file name containing the input") << std::endl; std::cout << "-G|--debug <COMP>" << std::endl; std::cout << " " << _TXT("Issue debug messages for component <COMP> to stderr") << std::endl; std::cout << "-m|--module <MOD>" << std::endl; std::cout << " " << _TXT("Load components from module <MOD>") << std::endl; std::cout << "-M|--moduledir <DIR>" << std::endl; std::cout << " " << _TXT("Search modules to load first in <DIR>") << std::endl; std::cout << "-R|--resourcedir <DIR>" << std::endl; std::cout << " " << _TXT("Search resource files for analyzer first in <DIR>") << std::endl; std::cout << "-r|--rpc <ADDR>" << std::endl; std::cout << " " << _TXT("Execute the command on the RPC server specified by <ADDR>") << std::endl; std::cout << "-T|--trace <CONFIG>" << std::endl; std::cout << " " << _TXT("Print method call traces configured with <CONFIG>") << std::endl; std::cout << " " << strus::string_format( _TXT("Example: %s"), "-T \"log=dump;file=stdout\"") << std::endl; std::cout << "-V|--verbose" << std::endl; std::cout << " " << _TXT("Verbose mode: Print some info like query analysis") << std::endl; return rt; } // Parse arguments: bool quiet = opt( "quiet"); bool doMeasureDuration = opt( "time"); bool verbose = opt("verbose"); std::string username; std::size_t nofRanks = 20; std::size_t firstRank = 0; std::string storagecfg; bool queryIsFile = opt("fileinput"); if (opt("user")) { username = opt[ "user"]; } if (opt("nofranks")) { nofRanks = opt.asUint( "nofranks"); } if (opt("firstrank")) { firstRank = opt.asUint( "firstrank"); } if (opt("configfile")) { if (opt("storage")) throw strus::runtime_error(_TXT("conflicting configuration options specified: '%s' and '%s'"), "--storage", "--configfile"); std::string configfile = opt[ "configfile"]; int ec = strus::readFile( configfile, storagecfg); if (ec) throw strus::runtime_error(_TXT("failed to read configuration file %s (errno %u)"), configfile.c_str(), ec); std::string::iterator di = storagecfg.begin(), de = storagecfg.end(); for (; di != de; ++di) { if ((unsigned char)*di < 32) *di = ' '; } } if (opt("storage")) { if (opt("configfile")) throw strus::runtime_error(_TXT("specified mutual exclusive options %s and %s"), "--storage", "--configfile"); storagecfg = opt["storage"]; } // Declare trace proxy objects: typedef strus::Reference<strus::TraceProxy> TraceReference; std::vector<TraceReference> trace; if (opt("trace")) { std::vector<std::string> tracecfglist( opt.list("trace")); std::vector<std::string>::const_iterator ti = tracecfglist.begin(), te = tracecfglist.end(); for (; ti != te; ++ti) { trace.push_back( new strus::TraceProxy( moduleLoader.get(), *ti, errorBuffer.get())); } } // Enable debugging selected with option 'debug': { std::vector<std::string> dbglist = opt.list( "debug"); std::vector<std::string>::const_iterator gi = dbglist.begin(), ge = dbglist.end(); for (; gi != ge; ++gi) { if (!dbgtrace->enable( *gi)) { throw strus::runtime_error(_TXT("failed to enable debug '%s'"), gi->c_str()); } } } // Set paths for locating resources: if (opt("resourcedir")) { std::vector<std::string> pathlist( opt.list("resourcedir")); std::vector<std::string>::const_iterator pi = pathlist.begin(), pe = pathlist.end(); for (; pi != pe; ++pi) { moduleLoader->addResourcePath( *pi); } } std::string analyzerprg = getFileArg( opt[0], moduleLoader.get()); std::string queryprg = getFileArg( opt[1], moduleLoader.get()); std::string querystring = opt[2]; if (errorBuffer->hasError()) { throw std::runtime_error( _TXT("error in initialization")); } // Create objects for query evaluation: strus::local_ptr<strus::RpcClientMessagingInterface> messaging; strus::local_ptr<strus::RpcClientInterface> rpcClient; strus::local_ptr<strus::AnalyzerObjectBuilderInterface> analyzerBuilder; strus::local_ptr<strus::StorageObjectBuilderInterface> storageBuilder; if (opt("rpc")) { messaging.reset( strus::createRpcClientMessaging( opt[ "rpc"], errorBuffer.get())); if (!messaging.get()) throw std::runtime_error( _TXT("failed to create rpc client messaging")); rpcClient.reset( strus::createRpcClient( messaging.get(), errorBuffer.get())); if (!rpcClient.get()) throw std::runtime_error( _TXT("failed to create rpc client")); (void)messaging.release(); analyzerBuilder.reset( rpcClient->createAnalyzerObjectBuilder()); if (!analyzerBuilder.get()) throw std::runtime_error( _TXT("failed to create rpc analyzer object builder")); storageBuilder.reset( rpcClient->createStorageObjectBuilder()); if (!storageBuilder.get()) throw std::runtime_error( _TXT("failed to create rpc storage object builder")); } else { analyzerBuilder.reset( moduleLoader->createAnalyzerObjectBuilder()); if (!analyzerBuilder.get()) throw std::runtime_error( _TXT("failed to create analyzer object builder")); storageBuilder.reset( moduleLoader->createStorageObjectBuilder()); if (!storageBuilder.get()) throw std::runtime_error( _TXT("failed to create storage object builder")); } // Create proxy objects if tracing enabled: std::vector<TraceReference>::const_iterator ti = trace.begin(), te = trace.end(); for (; ti != te; ++ti) { strus::AnalyzerObjectBuilderInterface* aproxy = (*ti)->createProxy( analyzerBuilder.get()); analyzerBuilder.release(); analyzerBuilder.reset( aproxy); strus::StorageObjectBuilderInterface* sproxy = (*ti)->createProxy( storageBuilder.get()); storageBuilder.release(); storageBuilder.reset( sproxy); } // Create objects: strus::local_ptr<strus::StorageClientInterface> storage( strus::createStorageClient( storageBuilder.get(), errorBuffer.get(), storagecfg)); if (!storage.get()) throw strus::runtime_error(_TXT("failed to create storage client: %s"), errorBuffer->fetchError()); strus::local_ptr<strus::QueryAnalyzerInstanceInterface> analyzer( analyzerBuilder->createQueryAnalyzer()); if (!analyzer.get()) throw strus::runtime_error(_TXT("failed to create query analyzer: %s"), errorBuffer->fetchError()); strus::local_ptr<strus::QueryEvalInterface> qeval( storageBuilder->createQueryEval()); if (!qeval.get()) throw strus::runtime_error(_TXT("failed to create query evaluation interface: %s"), errorBuffer->fetchError()); const strus::QueryProcessorInterface* qproc = storageBuilder->getQueryProcessor(); if (!qproc) throw strus::runtime_error(_TXT("failed to get query processor: %s"), errorBuffer->fetchError()); const strus::TextProcessorInterface* textproc = analyzerBuilder->getTextProcessor(); if (!textproc) throw strus::runtime_error(_TXT("failed to get text processor: %s"), errorBuffer->fetchError()); if (errorBuffer->hasError()) throw strus::runtime_error(_TXT("error in initialization: %s"), errorBuffer->fetchError()); // Load query analyzer program: if (!strus::load_QueryAnalyzer_programfile_std( analyzer.get(), textproc, analyzerprg, errorBuffer.get())) { throw strus::runtime_error(_TXT("failed to load query analyzer program: %s"), errorBuffer->fetchError()); } // Load query evaluation program: std::string qevalProgramSource; std::string queryprgpath = strus::isExplicitPath( queryprg) ? queryprg : textproc->getResourceFilePath( queryprg); int ec = strus::readFile( queryprgpath, qevalProgramSource); if (ec) throw strus::runtime_error(_TXT("failed to load query eval program %s (errno %u)"), queryprg.c_str(), ec); if (!strus::load_queryeval_program( *qeval, analyzer->queryTermTypes(), qproc, qevalProgramSource, errorBuffer.get())) { throw strus::runtime_error(_TXT("failed to load query evaluation program: %s"), errorBuffer->fetchError()); } // Load query: if (queryIsFile) { std::string qs; if (querystring == "-") { ec = strus::readStdin( qs); if (ec) throw strus::runtime_error( _TXT("failed to read query from stdin (errno %u)"), ec); } else { ec = strus::readFile( querystring, qs); if (ec) throw strus::runtime_error(_TXT("failed to read query from file %s (errno %u)"), querystring.c_str(), ec); } querystring = qs; } unsigned int nofQueries = 0; double startTime = 0.0; if (doMeasureDuration) { startTime = getTimeStamp(); } std::string::const_iterator si = querystring.begin(), se = querystring.end(); std::string qs; while (strus::scanNextProgram( qs, si, se, errorBuffer.get())) { ++nofQueries; strus::local_ptr<strus::QueryInterface> query( qeval->createQuery( storage.get())); if (!query.get()) throw strus::runtime_error(_TXT("failed to create query object: %s"), errorBuffer->fetchError()); std::string selectionFeatureSet; std::string weightingFeatureSet; std::vector<std::string> selfset = qeval->getSelectionFeatureSets(); if (!selfset.empty()) selectionFeatureSet = selfset[0]; std::vector<std::string> weightset = qeval->getWeightingFeatureSets(); if (!weightset.empty()) weightingFeatureSet = weightset[0]; if (!strus::loadQuery( *query, analyzer.get(), selectionFeatureSet, weightingFeatureSet, qproc, qs, errorBuffer.get())) { throw strus::runtime_error(_TXT("failed to load query from source: %s"), errorBuffer->fetchError()); } if (withDebugInfo) { query->setDebugMode( true); } query->setMaxNofRanks( nofRanks); query->setMinRank( firstRank); if (!username.empty()) { query->addAccess( username); } if (verbose) { std::cerr << "Query:" << std::endl; std::cerr << query->tostring() << std::endl; } strus::QueryResult result = query->evaluate(); if (!quiet) { std::cout << strus::string_format( _TXT("evaluated till pass %u, got %u ranks (%u without restrictions applied):"), result.evaluationPass(), result.nofRanked(), result.nofVisited()) << std::endl; std::cout << strus::string_format( _TXT("ranked list (starting with rank %u, maximum %u results):"), (unsigned int)firstRank, (unsigned int)nofRanks) << std::endl; } std::vector<strus::ResultDocument>::const_iterator wi = result.ranks().begin(), we = result.ranks().end(); if (!quiet) { for (int widx=1; wi != we; ++wi,++widx) { std::cout << strus::string_format( _TXT( "[%u] score %f"), widx, wi->weight()) << std::endl; std::vector<strus::SummaryElement>::const_iterator ai = wi->summaryElements().begin(), ae = wi->summaryElements().end(); for (; ai != ae; ++ai) { std::cout << "\t" << ai->name(); if (ai->index() >= 0) { std::cout << "[" << ai->index() << "]"; } std::cout << " = '" << ai->value() << "'"; std::cout << " " << ai->weight() << std::endl; } } } } if (doMeasureDuration) { double endTime = getTimeStamp(); double duration = endTime - startTime; std::cerr << strus::string_format( _TXT("evaluated %u queries in %.4f seconds"), nofQueries, duration) << std::endl; } if (errorBuffer->hasError()) { throw strus::runtime_error(_TXT("unhandled error in command line query: %s"), errorBuffer->fetchError()); } std::cerr << _TXT("done.") << std::endl; if (!dumpDebugTrace( dbgtrace, NULL/*filename ~ NULL = stderr*/)) { std::cerr << _TXT("failed to dump debug trace to file") << std::endl; } return 0; } catch (const std::bad_alloc&) { std::cerr << _TXT("ERROR ") << _TXT("out of memory") << std::endl; return -2; } catch (const std::runtime_error& e) { const char* errormsg = errorBuffer->fetchError(); if (errormsg) { std::cerr << _TXT("ERROR ") << e.what() << ": " << errormsg << std::endl; } else { std::cerr << _TXT("ERROR ") << e.what() << std::endl; } } catch (const std::exception& e) { std::cerr << _TXT("EXCEPTION ") << e.what() << std::endl; } if (!dumpDebugTrace( dbgtrace, NULL/*filename ~ NULL = stderr*/)) { std::cerr << _TXT("failed to dump debug trace to file") << std::endl; } return -1; }
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; }