Beispiel #1
0
/*
 * tagsearch: execute tag search
 *
 *	i)	pattern		search pattern
 *	i)	cwd		current directory
 *	i)	root		root of source tree
 *	i)	dbpath		database directory
 *	i)	db		GTAGS,GRTAGS,GSYMS
 */
void
tagsearch(const char *pattern, const char *cwd, const char *root, const char *dbpath, int db)
{
	int count, total = 0;
	char libdbpath[MAXPATHLEN];

	/*
	 * search in current source tree.
	 */
	count = search(pattern, root, cwd, dbpath, db);
	total += count;
	/*
	 * search in library path.
	 */
	if (db == GTAGS && getenv("GTAGSLIBPATH") && (count == 0 || Tflag) && !lflag) {
		STRBUF *sb = strbuf_open(0);
		char *libdir, *nextp = NULL;

		strbuf_puts(sb, getenv("GTAGSLIBPATH"));
		/*
		 * search for each tree in the library path.
		 */
		for (libdir = strbuf_value(sb); libdir; libdir = nextp) {
			if ((nextp = locatestring(libdir, PATHSEP, MATCH_FIRST)) != NULL)
				*nextp++ = 0;
			if (!gtagsexist(libdir, libdbpath, sizeof(libdbpath), 0))
				continue;
			if (!strcmp(dbpath, libdbpath))
				continue;
			if (!test("f", makepath(libdbpath, dbname(db), NULL)))
				continue;
			/*
			 * search again
			 */
			count = search(pattern, libdir, cwd, libdbpath, db);
			total += count;
			if (count > 0 && !Tflag) {
				/* for verbose message */
				dbpath = libdbpath;
				break;
			}
		}
		strbuf_close(sb);
	}
	if (vflag) {
		print_count(total);
		if (!Tflag)
			fprintf(stderr, " (using '%s')", makepath(dbpath, dbname(db), NULL));
		fputs(".\n", stderr);
	}
}
Beispiel #2
0
int Mysql_Operator::init(void) {
	const Json::Value &server_misc = SERVER_CONFIG->server_misc();
	if (server_misc == Json::Value::null) {
		LOG_FATAL("db init, server_misc null");
		return -1;
	}

	//初始化代理编号,服编号
	agent_num_ = server_misc["agent_num"].asInt();
	server_num_ = server_misc["server_num"].asInt();
	if (agent_num_ < 1) agent_num_ = 1;
	if (server_num_ < 1) server_num_ = 1;

	//连接mysql
	std::string ip(server_misc["mysql_game"]["ip"].asString());
	int port = server_misc["mysql_game"]["port"].asInt();
	std::string user(server_misc["mysql_game"]["user"].asString());
	std::string password(server_misc["mysql_game"]["password"].asString());
	std::string dbname(server_misc["mysql_game"]["dbname"].asString());
	std::string dbpoolname(server_misc["mysql_game"]["dbpoolname"].asString());
	MYSQL_MANAGER->init(ip, port, user, password, dbname, dbpoolname, 16);
	mysql_conn_ = MYSQL_MANAGER->get_mysql_conn(dbpoolname);

	sql::ResultSet *result = mysql_conn_->execute_query("select * from global where type='role_id'");
	if (result && result->rowsCount() <= 0) {
		mysql_conn_->execute("insert into global(type, value) values ('role_id', 0)");
	}
	result = mysql_conn_->execute_query("select * from global where type='guild_id'");
	if (result && result->rowsCount() <= 0) {
		mysql_conn_->execute("insert into global(type, value) values ('guild_id', 0)");
	}

	load_db_cache();
	return 0;
}
Beispiel #3
0
int U_EXPORT main(int argc, char* argv[])
{
   U_ULIB_INIT(argv);

   U_TRACE(5,"main(%d)",argc)

   UCDB y(false);
   UFileConfig fcg;
   off_t sz = 30000L;
   UString cfg(argv[1], strlen(argv[1])), dbname(argv[2]);

   if (fcg.open(cfg) == false) U_ERROR("file configurazione  <%s> not valid...", fcg.getPath().data());

   URDBServer s(&fcg, false);

   if (y.UFile::creat(dbname))
      {
      y.UFile::ftruncate(sz);
      y.UFile::memmap(PROT_READ | PROT_WRITE);

      cin >> y; // do ftruncate() and munmap()...

      y.UFile::close();
      y.UFile::reset();

      if (s.open(dbname)) s.go();
      }
void ReportWriterWindow::setCaption() {
    QString caption = QString("%1 %2 %3")
                          .arg(_name)
                          .arg(tr("Version"))
                          .arg(_version);

    QSqlDatabase * db = QSqlDatabase::database(QSqlDatabase::defaultConnection, false);
    if(db) {
        XSqlQuery dbname( "SELECT metric_value, CURRENT_USER AS username "
                          "FROM metric "
                          "WHERE (metric_name='DatabaseName')" );

        if ((dbname.isActive()) && (dbname.size())) {
            QString protocol;
            QString server;
            QString database;
            QString port;

            dbname.next();

            parseDatabaseURL((const QString &)_databaseURL, protocol, server, database, port);

            caption = QString( tr("%1 - %2 on %3/%4 AS %5") )
                            .arg(caption)
                            .arg(dbname.value("metric_value").toString())
                            .arg(server)
                            .arg(database)
                            .arg(dbname.value("username").toString());
        }
    }

    QMainWindow::setCaption(caption);
}
QSqlError LogisticApplication::slotAddConnection(const QString &user, const QString &passwd)
{   
    QString templateString = QString("DRIVER={SQL Server};Server=%1;Database=%2;Uid=%3;Pwd=%4;");
    QString connectionString = QString(templateString).arg(host()).arg(dbname()).arg(user).arg(passwd);

    database = QSqlDatabase::addDatabase(driver(), "Logistic");
    database.setDatabaseName(connectionString);

#ifndef QT_NO_CURSOR
    QApplication::setOverrideCursor(QCursor(QPixmap("data/picture/additionally/wait.png")));
#endif
    if (!database.open()) {
#ifndef QT_NO_CURSOR
    QApplication::restoreOverrideCursor();
#endif
        QMessageBox::critical(0, "Ошибка", "Ошибка подключения к базе данных");
        return database.lastError();
    } else {
        emit successConnection();
    }
#ifndef QT_NO_CURSOR
    QApplication::restoreOverrideCursor();
#endif
    return database.lastError();
}
template<> StrVec
GncDbiProviderImpl<DbType::DBI_MYSQL>::get_table_list (dbi_conn conn,
                                                       const std::string& table)
{
    std::string dbname (dbi_conn_get_option (conn, "dbname"));
    dbname.insert((std::string::size_type)0, 1, '`');
    dbname += '`';
    return conn_get_table_list (conn, dbname, table);
}
template<> StrVec
GncDbiProviderImpl<DbType::DBI_SQLITE>::get_table_list (dbi_conn conn,
                                                        const std::string& table)
{
    /* Return the list, but remove the tables that sqlite3 adds for
     * its own use. */
    std::string dbname (dbi_conn_get_option (conn, "dbname"));
    auto list = conn_get_table_list (conn, dbname, table);
    auto end = std::remove(list.begin(), list.end(), "sqlite_sequence");
    list.erase(end, list.end());
    return list;
}
Beispiel #8
0
        void buildCollection() {
            BSONObj info;
            // Create a collection with specified extent sizes
            BSONObj command = BSON( "create" << collname() << "capped" << true <<
                                    "$nExtents" << extentSizes() << "autoIndexId" << false );
            ASSERT(client()->runCommand(dbname(), command, info));

            // Populate documents.
            for(int i = 0; i < numDocs(); ++i) {
                client()->insert(ns(), BSON( "_id" << i << "ts" << i << "payload" << payload8k() ));
            }
        }
Beispiel #9
0
/* test how the database server handles multiple queries
   embedded in a single query string.
 */
int main(int argc, char *argv[]) {
  QCoreApplication app(argc, argv);
  QSqlDatabase     db = QSqlDatabase::addDatabase("QPSQL");
  QTextStream      input(stdin),
                   output(stdout);

  QString hostname("localhost"),
          username("admin"),
          password("admin"),
          dbname("template1");
  int     port = 5962;

  for (int i = 1; i < argc; i++) {
    QString option(argv[i]);
    if (option == "-h")
      hostname = argv[++i];
    else if (option == "-U")
      username = argv[++i];
    else if (option == "-w")
      password = argv[++i];
    else if (option == "-d")
      dbname = argv[++i];
    else if (option == "-p")
      port = QString(argv[++i]).toInt();
    else {
      usage(argv[0]);
      exit(1);
    }
  }

  db.setHostName(hostname);
  db.setPort(port);
  db.setUserName(username);
  db.setPassword(password);
  db.setDatabaseName(dbname);

  if (db.open()) {
    QStringList querystrings;
    querystrings << "SELECT false AS result FROM information_schema.columns LIMIT 1;"
                    "SELECT true  AS result FROM information_schema.columns LIMIT 1;"
                 << "DO $$ DECLARE test BOOLEAN ; BEGIN test := false; END; $$;"
                    "SELECT true AS result FROM information_schema.columns LIMIT 1;"
                 ;

    foreach(QString str, querystrings) {
      QSqlQuery q(str);
      if (q.first())
        qDebug() << (q.value("result").toBool() ? "PASSED" : "FAILED") << str;
      else if (q.lastError().type() != QSqlError::NoError)
        qDebug() << "FAILED" << q.lastError().text();
    }
bool PDOPgSqlConnection::create(const Array &options){
  long connect_timeout = pdo_attr_lval(options, PDO_ATTR_TIMEOUT, 30);
  struct pdo_data_src_parser vars[] = {
    { "host", "localhost", 0 },
    { "port", "5432", 0 },
    { "dbname", "", 0 },
    { "user", nullptr, 0 },
    { "password", nullptr, 0 }
  };
  parseDataSource(data_source.data(), data_source.size(), vars, 5, "; ");

  std::stringstream conninfo;
  conninfo << "host='";
  std::string host(vars[0].optval);
  ReplaceStringInPlace(host, "\\", "\\\\");
  ReplaceStringInPlace(host, "'", "\\'");
  conninfo << host << "' port='";
  std::string port(vars[1].optval);
  ReplaceStringInPlace(port, "\\", "\\\\");
  ReplaceStringInPlace(port, "'", "\\'");
  conninfo << port << "' dbname='";
  std::string dbname(vars[2].optval);
  ReplaceStringInPlace(dbname, "\\", "\\\\");
  ReplaceStringInPlace(dbname, "'", "\\'");
  conninfo << dbname << "' password='******'", "\\'");
  conninfo << password << "' user='******'", "\\'");
  conninfo << username << "'";
  conninfo << " connect_timeout=" << connect_timeout;

  m_server = new PQ::Connection(conninfo.str());

  if(m_server->status() == CONNECTION_OK){
    return true;
  } else {
    handleError(
      nullptr,
      PHP_PDO_PGSQL_CONNECTION_FAILURE_SQLSTATE,
      m_server->errorMessage()
    );
    return false;
  }
}
template<> StrVec
GncDbiProviderImpl<DbType::DBI_PGSQL>::get_table_list (dbi_conn conn,
                                                       const std::string& table)
{
    std::string dbname (dbi_conn_get_option (conn, "dbname"));
    auto list = conn_get_table_list (conn, dbname, table);
    auto end = std::remove_if (list.begin(), list.end(),
                               [](std::string& table_name){
                                   return table_name == "sql_features" ||
                                   table_name == "sql_implementation_info" ||
                                   table_name == "sql_languages" ||
                                   table_name == "sql_packages" ||
                                   table_name == "sql_parts" ||
                                   table_name == "sql_sizing" ||
                                   table_name == "sql_sizing_profiles";
                               });
    list.erase(end, list.end());
    return list;
}
Beispiel #12
0
/**
 * gfind_open: start iterator using GPATH.
 *
 *	@param[in]	dbpath  dbpath
 *	@param[in]	local   local prefix,
 *			if NULL specified, it assumes "./";
 *	@param[in]      target  GPATH_SOURCE: only source file,
 *			GPATH_OTHER: only other file,
 *			GPATH_BOTH: source file + other file
 *	@param[in]	flags	GPATH_NEARSORT
 *	@return		GFIND structure
 */
GFIND *
gfind_open(const char *dbpath, const char *local, int target, int flags)
{
	GFIND *gfind = (GFIND *)check_calloc(sizeof(GFIND), 1);

	gfind->dbop = dbop_open(makepath(dbpath, dbname(GPATH), NULL), 0, 0, 0);
	if (gfind->dbop == NULL)
		die("GPATH not found.");
	gfind->path = NULL;
	gfind->prefix = check_strdup(local ? local : "./");
	gfind->first = 1;
	gfind->eod = 0;
	gfind->target = target;
	gfind->type = GPATH_SOURCE;
	gfind->flags = flags;
	gfind->path_array = NULL;
	gfind->version = dbop_getversion(gfind->dbop);
	if (gfind->version > support_version)
		die("GPATH seems new format. Please install the latest GLOBAL.");
	else if (gfind->version < support_version)
		die("GPATH seems older format. Please remake tag files."); 
	/*
	 * Nearness sort.
	 * In fact, this timing of sort is not good for performance.
	 * Reconsideration is needed later.
	 */
	if (gfind->flags & GPATH_NEARSORT) {
		const char *path = NULL;
		VARRAY *varray = varray_open(sizeof(char *), 100);
		POOL *pool = pool_open();
		while ((path = gfind_read(gfind)) != NULL) {
			char **a = varray_append(varray);
			*a = pool_strdup(pool, path, 0);
		}
		if ((nearbase = get_nearbase_path()) == NULL)
			die("cannot get nearbase path.");
		qsort(varray_assign(varray, 0, 0), varray->length, sizeof(char *), compare_nearpath);
		gfind->path_array = varray;
		gfind->pool = pool;
		gfind->index = 0;
	}
	return gfind;
}
t_rc SSQLM_DDL_Manager::DropTable(char * t_Name) {

	t_rc rc;

	std::string a_path = this->path + "attr.met";
	REM_RecordFileHandle rfh;
	rc = this->rfm->OpenRecordFile(a_path.c_str(), rfh);
	if (rc != OK) return rc;
	
	REM_RecordFileScan rfs;
	rc = rfs.OpenRecordScan(rfh,TYPE_STRING,REL_NAME_SIZE,ATTR_REL_NAME_OFFSET,EQ_OP,t_Name);
	if (rc != OK) return rc;

	REM_RecordHandle rh;
	while ((rc = rfs.GetNextRecord(rh)) == OK) {
		char * pData;
		rc = rh.GetData(pData);
		if (rc != OK) return rc;

		int indexNo;
		memcpy(&indexNo,&pData[ATTR_INX_NO_OFFSET],sizeof(int));

		if (indexNo >= 0) {
			char * attrName = new char[ATTR_NAME_SIZE];
			memcpy(attrName,&pData[ATTR_NAME_OFFSET],ATTR_NAME_SIZE);

			rc = this->DropIndex(t_Name, attrName);
			if (rc != OK) return rc;
		}
	}

	rc = smm->DeleteRelationMetadata(t_Name);
	if (rc != OK) return rc;

	std::string dbname(this->openedDatabaseName);
	std::string path("C:\\sirenbase\\data\\" + dbname + "\\" + t_Name);
	rc = this->rfm->DestroyRecordFile(path.c_str());
	if (rc != OK) return rc;

	
	return (OK);
}
Beispiel #14
0
/**
 * completion: print completion list of specified @a prefix
 *
 *	@param[in]	dbpath	dbpath directory
 *	@param[in]	root	root directory
 *	@param[in]	prefix	prefix of primary key
 *	@param[in]	db	#GTAGS,#GRTAGS,#GSYMS
 */
void
completion(const char *dbpath, const char *root, const char *prefix, int db)
{
	int count, total = 0;
	char libdbpath[MAXPATHLEN];

	if (prefix && *prefix == 0)	/* In the case global -c '' */
		prefix = NULL;
	count = completion_tags(dbpath, root, prefix, db);
	/*
	 * search in library path.
	 */
	if (db == GTAGS && getenv("GTAGSLIBPATH") && (count == 0 || Tflag) && !Sflag) {
		STRBUF *sb = strbuf_open(0);
		char *libdir, *nextp = NULL;

		strbuf_puts(sb, getenv("GTAGSLIBPATH"));
		/*
		* search for each tree in the library path.
		*/
		for (libdir = strbuf_value(sb); libdir; libdir = nextp) {
			if ((nextp = locatestring(libdir, PATHSEP, MATCH_FIRST)) != NULL)
				*nextp++ = 0;
			if (!gtagsexist(libdir, libdbpath, sizeof(libdbpath), 0))
				continue;
			if (!strcmp(dbpath, libdbpath))
				continue;
			if (!test("f", makepath(libdbpath, dbname(db), NULL)))
				continue;
			/*
			 * search again
			 */
			count = completion_tags(libdbpath, libdir, prefix, db);
			total += count;
			if (count > 0 && !Tflag)
				break;
		}
		strbuf_close(sb);
	}
	/* return total; */
}
Beispiel #15
0
/*
 * gfind_open: start iterator using GPATH.
 *
 *	i)	dbpath	dbpath
 *	i)	local	local prefix
 *			if NULL specified, it assumes "./";
 *	i)	target	GPATH_SOURCE: only source file
 *			GPATH_OTHER: only other file
 *			GPATH_BOTH: source file + other file
 *	r)		GFIND structure
 */
GFIND *
gfind_open(const char *dbpath, const char *local, int target)
{
	GFIND *gfind = (GFIND *)check_calloc(sizeof(GFIND), 1);

	gfind->dbop = dbop_open(makepath(dbpath, dbname(GPATH), NULL), 0, 0, 0);
	if (gfind->dbop == NULL)
		die("GPATH not found.");
	gfind->path = NULL;
	gfind->prefix = check_strdup(local ? local : "./");
	gfind->first = 1;
	gfind->eod = 0;
	gfind->target = target;
	gfind->type = GPATH_SOURCE;
	gfind->version = dbop_getversion(gfind->dbop);
	if (gfind->version > support_version)
		die("GPATH seems new format. Please install the latest GLOBAL.");
	else if (gfind->version < support_version)
		die("GPATH seems older format. Please remake tag files."); 
	return gfind;
}
Beispiel #16
0
/*
 * gpath_open: open gpath tag file
 *
 *	i)	dbpath	GTAGSDBPATH
 *	i)	mode	0: read only
 *			1: create
 *			2: modify
 *	r)		0: normal
 *			-1: error
 */
int
gpath_open(const char *dbpath, int mode)
{
	if (opened > 0) {
		if (mode != _mode)
			die("duplicate open with different mode.");
		opened++;
		return 0;
	}
	/*
	 * We create GPATH just first time.
	 */
	_mode = mode;
	if (mode == 1 && created)
		mode = 0;
	dbop = dbop_open(makepath(dbpath, dbname(GPATH), NULL), mode, 0644, 0);
	if (dbop == NULL)
		return -1;
	if (mode == 1) {
		dbop_putversion(dbop, create_version);
		_nextkey = 1;
		
	} else {
		int format_version;
		const char *path = dbop_get(dbop, NEXTKEY);

		if (path == NULL)
			die("nextkey not found in GPATH.");
		_nextkey = atoi(path);
		format_version = dbop_getversion(dbop);
		if (format_version > support_version)
			die("GPATH seems new format. Please install the latest GLOBAL.");
		else if (format_version < support_version)
                        die("GPATH seems older format. Please remake tag files."); 
	}
	opened++;
	return 0;
}
Beispiel #17
0
/*
 * createtags: create tags file
 *
 *	i)	dbpath	dbpath directory
 *	i)	root	root directory of source tree
 */
void
createtags(const char *dbpath, const char *root)
{
	STATISTICS_TIME *tim;
	STRBUF *sb = strbuf_open(0);
	struct put_func_data data;
	int openflags, flags, seqno;
	const char *path;

	tim = statistics_time_start("Time of creating %s and %s.", dbname(GTAGS), dbname(GRTAGS));
	if (vflag)
		fprintf(stderr, "[%s] Creating '%s' and '%s'.\n", now(), dbname(GTAGS), dbname(GRTAGS));
	openflags = cflag ? GTAGS_COMPACT : 0;
	data.gtop[GTAGS] = gtags_open(dbpath, root, GTAGS, GTAGS_CREATE, openflags);
	data.gtop[GTAGS]->flags = 0;
	if (extractmethod)
		data.gtop[GTAGS]->flags |= GTAGS_EXTRACTMETHOD;
	data.gtop[GRTAGS] = gtags_open(dbpath, root, GRTAGS, GTAGS_CREATE, openflags);
	data.gtop[GRTAGS]->flags = data.gtop[GTAGS]->flags;
	flags = 0;
	if (debug)
		flags |= PARSER_DEBUG;
	if (wflag)
		flags |= PARSER_WARNING;
	/*
	 * Add tags to GTAGS and GRTAGS.
	 */
	if (file_list)
		find_open_filelist(file_list, root);
	else
		find_open(NULL);
	seqno = 0;
	while ((path = find_read()) != NULL) {
		if (*path == ' ') {
			path++;
			if (!test("b", path))
				gpath_put(path, GPATH_OTHER);
			continue;
		}
		gpath_put(path, GPATH_SOURCE);
		data.fid = gpath_path2fid(path, NULL);
		if (data.fid == NULL)
			die("GPATH is corrupted.('%s' not found)", path);
		seqno++;
		if (vflag)
			fprintf(stderr, " [%d] extracting tags of %s\n", seqno, path + 2);
		if (debug)
			fprintf(stderr, "[%s]\n", path + 2);
		parse_file(path, flags, put_syms, &data);
		gtags_flush(data.gtop[GTAGS], data.fid);
		gtags_flush(data.gtop[GRTAGS], data.fid);
	}
	total = seqno;
	parser_exit();
	find_close();
	statistics_time_end(tim);
	tim = statistics_time_start("Time of flushing B-tree cache");
	gtags_close(data.gtop[GTAGS]);
	gtags_close(data.gtop[GRTAGS]);
	statistics_time_end(tim);
	strbuf_reset(sb);
	if (getconfs("GTAGS_extra", sb)) {
		tim = statistics_time_start("Time of executing GTAGS_extra command");
		if (system(strbuf_value(sb)))
			fprintf(stderr, "GTAGS_extra command failed: %s\n", strbuf_value(sb));
		statistics_time_end(tim);
	}
	strbuf_reset(sb);
	if (getconfs("GRTAGS_extra", sb)) {
		tim = statistics_time_start("Time of executing GRTAGS_extra command");
		if (system(strbuf_value(sb)))
			fprintf(stderr, "GRTAGS_extra command failed: %s\n", strbuf_value(sb));
		statistics_time_end(tim);
	}
	strbuf_close(sb);
}
Beispiel #18
0
void
gtags_show_statistics(GTOP *gtop)
{
	fprintf(stderr, "Numbers of gtags (%s): %d\n", dbname(gtop->db), gtop->readcount);
	fprintf(stderr, "Numbers of dbop  (%s): %d\n", dbname(gtop->db), gtop->dbop->readcount);
}
Beispiel #19
0
int
main(int argc, char **argv)
{
	const char *av = NULL;
	int func_total, file_total;
        char arg_dbpath[MAXPATHLEN];
	const char *index = NULL;
	int optchar;
        int option_index = 0;
	STATISTICS_TIME *tim;

	arg_dbpath[0] = 0;
	basic_check();
	/*
	 * Setup GTAGSCONF and GTAGSLABEL environment variable
	 * according to the --gtagsconf and --gtagslabel option.
	 */
	preparse_options(argc, argv);
	/*
	 * Load configuration values.
	 */
	if (!vgetcwd(cwdpath, sizeof(cwdpath)))
		die("cannot get current directory.");
	openconf(cwdpath);
	configuration();
	/*
	 * setup_langmap() is needed to use decide_lang().
	 */
	setup_langmap(langmap);
	save_environment(argc, argv);
	/*
	 * insert htags_options at the head of argv.
	 */
	setenv_from_config();
	{
		char *env = getenv("HTAGS_OPTIONS");
		if (env && *env)
			argv = prepend_options(&argc, argv, env);
	}
	while ((optchar = getopt_long(argc, argv, "acd:DfFghIm:nNoqst:Tvwx", long_options, &option_index)) != EOF) {
		switch (optchar) {
		case 0:
			/* already flags set */
			break;
		case OPT_AUTO_COMPLETION:
			auto_completion = 1;
			if (optarg) {
				if (atoi(optarg) > 0)
					auto_completion_limit = optarg;
				else
					die("The option value of --auto-completion must be numeric.");
			}
			break;
		case OPT_CFLOW:
			call_file = optarg;
			break;
		case OPT_CALL_TREE:
			call_file = optarg;
			break;
		case OPT_CALLEE_TREE:
			callee_file = optarg;
			break;
		case OPT_CVSWEB:
			cvsweb_url = optarg;
			break;
		case OPT_CVSWEB_CVSROOT:
			cvsweb_cvsroot = optarg;
			break;
		case OPT_GTAGSCONF:
		case OPT_GTAGSLABEL:
			/* These options are already parsed in preparse_options() */
			break;
		case OPT_INSERT_FOOTER:
			insert_footer = optarg;
			break;
		case OPT_INSERT_HEADER:
			insert_header = optarg;
			break;
		case OPT_HTML_HEADER:
			{
				STATIC_STRBUF(sb);
				if (!test("r", optarg))
					die("file '%s' not found.", optarg);
				strbuf_clear(sb);
				loadfile(optarg, sb);
				html_header = strbuf_value(sb);
			}
			break;
		case OPT_ITEM_ORDER:
			item_order = optarg;
			break;
		case OPT_TABS:
			if (atoi(optarg) > 0)
				tabs = atoi(optarg);
			else
				die("--tabs option requires numeric value.");
                        break;
		case OPT_NCOL:
			if (atoi(optarg) > 0)
				ncol = atoi(optarg);
			else
				die("--ncol option requires numeric value.");
                        break;
		case OPT_TREE_VIEW:
			tree_view = 1;
			if (optarg)
				tree_view_type = optarg;
			break;
                case 'a':
                        aflag++;
                        break;
                case 'd':
			strlimcpy(arg_dbpath, optarg, sizeof(arg_dbpath));
                        break;
                case 'D':
			dynamic = 1;
                        break;
                case 'f':
                        fflag++;
                        break;
                case 'F':
                        Fflag++;
                        break;
                case 'g':
                        gflag++;
                        break;
                case 'h':
			definition_header = AFTER_HEADER;
			if (optarg) {
				if (!strcmp(optarg, "before"))
					definition_header = BEFORE_HEADER;
				else if (!strcmp(optarg, "right"))
					definition_header = RIGHT_HEADER;
				else if (!strcmp(optarg, "after"))
					definition_header = AFTER_HEADER;
				else
					die("The option value of --func-header must be one of 'before', 'right' and 'after'.");
			}
                        break;
                case 'I':
                        Iflag++;
                        break;
                case 'm':
			main_func = optarg;
                        break;
                case 'n':
                        nflag++;
			if (optarg) {
				if (atoi(optarg) > 0)
					ncol = atoi(optarg);
				else
					die("The option value of --line-number must be numeric.");
			}
                        break;
                case 'o':
			other_files = 1;
                        break;
                case 's':
			symbol = 1;
                        break;
                case 'T':
			table_flist = 1;
			if (optarg) {
				if (atoi(optarg) > 0)
					flist_fields = atoi(optarg);
				else
					die("The option value of the --table-flist must be numeric.");
			}
                        break;
                case 't':
			title = optarg;
                        break;
                case 'q':
                        qflag++;
			setquiet();
                        break;
                case 'v':
                        vflag++;
			setverbose();
                        break;
                case 'w':
                        wflag++;
                        break;
                default:
                        usage();
                        break;
		}
	}
	/*
	 * Leaving everything to htags.
	 * Htags selects popular options for you.
	 */
	if (suggest2)
		suggest = 1;
	if (suggest) {
		int gtags_not_found = 0;
		char dbpath[MAXPATHLEN];

		aflag = Iflag = nflag = vflag = 1;
		setverbose();
		definition_header = AFTER_HEADER;
		other_files = symbol = show_position = table_flist = fixed_guide = 1;
		if (arg_dbpath[0]) {
			if (!test("f", makepath(arg_dbpath, dbname(GTAGS), NULL)))
				gtags_not_found = 1;
		} else if (gtagsexist(".", dbpath, sizeof(dbpath), 0) == 0) {
			gtags_not_found = 1;
		}
		if (gtags_not_found)
			gflag = 1;
	}
	if (suggest2) {
		Fflag = 1;				/* uses frame */
		fflag = dynamic = 1;			/* needs a HTTP server */
		auto_completion = tree_view = 1;	/* needs javascript */
	}
	if (call_file && !test("fr", call_file))
		die("cflow file not found. '%s'", call_file);
	if (callee_file && !test("fr", callee_file))
		die("cflow file not found. '%s'", callee_file);
	if (insert_header && !test("fr", insert_header))
		die("page header file '%s' not found.", insert_header);
	if (insert_footer && !test("fr", insert_footer))
		die("page footer file '%s' not found.", insert_footer);
	if (!fflag)
		auto_completion = 0;
        argc -= optind;
        argv += optind;
        if (!av)
                av = (argc > 0) ? *argv : NULL;

	if (debug)
		setdebug();
	settabs(tabs);					/* setup tab skip */
        if (qflag) {
                setquiet();
		vflag = 0;
	}
        if (show_version)
                version(av, vflag);
        if (show_help)
                help();
	/*
	 * Invokes gtags beforehand.
	 */
	if (gflag) {
		STRBUF *sb = strbuf_open(0);

		strbuf_puts(sb, gtags_path);
		if (vflag)
			strbuf_puts(sb, " -v");
		if (wflag)
			strbuf_puts(sb, " -w");
		if (suggest2 && enable_idutils && usable("mkid"))
			strbuf_puts(sb, " -I");
		if (arg_dbpath[0]) {
			strbuf_putc(sb, ' ');
			strbuf_puts(sb, arg_dbpath);
		}
		if (system(strbuf_value(sb)))
			die("cannot execute gtags(1) command.");
		strbuf_close(sb);
	}
	/*
	 * get dbpath.
	 */
	if (arg_dbpath[0]) {
		strlimcpy(dbpath, arg_dbpath, sizeof(dbpath));
	} else {
		int status = setupdbpath(0);
		if (status < 0)
			die_with_code(-status, "%s", gtags_dbpath_error);
		strlimcpy(dbpath, get_dbpath(), sizeof(dbpath));
	}
	if (!title) {
		char *p = strrchr(cwdpath, sep);
		title = p ? p + 1 : cwdpath;
	}
	if (cvsweb_url && test("d", "CVS"))
		use_cvs_module = 1;
	/*
	 * decide directory in which we make hypertext.
	 */
	if (av) {
		char realpath[MAXPATHLEN];

		if (!test("dw", av))
			die("'%s' is not writable directory.", av);
		if (chdir(av) < 0)
			die("directory '%s' not found.", av);
		if (!vgetcwd(realpath, sizeof(realpath)))
			die("cannot get current directory");
		if (chdir(cwdpath) < 0)
			die("cannot return to original directory.");
		snprintf(distpath, sizeof(distpath), "%s/HTML", realpath);
	} else {
		snprintf(distpath, sizeof(distpath), "%s/HTML", cwdpath);
	}
	/*
	 * Existence check of tag files.
	 */
	{
		int i;
		const char *path;
		GTOP *gtop;

		for (i = GPATH; i < GTAGLIM; i++) {
			path = makepath(dbpath, dbname(i), NULL);
			gtags_exist[i] = test("fr", path);
		}
		/*
		 * Real GRTAGS includes virtual GSYMS.
		 */
		gtags_exist[GSYMS] = symbol ? 1 : 0;
		if (!gtags_exist[GPATH] || !gtags_exist[GTAGS] || !gtags_exist[GRTAGS])
			die("GPATH, GTAGS and/or GRTAGS not found. Please reexecute htags with the -g option.");
		/*
		 * version check.
		 * Do nothing, but the version of tag file will be checked.
		 */
		gtop = gtags_open(dbpath, cwdpath, GTAGS, GTAGS_READ, 0);
		gtags_close(gtop);
		/*
		 * Check whether GRTAGS is empty.
		 */
		gtop = gtags_open(dbpath, cwdpath, GRTAGS, GTAGS_READ, 0);
		if (gtags_first(gtop, NULL, 0) == NULL)
			grtags_is_empty = 1;
		gtags_close(gtop);
	}
	/*
	 * make dbpath absolute.
	 */
	{
		char buf[MAXPATHLEN];
		if (realpath(dbpath, buf) == NULL)
			die("cannot get realpath of dbpath.");
		strlimcpy(dbpath, buf, sizeof(dbpath));
	}
	/*
	 * The older version (4.8.7 or former) of GPATH doesn't have files
         * other than source file. The oflag requires new version of GPATH.
	 */
	if (other_files) {
		GFIND *gp = gfind_open(dbpath, NULL, 0, 0);
		if (gp->version < 2)
			die("GPATH is old format. Please remake it by invoking gtags(1).");
		gfind_close(gp);
	}
	/*
	 * for global(1) and gtags(1).
	 */
	set_env("GTAGSROOT", cwdpath);
	set_env("GTAGSDBPATH", dbpath);
	set_env("GTAGSLIBPATH", "");
	/*------------------------------------------------------------------
	 * MAKE FILES
	 *------------------------------------------------------------------
	 *       HTML/cgi-bin/global.cgi ... CGI program (1)
	 *       HTML/cgi-bin/ghtml.cgi  ... unzip script (1)
	 *       HTML/.htaccess          ... skeleton of .htaccess (1)
	 *       HTML/help.html          ... help file (2)
	 *       HTML/R/                 ... references (3)
	 *       HTML/D/                 ... definitions (3)
	 *       HTML/search.html        ... search index (4)
	 *       HTML/defines.html       ... definitions index (5)
	 *       HTML/defines/           ... definitions index (5)
	 *       HTML/files/             ... file index (6)
	 *       HTML/index.html         ... index file (7)
	 *       HTML/mains.html         ... main index (8)
	 *       HTML/null.html          ... main null html (8)
	 *       HTML/S/                 ... source files (9)
	 *       HTML/I/                 ... include file index (9)
	 *       HTML/rebuild.sh         ... rebuild script (10)
	 *       HTML/style.css          ... style sheet (11)
	 *------------------------------------------------------------------
	 */
	/* for clean up */
	signal_setup();
	sethandler(clean);

        HTML = normal_suffix;

	message("[%s] Htags started", now());
	init_statistics();
	/*
	 * (#) check if GTAGS, GRTAGS is the latest.
	 */
	if (get_dbpath())
		message(" Using %s/GTAGS.", get_dbpath());
	if (grtags_is_empty)
		message(" GRTAGS is empty.");
	if (gpath_open(dbpath, 0) < 0)
		die("GPATH not found.");
	if (!w32) {
		/* UNDER CONSTRUCTION */
	}
	if (auto_completion || tree_view) {
		STATIC_STRBUF(sb);
		strbuf_clear(sb);
		strbuf_puts_nl(sb, "<script type='text/javascript' src='js/jquery.js'></script>");
		if (auto_completion)
			loadfile(makepath(datadir, "gtags/jscode_suggest", NULL), sb);
		if (tree_view)
			loadfile(makepath(datadir, "gtags/jscode_treeview", NULL), sb);
		jscode = strbuf_value(sb);
	}
	/*
	 * (0) make directories
	 */
	message("[%s] (0) making directories ...", now());
	if (!test("d", distpath))
		if (mkdir(distpath, 0777) < 0)
			die("cannot make directory '%s'.", distpath);
	make_directory_in_distpath("files");
	make_directory_in_distpath("defines");
	make_directory_in_distpath(SRCS);
	make_directory_in_distpath(INCS);
	make_directory_in_distpath(INCREFS);
	if (!dynamic) {
		make_directory_in_distpath(DEFS);
		make_directory_in_distpath(REFS);
		if (symbol)
			make_directory_in_distpath(SYMS);
	}
	if (fflag || dynamic)
		make_directory_in_distpath("cgi-bin");
	if (Iflag)
		make_directory_in_distpath("icons");
	if (auto_completion || tree_view)
		 make_directory_in_distpath("js");
	/*
	 * (1) make CGI program
	 */
	if (fflag || dynamic) {
		char cgidir[MAXPATHLEN];

		snprintf(cgidir, sizeof(cgidir), "%s/cgi-bin", distpath);
		message("[%s] (1) making CGI program ...", now());
		if (fflag || dynamic)
			makeprogram(cgidir, "global.cgi", 0755);
		if (auto_completion)
			makeprogram(cgidir, "completion.cgi", 0755);
		makehtaccess(cgidir, ".htaccess", 0644);
	} else {
		message("[%s] (1) making CGI program ...(skipped)", now());
	}
	if (av) {
		const char *path = makepath(distpath, "GTAGSROOT", NULL);
		FILE *op = fopen(path, "w");
		if (op == NULL)
			die("cannot make file '%s'.", path);
		fputs(cwdpath, op);
		fputc('\n', op);
		fclose(op);
	}
	/*
	 * (2) make help file
	 */
	message("[%s] (2) making help.html ...", now());
	makehelp("help.html");
	/*
	 * (#) load GPATH
	 */
	load_gpath(dbpath);

	/*
	 * (3) make function entries (D/ and R/)
	 *     MAKING TAG CACHE
	 */
	message("[%s] (3) making tag lists ...", now());
	cache_open();
	tim = statistics_time_start("Time of making tag lists");
	func_total = makedupindex();
	statistics_time_end(tim);
	message("Total %d functions.", func_total);
	/*
	 * (4) search index. (search.html)
	 */
	if (Fflag && fflag) {
		message("[%s] (4) making search index ...", now());
		makesearchindex("search.html");
	}
	{
		STRBUF *defines = strbuf_open(0);
		STRBUF *files = strbuf_open(0);

		/*
		 * (5) make definition index (defines.html and defines/)
		 *     PRODUCE @defines
		 */
		message("[%s] (5) making definition index ...", now());
		tim = statistics_time_start("Time of making definition index");
		func_total = makedefineindex("defines.html", func_total, defines);
		statistics_time_end(tim);
		message("Total %d functions.", func_total);
		/*
		 * (6) make file index (files.html and files/)
		 *     PRODUCE @files, %includes
		 */
		message("[%s] (6) making file index ...", now());
		init_inc();
		tim = statistics_time_start("Time of making file index");
		file_total = makefileindex("files.html", files);
		statistics_time_end(tim);
		message("Total %d files.", file_total);
		html_count += file_total;
		/*
		 * (7) make call tree using cflow(1)'s output (cflow.html)
		 */
		if (call_file || callee_file) {
			message("[%s] (7) making cflow index ...", now());
			tim = statistics_time_start("Time of making cflow index");
			if (call_file)
				if (makecflowindex("call.html", call_file) < 0)
					call_file = NULL;
			if (callee_file)
				if (makecflowindex("callee.html", callee_file) < 0)
					callee_file = NULL;
			statistics_time_end(tim);
		}
		/*
		 * [#] make include file index.
		 */
		message("[%s] (#) making include file index ...", now());
		tim = statistics_time_start("Time of making include file index");
		makeincludeindex();
		statistics_time_end(tim);
		/*
		 * [#] make a common part for mains.html and index.html
		 *     USING @defines @files
		 */
		message("[%s] (#) making a common part ...", now());
		index = makecommonpart(title, strbuf_value(defines), strbuf_value(files));

		strbuf_close(defines);
		strbuf_close(files);
	}
	/*
	 * (7)make index file (index.html)
	 */
	message("[%s] (7) making index file ...", now());
	makeindex("index.html", title, index);
	/*
	 * (8) make main index (mains.html)
	 */
	message("[%s] (8) making main index ...", now());
	makemainindex("mains.html", index);
	/*
	 * (9) make HTML files (SRCS/)
	 *     USING TAG CACHE, %includes and anchor database.
	 */
	message("[%s] (9) making hypertext from source code ...", now());
	tim = statistics_time_start("Time of making hypertext");
	makehtml(file_total);
	statistics_time_end(tim);
	/*
	 * (10) rebuild script. (rebuild.sh)
	 *
	 * Don't grant execute permission to rebuild script.
	 */
	makerebuild("rebuild.sh");
	if (chmod(makepath(distpath, "rebuild.sh", NULL), 0640) < 0)
		die("cannot chmod rebuild script.");
	/*
	 * (11) style sheet file (style.css)
	 */
	if (enable_xhtml) {
		char src[MAXPATHLEN];
		char dist[MAXPATHLEN];
		snprintf(src, sizeof(src), "%s/gtags/style.css", datadir);
		snprintf(dist, sizeof(dist), "%s/style.css", distpath);
		copyfile(src, dist);
	}
	if (auto_completion || tree_view) {
		char src[MAXPATHLEN];
		char dist[MAXPATHLEN];

		snprintf(src, sizeof(src), "%s/gtags/jquery", datadir);
		snprintf(dist, sizeof(dist), "%s/js", distpath);
		copydirectory(src, dist);
		snprintf(src, sizeof(src), "%s/gtags/jquery/images", datadir);
		snprintf(dist, sizeof(dist), "%s/js/images", distpath);
		copydirectory(src, dist);
	}
	message("[%s] Done.", now());
	if (vflag && (fflag || dynamic || auto_completion)) {
		message("\n[Information]\n");
		message(" o Htags was invoked with the -f, -c, -D or --auto-completion option. You should");
		message("   start http server so that cgi-bin/*.cgi is executed as a CGI script.");
 		message("\n If you are using Apache, 'HTML/.htaccess' might be helpful for you.\n");
		message(" Good luck!\n");
	}
	if (Iflag) {
		char src[MAXPATHLEN];
		char dist[MAXPATHLEN];

		snprintf(src, sizeof(src), "%s/gtags/icons", datadir);
		snprintf(dist, sizeof(dist), "%s/icons", distpath);
		copydirectory(src, dist);
	}
	gpath_close();
	/*
	 * Print statistics information.
	 */
	print_statistics(statistics);
	clean();
	return 0;
}
Beispiel #20
0
int
main(int argc, char **argv)
{
    char dbpath[MAXPATHLEN];
    char cwd[MAXPATHLEN];
    STRBUF *sb = strbuf_open(0);
    int optchar;
    int option_index = 0;
    STATISTICS_TIME *tim;

    /*
     * Setup GTAGSCONF and GTAGSLABEL environment variable
     * according to the --gtagsconf and --gtagslabel option.
     */
    preparse_options(argc, argv);
    /*
     * Get the project root directory.
     */
    if (!vgetcwd(cwd, MAXPATHLEN))
        die("cannot get current directory.");
    canonpath(cwd);
    /*
     * Load configuration file.
     */
    openconf(cwd);
    configuration();
    setenv_from_config();
    {
        char *env = getenv("GTAGS_OPTIONS");
        if (env && *env)
            argv = prepend_options(&argc, argv, env);
    }
    logging_arguments(argc, argv);
    while ((optchar = getopt_long(argc, argv, "cd:f:iIn:oOqvwse", long_options, &option_index)) != EOF) {
        switch (optchar) {
        case 0:
            /* already flags set */
            break;
        case OPT_CONFIG:
            show_config = 1;
            if (optarg)
                config_name = optarg;
            break;
        case OPT_GTAGSCONF:
        case OPT_GTAGSLABEL:
            /* These options are already parsed in preparse_options() */
            break;
        case OPT_SINGLE_UPDATE:
            iflag++;
            single_update = optarg;
            break;
        case OPT_ACCEPT_DOTFILES:
            set_accept_dotfiles();
            break;
        case 'c':
            cflag++;
            break;
        case 'd':
            dump_target = optarg;
            break;
        case 'f':
            file_list = optarg;
            break;
        case 'i':
            iflag++;
            break;
        case 'I':
            Iflag++;
            break;
        case 'o':
            /*
             * Though the -o(--omit-gsyms) was removed, this code
             * is left for compatibility.
             */
            break;
        case 'O':
            Oflag++;
            break;
        case 'q':
            qflag++;
            setquiet();
            break;
        case 'w':
            wflag++;
            break;
        case 'v':
            vflag++;
            setverbose();
            break;
        default:
            usage();
            break;
        }
    }
    if (qflag)
        vflag = 0;
    if (show_version)
        version(NULL, vflag);
    if (show_help)
        help();

    argc -= optind;
    argv += optind;

    /* If dbpath is specified, -O(--objdir) option is ignored. */
    if (argc > 0)
        Oflag = 0;
    if (show_config) {
        openconf(setupdbpath(0) == 0 ? get_root() : NULL);
        if (config_name)
            printconf(config_name);
        else
            fprintf(stdout, "%s\n", getconfline());
        exit(0);
    } else if (dump_target) {
        /*
         * Dump a tag file.
         */
        DBOP *dbop = NULL;
        const char *dat = 0;
        int is_gpath = 0;

        if (!test("f", dump_target))
            die("file '%s' not found.", dump_target);
        if ((dbop = dbop_open(dump_target, 0, 0, DBOP_RAW)) == NULL)
            die("file '%s' is not a tag file.", dump_target);
        /*
         * The file which has a NEXTKEY record is GPATH.
         */
        if (dbop_get(dbop, NEXTKEY))
            is_gpath = 1;
        for (dat = dbop_first(dbop, NULL, NULL, 0); dat != NULL; dat = dbop_next(dbop)) {
            const char *flag = is_gpath ? dbop_getflag(dbop) : "";

            if (*flag)
                printf("%s\t%s\t%s\n", dbop->lastkey, dat, flag);
            else
                printf("%s\t%s\n", dbop->lastkey, dat);
        }
        dbop_close(dbop);
        exit(0);
    } else if (Iflag) {
#define REQUIRED_MKID_VERSION "4.5"
        char *p;

        if (!usable("mkid"))
            die("mkid not found.");
        if (read_first_line("mkid --version", sb))
            die("mkid cannot executed.");
        p = strrchr(strbuf_value(sb), ' ');
        if (p == NULL)
            die("invalid version string of mkid: %s", strbuf_value(sb));
        switch (check_version(p + 1, REQUIRED_MKID_VERSION)
#ifdef _WIN32
                || strcmp(p + 1, "3.2.99") == 0
#endif
               )  {
        case 1:
            break;	/* OK */
        case 0:
            die("mkid version %s or later is required.", REQUIRED_MKID_VERSION);
        default:
            die("invalid version string of mkid: %s", strbuf_value(sb));
        }
    }

    /*
     * If 'gtags.files' exists, use it as a file list.
     * If the file_list other than "-" is given, it must be readable file.
     */
    if (file_list == NULL && test("f", GTAGSFILES))
        file_list = GTAGSFILES;
    if (file_list && strcmp(file_list, "-")) {
        if (test("d", file_list))
            die("'%s' is a directory.", file_list);
        else if (!test("f", file_list))
            die("'%s' not found.", file_list);
        else if (!test("r", file_list))
            die("'%s' is not readable.", file_list);
    }
    /*
     * Regularize the path name for single updating (--single-update).
     */
    if (single_update) {
        static char regular_path_name[MAXPATHLEN];
        char *p = single_update;

        if (!test("f", p))
            die("'%s' not found.", p);
#if _WIN32 || __DJGPP__
        for (; *p; p++)
            if (*p == '\\')
                *p = '/';
        p = single_update;
#define LOCATEFLAG MATCH_AT_FIRST|IGNORE_CASE
#else
#define LOCATEFLAG MATCH_AT_FIRST
#endif
        if (isabspath(p)) {
            char *q = locatestring(p, cwd, LOCATEFLAG);

            if (q && *q == '/')
                snprintf(regular_path_name, MAXPATHLEN, "./%s", q + 1);
            else
                die("path '%s' is out of the project.", p);

        } else {
            if (p[0] == '.' && p[1] == '/')
                snprintf(regular_path_name, MAXPATHLEN, "%s", p);
            else
                snprintf(regular_path_name, MAXPATHLEN, "./%s", p);
        }
        single_update = regular_path_name;
    }
    /*
     * Decide directory (dbpath) in which gtags make tag files.
     *
     * Gtags create tag files at current directory by default.
     * If dbpath is specified as an argument then use it.
     * If the -i option specified and both GTAGS and GRTAGS exists
     * at one of the candidate directories then gtags use existing
     * tag files.
     */
    if (iflag) {
        if (argc > 0)
            realpath(*argv, dbpath);
        else if (!gtagsexist(cwd, dbpath, MAXPATHLEN, vflag))
            strlimcpy(dbpath, cwd, sizeof(dbpath));
    } else {
        if (argc > 0)
            realpath(*argv, dbpath);
        else if (Oflag) {
            char *objdir = getobjdir(cwd, vflag);

            if (objdir == NULL)
                die("Objdir not found.");
            strlimcpy(dbpath, objdir, sizeof(dbpath));
        } else
            strlimcpy(dbpath, cwd, sizeof(dbpath));
    }
    if (iflag && (!test("f", makepath(dbpath, dbname(GTAGS), NULL)) ||
                  !test("f", makepath(dbpath, dbname(GRTAGS), NULL)) ||
                  !test("f", makepath(dbpath, dbname(GPATH), NULL)))) {
        if (wflag)
            warning("GTAGS, GRTAGS or GPATH not found. -i option ignored.");
        iflag = 0;
    }
    if (!test("d", dbpath))
        die("directory '%s' not found.", dbpath);
    if (vflag)
        fprintf(stderr, "[%s] Gtags started.\n", now());
    /*
     * initialize parser.
     */
    if (vflag && gtags_parser)
        fprintf(stderr, " Using plug-in parser.\n");
    parser_init(langmap, gtags_parser);
    if (vflag && file_list)
        fprintf(stderr, " Using '%s' as a file list.\n", file_list);
    /*
     * Start statistics.
     */
    init_statistics();
    /*
     * incremental update.
     */
    if (iflag) {
        /*
         * Version check. If existing tag files are old enough
         * gtagsopen() abort with error message.
         */
        GTOP *gtop = gtags_open(dbpath, cwd, GTAGS, GTAGS_MODIFY, 0);
        gtags_close(gtop);
        /*
         * GPATH is needed for incremental updating.
         * Gtags check whether or not GPATH exist, since it may be
         * removed by mistake.
         */
        if (!test("f", makepath(dbpath, dbname(GPATH), NULL)))
            die("Old version tag file found. Please remake it.");
        (void)incremental(dbpath, cwd);
        print_statistics(statistics);
        exit(0);
    }
    /*
     * create GTAGS and GRTAGS
     */
    createtags(dbpath, cwd);
    /*
     * create idutils index.
     */
    if (Iflag) {
        FILE *op;
        GFIND *gp;
        const char *path;

        tim = statistics_time_start("Time of creating ID");
        if (vflag)
            fprintf(stderr, "[%s] Creating indexes for idutils.\n", now());
        strbuf_reset(sb);
        /*
         * Since idutils stores the value of PWD in ID file, we need to
         * force idutils to follow our style.
         */
#if _WIN32 || __DJGPP__
        strbuf_puts(sb, "mkid --files0-from=-");
#else
        strbuf_sprintf(sb, "PWD=%s mkid --files0-from=-", quote_shell(cwd));
#endif
        if (vflag)
            strbuf_puts(sb, " -v");
        strbuf_sprintf(sb, " --file=%s/ID", quote_shell(dbpath));
        if (vflag) {
#ifdef __DJGPP__
            if (is_unixy())	/* test for 4DOS as well? */
#endif
                strbuf_puts(sb, " 1>&2");
        } else {
            strbuf_puts(sb, " >" NULL_DEVICE);
#ifdef __DJGPP__
            if (is_unixy())	/* test for 4DOS as well? */
#endif
                strbuf_puts(sb, " 2>&1");
        }
        if (debug)
            fprintf(stderr, "executing mkid like: %s\n", strbuf_value(sb));
        op = popen(strbuf_value(sb), "w");
        if (op == NULL)
            die("cannot execute '%s'.", strbuf_value(sb));
        gp = gfind_open(dbpath, NULL, GPATH_BOTH);
        while ((path = gfind_read(gp)) != NULL) {
            fputs(path, op);
            fputc('\0', op);
        }
        gfind_close(gp);
        if (pclose(op) != 0)
            die("terminated abnormally '%s' (errno = %d).", strbuf_value(sb), errno);
        if (test("f", makepath(dbpath, "ID", NULL)))
            if (chmod(makepath(dbpath, "ID", NULL), 0644) < 0)
                die("cannot chmod ID file.");
        statistics_time_end(tim);
    }
    if (vflag)
        fprintf(stderr, "[%s] Done.\n", now());
    closeconf();
    strbuf_close(sb);
    print_statistics(statistics);

    return 0;
}
Beispiel #21
0
int
decide_tag_by_context(const char *tag, const char *file, int lineno)
{
	STRBUF *sb = NULL;
	char path[MAXPATHLEN], s_fid[MAXFIDLEN];
	const char *tagline, *p;
	DBOP *dbop;
	int db = GSYMS;
	int iscompline = 0;

	if (normalize(file, get_root_with_slash(), cwd, path, sizeof(path)) == NULL)
		die("'%s' is out of source tree.", file);
	/*
	 * get file id
	 */
	if (gpath_open(dbpath, 0) < 0)
		die("GPATH not found.");
	if ((p = gpath_path2fid(path, NULL)) == NULL)
		die("path name in the context is not found.");
	strlimcpy(s_fid, p, sizeof(s_fid));
	gpath_close();
	/*
	 * read btree records directly to avoid the overhead.
	 */
	dbop = dbop_open(makepath(dbpath, dbname(GTAGS), NULL), 0, 0, 0);
	if (dbop == NULL)
		die("cannot open GTAGS.");
	if (dbop_getoption(dbop, COMPLINEKEY))
		iscompline = 1;
	tagline = dbop_first(dbop, tag, NULL, 0);
	if (tagline) {
		db = GTAGS;
		for (; tagline; tagline = dbop_next(dbop)) {
			/*
			 * examine whether the definition record include the context.
			 */
			p = locatestring(tagline, s_fid, MATCH_AT_FIRST);
			if (p != NULL && *p == ' ') {
				for (p++; *p && *p != ' '; p++)
					;
				if (*p++ != ' ' || !isdigit(*p))
					die("Impossible! decide_tag_by_context(1)");
				/*
				 * Standard format	n <blank> <image>$
				 * Compact format	d,d,d,d$
				 */
				if (!iscompline) {			/* Standard format */
					if (atoi(p) == lineno) {
						db = GRTAGS;
						goto finish;
					}
				} else {				/* Compact format */
					int n, cur, last = 0;

					do {
						if (!isdigit(*p))
							die("Impossible! decide_tag_by_context(2)");
						NEXT_NUMBER(p);
						cur = last + n;
						if (cur == lineno) {
							db = GRTAGS;
							goto finish;
						}
						last = cur;
						if (*p == '-') {
							if (!isdigit(*++p))
								die("Impossible! decide_tag_by_context(3)");
							NEXT_NUMBER(p);
							cur = last + n;
							if (lineno >= last && lineno <= cur) {
								db = GRTAGS;
								goto finish;
							}
							last = cur;
						}
						if (*p) {
							if (*p == ',')
								p++;
							else
								die("Impossible! decide_tag_by_context(4)");
						}
					} while (*p);
				}
			}
		}
	}
finish:
	dbop_close(dbop);
	if (db == GSYMS && getenv("GTAGSLIBPATH")) {
		char libdbpath[MAXPATHLEN];
		char *libdir = NULL, *nextp = NULL;

		sb = strbuf_open(0);
		strbuf_puts(sb, getenv("GTAGSLIBPATH"));
		for (libdir = strbuf_value(sb); libdir; libdir = nextp) {
			 if ((nextp = locatestring(libdir, PATHSEP, MATCH_FIRST)) != NULL)
                                *nextp++ = 0;
			if (!gtagsexist(libdir, libdbpath, sizeof(libdbpath), 0))
				continue;
			if (!strcmp(dbpath, libdbpath))
				continue;
			dbop = dbop_open(makepath(libdbpath, dbname(GTAGS), NULL), 0, 0, 0);
			if (dbop == NULL)
				continue;
			tagline = dbop_first(dbop, tag, NULL, 0);
			dbop_close(dbop);
			if (tagline != NULL) {
				db = GTAGS;
				break;
			}
		}
		strbuf_close(sb);
	}
	return db;
}
Beispiel #22
0
int
main(int argc, char **argv)
{
	char dbpath[MAXPATHLEN];
	char cwd[MAXPATHLEN];
	STRBUF *sb = strbuf_open(0);
	int optchar;
	int option_index = 0;
	STATISTICS_TIME *tim;

	while ((optchar = getopt_long(argc, argv, "cd:f:iuIn:oOqvwse", long_options, &option_index)) != EOF) {
		switch (optchar) {
		case 0:
			/* already flags set */
			break;
		case OPT_CONFIG:
			show_config = 1;
			if (optarg)
				config_name = optarg;
			break;
		case OPT_GTAGSCONF:
			gtagsconf = optarg;
			break;
		case OPT_GTAGSLABEL:
			gtagslabel = optarg;
			break;
		case OPT_PATH:
			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_SINGLE_UPDATE:
			iflag++;
			single_update = optarg;
			break;
		case OPT_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 'c':
			cflag++;
			break;
		case 'd':
			dump_target = optarg;
			break;
		case 'f':
			file_list = optarg;
			break;
		case 'i':
			iflag++;
			break;
		case 'u':
			uflag++;
			iflag++;
			break;
		case 'I':
			Iflag++;
			break;
		case 'o':
			/*
			 * Though the -o(--omit-gsyms) was removed, this code
			 * is left for compatibility.
			 */
			break;
		case 'O':
			Oflag++;
			break;
		case 'q':
			qflag++;
			setquiet();
			break;
		case 'w':
			wflag++;
			break;
		case 'v':
			vflag++;
			setverbose();
			break;
		default:
			usage();
			break;
		}
	}
	if (gtagsconf) {
		char path[MAXPATHLEN];

		if (realpath(gtagsconf, path) == NULL)
			die("%s not found.", gtagsconf);
		set_env("GTAGSCONF", path);
	}
	if (gtagslabel) {
		set_env("GTAGSLABEL", gtagslabel);
	}
	if (qflag)
		vflag = 0;
	if (show_version)
		version(NULL, vflag);
	if (show_help)
		help();

	argc -= optind;
        argv += optind;

	/* If dbpath is specified, -O(--objdir) option is ignored. */
	if (argc > 0)
		Oflag = 0;
	if (show_config) {
		if (config_name)
			printconf(config_name);
		else
			fprintf(stdout, "%s\n", getconfline());
		exit(0);
	} else if (do_path) {
		/*
		 * This is the main body of path filter.
		 * 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 follws:
		 *
		 * 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=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("gtags --path: 3 arguments needed.");
		cv = convert_open(convert_type, FORMAT_CTAGS_X, argv[0], argv[1], argv[2], stdout);
		while ((ctags_x = strbuf_fgets(ib, stdin, STRBUF_NOCRLF)) != NULL)
			convert_put(cv, ctags_x);
		convert_close(cv);
		strbuf_close(ib);
		exit(0);
	} else if (dump_target) {
		/*
		 * Dump a tag file.
		 */
		DBOP *dbop = NULL;
		const char *dat = 0;
		int is_gpath = 0;

		char* target_file = NULL;
		if (!test("f", dump_target)) {
			target_file = strchr(dump_target, ':');
			if (target_file == NULL) 
				die("file '%s' not found", dump_target);

			*target_file++ = 0; //move to the next char, which starts the target file.
			if (!test("f", dump_target)) {
				die("file '%s' not found.", dump_target);
			}
		}

		if ((dbop = dbop_open(dump_target, 0, 0, DBOP_RAW)) == NULL)
			die("file '%s' is not a tag file.", dump_target);
		/*
		 * The file which has a NEXTKEY record is GPATH.
		 */
		if (dbop_get(dbop, NEXTKEY))
			is_gpath = 1;

		if (target_file && !is_gpath) {
			die("dump target_file can only be used with GPATH");
		}

		if (target_file) {
			dat = dbop_get(dbop, target_file);
			if (dat == NULL) {
				die("target_file %s not found in GPATH", target_file);
			}
			time_t t = gpath_mtime(dbop, target_file);
			printf("%d\n", t);
		} else {
			for (dat = dbop_first(dbop, NULL, NULL, 0); dat != NULL; dat = dbop_next(dbop)) {
				const char *flag = is_gpath ? dbop_getflag(dbop) : "";

				if (*flag)
					if (is_gpath) {
						time_t t = gpath_mtime(dbop, dbop->lastkey);
						printf("%s\t%s\t%s\t%s\n", dbop->lastkey, dat, flag, ctime(&t));
					} else
						printf("%s\t%s\t%s\n", dbop->lastkey, dat, flag);
				else
					printf("%s\t%s\n", dbop->lastkey, dat);
			}
		}
		dbop_close(dbop);
		exit(0);
	} else if (Iflag) {
		if (!usable("mkid"))
			die("mkid not found.");
	}

	/*
	 * If 'gtags.files' exists, use it as a file list.
	 * If the file_list other than "-" is given, it must be readable file.
	 */
	if (file_list == NULL && test("f", GTAGSFILES))
		file_list = GTAGSFILES;
	if (file_list && strcmp(file_list, "-")) {
		if (test("d", file_list))
			die("'%s' is a directory.", file_list);
		else if (!test("f", file_list))
			die("'%s' not found.", file_list);
		else if (!test("r", file_list))
			die("'%s' is not readable.", file_list);
	}
	/*
	 * Regularize the path name for single updating (--single-update).
	 */
	if (single_update) {
		static char regular_path_name[MAXPATHLEN];
		char *p = single_update;
		
		if (!test("f", p))
			die("'%s' not found.", p);
		if (isabspath(p))
			die("--single-update requires relative path name.");
		if (!(p[0] == '.' && p[1] == '/')) {
			snprintf(regular_path_name, MAXPATHLEN, "./%s", p);
			p = regular_path_name;
		}
		single_update = p;
	}
	if (!getcwd(cwd, MAXPATHLEN))
		die("cannot get current directory.");
	canonpath(cwd);
	/*
	 * Decide directory (dbpath) in which gtags make tag files.
	 *
	 * Gtags create tag files at current directory by default.
	 * If dbpath is specified as an argument then use it.
	 * If the -i option specified and both GTAGS and GRTAGS exists
	 * at one of the candidate directories then gtags use existing
	 * tag files.
	 */
	if (iflag) {
		if (argc > 0)
			realpath(*argv, dbpath);
		else if (!gtagsexist(cwd, dbpath, MAXPATHLEN, vflag))
			strlimcpy(dbpath, cwd, sizeof(dbpath));
	} else {
		if (argc > 0)
			realpath(*argv, dbpath);
		else if (Oflag) {
			char *objdir = getobjdir(cwd, vflag);

			if (objdir == NULL)
				die("Objdir not found.");
			strlimcpy(dbpath, objdir, sizeof(dbpath));
		} else
			strlimcpy(dbpath, cwd, sizeof(dbpath));
	}
	if (iflag && (!test("f", makepath(dbpath, dbname(GTAGS), NULL)) ||
		!test("f", makepath(dbpath, dbname(GRTAGS), NULL)) ||
		!test("f", makepath(dbpath, dbname(GPATH), NULL)))) {
		if (wflag)
			warning("GTAGS, GRTAGS or GPATH not found. -i option ignored.");
		iflag = 0;
	}
	if (!test("d", dbpath))
		die("directory '%s' not found.", dbpath);
	if (vflag)
		fprintf(stderr, "[%s] Gtags started.\n", now());
	/*
	 * load configuration file.
	 */
	openconf();
	if (getconfb("extractmethod"))
		extractmethod = 1;
	strbuf_reset(sb);
	if (getconfs("langmap", sb))
		langmap = check_strdup(strbuf_value(sb));
	strbuf_reset(sb);
	if (getconfs("gtags_parser", sb))
		gtags_parser = check_strdup(strbuf_value(sb));
	/*
	 * initialize parser.
	 */
	if (vflag && gtags_parser)
		fprintf(stderr, " Using plug-in parser.\n");
	parser_init(langmap, gtags_parser);
	if (vflag && file_list)
		fprintf(stderr, " Using '%s' as a file list.\n", file_list);
	/*
	 * Start statistics.
	 */
	init_statistics();
	/*
	 * incremental update.
	 */
	if (iflag) {
		/*
		 * Version check. If existing tag files are old enough
		 * gtagsopen() abort with error message.
		 */
		GTOP *gtop = gtags_open(dbpath, cwd, GTAGS, GTAGS_MODIFY, 0);
		gtags_close(gtop);
		/*
		 * GPATH is needed for incremental updating.
		 * Gtags check whether or not GPATH exist, since it may be
		 * removed by mistake.
		 */
		if (!test("f", makepath(dbpath, dbname(GPATH), NULL)))
			die("Old version tag file found. Please remake it.");
		(void)incremental(dbpath, cwd);
		print_statistics(statistics);
		exit(0);
	}
	/*
	 * create GTAGS and GRTAGS
	 */
	createtags(dbpath, cwd);
	/*
	 * create idutils index.
	 */
	if (Iflag) {
		tim = statistics_time_start("Time of creating ID");
		if (vflag)
			fprintf(stderr, "[%s] Creating indexes for idutils.\n", now());
		strbuf_reset(sb);
		strbuf_puts(sb, "mkid");
		if (vflag)
			strbuf_puts(sb, " -v");
		strbuf_sprintf(sb, " --file='%s/ID'", dbpath);
		if (vflag) {
#ifdef __DJGPP__
			if (is_unixy())	/* test for 4DOS as well? */
#endif
			strbuf_puts(sb, " 1>&2");
		} else {
			strbuf_puts(sb, " >/dev/null");
		}
		if (debug)
			fprintf(stderr, "executing mkid like: %s\n", strbuf_value(sb));
		if (system(strbuf_value(sb)))
			die("mkid failed: %s", strbuf_value(sb));
		if (chmod(makepath(dbpath, "ID", NULL), 0644) < 0)
			die("cannot chmod ID file.");
		statistics_time_end(tim);
	}
	if (vflag)
		fprintf(stderr, "[%s] Done.\n", now());
	closeconf();
	strbuf_close(sb);
	print_statistics(statistics);

	return 0;
}
Beispiel #23
0
void
parsefile(char *const *argv, const char *cwd, const char *root, const char *dbpath, int db)
{
	int count = 0;
	int file_count = 0;
	STRBUF *sb = strbuf_open(0);
	char *langmap;
	const char *plugin_parser, *av;
	char path[MAXPATHLEN];
	struct parsefile_data data;

	if (db == GRTAGS + GSYMS)
		data.target = TARGET_REF|TARGET_SYM;
	else
		data.target = 1 << db;
	data.extractmethod = getconfb("extractmethod");
	if (getconfs("langmap", sb))
		langmap = check_strdup(strbuf_value(sb));
	else
		langmap = NULL;
	strbuf_reset(sb);
	if (getconfs("gtags_parser", sb))
		plugin_parser = strbuf_value(sb);
	else
		plugin_parser = NULL;
	data.cv = convert_open(type, format, root, cwd, dbpath, stdout);
	if (gpath_open(dbpath, 0) < 0)
		die("GPATH not found.");
	if (data.target == TARGET_REF || data.target == TARGET_SYM) {
		data.dbop = dbop_open(makepath(dbpath, dbname(GTAGS), NULL), 0, 0, 0);
		if (data.dbop == NULL)
			die("%s not found.", dbname(GTAGS));
	} else {
		data.dbop = NULL;
	}
	data.fid = NULL;
	parser_init(langmap, plugin_parser);
	if (langmap != NULL)
		free(langmap);

	if (*argv && file_list)
		args_open_both(argv, file_list);
	else if (*argv)
		args_open(argv);
	else if (file_list)
		args_open_filelist(file_list);
	else
		args_open_nop();
	while ((av = args_read()) != NULL) {
		/*
		 * convert the path into relative to the root directory of source tree.
		 */
		if (normalize(av, get_root_with_slash(), cwd, path, sizeof(path)) == NULL)
			if (!qflag)
				fprintf(stderr, "'%s' is out of source tree.\n", path + 2);
		/*
		 * Memorize the file id of the path. This is used in put_syms().
		 */
		{
			static char s_fid[MAXFIDLEN];
			const char *p = gpath_path2fid(path, NULL);

			if (!p) {
				if (!qflag)
					fprintf(stderr, "'%s' not found in GPATH.\n", path + 2);
				continue;
			}
			strlimcpy(s_fid, p, sizeof(s_fid));
			data.fid = s_fid;
		}
		if (!test("f", makepath(root, path, NULL))) {
			if (test("d", NULL)) {
				if (!qflag)
					fprintf(stderr, "'%s' is a directory.\n", av);
			} else {
				if (!qflag)
					fprintf(stderr, "'%s' not found.\n", av);
			}
			continue;
		}
		if (lflag && !locatestring(path, localprefix, MATCH_AT_FIRST))
			continue;
		data.count = 0;
		parse_file(path, 0, put_syms, &data);
		count += data.count;
		file_count++;
	}
	args_close();
	parser_exit();
	/*
	 * Settlement
	 */
	if (data.dbop != NULL)
		dbop_close(data.dbop);
	gpath_close();
	convert_close(data.cv);
	strbuf_close(sb);
	if (vflag) {
		print_count(count);
		fprintf(stderr, " (no index used).\n");
	}
}
Beispiel #24
0
/*
 * pathlist: print candidate path list.
 *
 *	i)	dbpath
 */
void
pathlist(const char *pattern, const char *dbpath)
{
	GFIND *gp;
	CONVERT *cv;
	const char *path, *p;
	regex_t preg;
	int count;
	int target = GPATH_SOURCE;

	if (oflag)
		target = GPATH_BOTH;
	if (Oflag)
		target = GPATH_OTHER;
	if (pattern) {
		int flags = 0;
		char edit[IDENTLEN];

		if (!Gflag)
			flags |= REG_EXTENDED;
		if (iflag || getconfb("icase_path"))
			flags |= REG_ICASE;
#ifdef _WIN32
		flags |= REG_ICASE;
#endif /* _WIN32 */
		/*
		 * We assume '^aaa' as '^/aaa'.
		 */
		if (*pattern == '^' && *(pattern + 1) != '/') {
			snprintf(edit, sizeof(edit), "^/%s", pattern + 1);
			pattern = edit;
		}
		if (regcomp(&preg, pattern, flags) != 0)
			die("invalid regular expression.");
	}
	if (!localprefix)
		localprefix = "./";
	cv = convert_open(type, format, root, cwd, dbpath, stdout);
	count = 0;

	gp = gfind_open(dbpath, localprefix, target);
	while ((path = gfind_read(gp)) != NULL) {
		/*
		 * skip localprefix because end-user doesn't see it.
		 */
		p = path + strlen(localprefix) - 1;
		if (pattern) {
			int result = regexec(&preg, p, 0, 0, 0);

			if ((!Vflag && result != 0) || (Vflag && result == 0))
				continue;
		} else if (Vflag)
			continue;
		if (format == FORMAT_PATH)
			convert_put_path(cv, path);
		else
			convert_put_using(cv, "path", path, 1, " ", gp->dbop->lastdat);
		count++;
	}
	gfind_close(gp);
	convert_close(cv);
	if (pattern)
		regfree(&preg);
	if (vflag) {
		switch (count) {
		case 0:
			fprintf(stderr, "file not found");
			break;
		case 1:
			fprintf(stderr, "1 file located");
			break;
		default:
			fprintf(stderr, "%d files located", count);
			break;
		}
		fprintf(stderr, " (using '%s').\n", makepath(dbpath, dbname(GPATH), NULL));
	}
}
Beispiel #25
0
/*
 * incremental: incremental update
 *
 *	i)	dbpath	dbpath directory
 *	i)	root	root directory of source tree
 *	r)		0: not updated, 1: updated
 */
int
incremental(const char *dbpath, const char *root)
{
	STATISTICS_TIME *tim;
	struct stat statp;
	STRBUF *addlist = strbuf_open(0);
	STRBUF *deletelist = strbuf_open(0);
	STRBUF *addlist_other = strbuf_open(0);
	IDSET *deleteset, *findset;
	int updated = 0;
	const char *path;
	unsigned int id, limit;

	tim = statistics_time_start("Time of inspecting %s and %s.", dbname(GTAGS), dbname(GRTAGS));
	if (vflag) {
		fprintf(stderr, " Tag found in '%s'.\n", dbpath);
		fprintf(stderr, " Incremental updating.\n");
	}
	/*
	 * get modified time of GTAGS.
	 */
	path = makepath(dbpath, dbname(GTAGS), NULL);

	if (gpath_open(dbpath, 0) < 0)
		die("GPATH not found.");
	/*
	 * deleteset:
	 *	The list of the path name which should be deleted from GPATH.
	 * findset:
	 *	The list of the path name which exists in the current project.
	 *	A project is limited by the --file option.
	 */
	deleteset = idset_open(gpath_nextkey());
	findset = idset_open(gpath_nextkey());
	total = 0;
	/*
	 * Make add list and delete list for update.
	 */
	if (single_update) {
		int type;
		const char *fid = gpath_path2fid(single_update, &type);
		/*
		 * The --single-update=file supports only updating.
		 * If it is new file, this option is ignored, and the processing is
		 * automatically switched to the normal procedure.
		 */
		if (fid == NULL) {
			if (vflag)
				fprintf(stderr, " --single-update option ignored, because '%s' is new file.\n", single_update);
			goto normal_update;
		}
		/*
		 * If type != GPATH_SOURCE then we have nothing to do, and you will see
		 * a message 'Global databases are up to date.'.
		 */
		if (type == GPATH_SOURCE) {
			strbuf_puts0(addlist, single_update);
			idset_add(deleteset, atoi(fid));
			total++;
		}
	} else {
normal_update:
		if (file_list)
			find_open_filelist(file_list, root);
		else
			find_open(NULL);
		while ((path = find_read()) != NULL) {
			const char *fid;
			int n_fid = 0;
			int other = 0;

			/* a blank at the head of path means 'NOT SOURCE'. */
			if (*path == ' ') {
				if (test("b", ++path))
					continue;
				other = 1;
			}
			if (stat(path, &statp) < 0)
				die("stat failed '%s'.", path);
			fid = gpath_path2fid(path, NULL);
			if (fid) { 
				n_fid = atoi(fid);
				idset_add(findset, n_fid);
			}
			if (other) {
				if (fid == NULL)
					strbuf_puts0(addlist_other, path);
			} else {
				if (fid == NULL) {
					strbuf_puts0(addlist, path);
					total++;
				} else if (gpath_mtime(NULL, fid) < statp.st_mtime) {
					if (uflag) {
						printf("%s\n", path);
					} else {
						strbuf_puts0(addlist, path);
						total++;
						idset_add(deleteset, n_fid);
					}
				}
			}
		}
		find_close();
		/*
		 * make delete list.
		 */
		if (remove_lost) {
			limit = gpath_nextkey();
		} else {
			limit = 0;
		}
		for (id = 1; id < limit; id++) {
			char fid[MAXFIDLEN];
			int type;

			snprintf(fid, sizeof(fid), "%d", id);
			/*
			 * This is a hole of GPATH. The hole increases if the deletion
			 * and the addition are repeated.
			 */
			if ((path = gpath_fid2path(fid, &type)) == NULL)
				continue;
			/*
			 * The file which does not exist in the findset is treated
			 * assuming that it does not exist in the file system.
			 */
			if (type == GPATH_OTHER) {
				if (!idset_contains(findset, id) || !test("f", path) || test("b", path))
					strbuf_puts0(deletelist, path);
			} else {
				if (!idset_contains(findset, id) || !test("f", path)) {
					strbuf_puts0(deletelist, path);
					idset_add(deleteset, id);
				}
			}
		}
	}
	gpath_close();
	statistics_time_end(tim);
	/*
	 * execute updating.
	 */
	if ((!idset_empty(deleteset) || strbuf_getlen(addlist) > 0) ||
	    (strbuf_getlen(deletelist) + strbuf_getlen(addlist_other) > 0))
	{
		int db;

		updated = 1;
		tim = statistics_time_start("Time of updating %s and %s.", dbname(GTAGS), dbname(GRTAGS));
		if (!idset_empty(deleteset) || strbuf_getlen(addlist) > 0)
			updatetags(dbpath, root, deleteset, addlist);
		if (strbuf_getlen(deletelist) + strbuf_getlen(addlist_other) > 0) {
			const char *start, *end, *p;

			if (vflag)
				fprintf(stderr, "[%s] Updating '%s'.\n", now(), dbname(GPATH));
			gpath_open(dbpath, 2);
			if (strbuf_getlen(deletelist) > 0) {
				start = strbuf_value(deletelist);
				end = start + strbuf_getlen(deletelist);

				for (p = start; p < end; p += strlen(p) + 1)
					gpath_delete(p);
			}
			if (strbuf_getlen(addlist_other) > 0) {
				start = strbuf_value(addlist_other);
				end = start + strbuf_getlen(addlist_other);

				for (p = start; p < end; p += strlen(p) + 1)
					gpath_put(p, GPATH_OTHER);
			}
			gpath_close();
		}
		/*
		 * Update modification time of tag files
		 * because they may have no definitions.
		 */
		for (db = GTAGS; db < GTAGLIM; db++)
			utime(makepath(dbpath, dbname(db), NULL), NULL);
		statistics_time_end(tim);
	}
	if (vflag) {
		if (updated)
			fprintf(stderr, " Global databases have been modified.\n");
		else
			fprintf(stderr, " Global databases are up to date.\n");
		fprintf(stderr, "[%s] Done.\n", now());
	}
	strbuf_close(addlist);
	strbuf_close(deletelist);
	strbuf_close(addlist_other);
	idset_close(deleteset);
	idset_close(findset);

	return updated;
}
Beispiel #26
0
/*
 * updatetags: update tag file.
 *
 *	i)	dbpath		directory in which tag file exist
 *	i)	root		root directory of source tree
 *	i)	deleteset	bit array of fid of deleted or modified files 
 *	i)	addlist		\0 separated list of added or modified files
 */
void
updatetags(const char *dbpath, const char *root, IDSET *deleteset, STRBUF *addlist)
{
	struct put_func_data data;
	int seqno, flags;
	const char *path, *start, *end;

	if (vflag)
		fprintf(stderr, "[%s] Updating '%s' and '%s'.\n", now(), dbname(GTAGS), dbname(GRTAGS));
	/*
	 * Open tag files.
	 */
	data.gtop[GTAGS] = gtags_open(dbpath, root, GTAGS, GTAGS_MODIFY, 0);
	if (test("f", makepath(dbpath, dbname(GRTAGS), NULL))) {
		data.gtop[GRTAGS] = gtags_open(dbpath, root, GRTAGS, GTAGS_MODIFY, 0);
	} else {
		/*
		 * If you set NULL to data.gtop[GRTAGS], parse_file() doesn't write to
		 * GRTAGS. See put_syms().
		 */
		data.gtop[GRTAGS] = NULL;
	}
	/*
	 * Delete tags from GTAGS.
	 */
	if (!idset_empty(deleteset)) {
		if (vflag) {
			char fid[MAXFIDLEN];
			int total = idset_count(deleteset);
			unsigned int id;

			seqno = 1;
			for (id = idset_first(deleteset); id != END_OF_ID; id = idset_next(deleteset)) {
				snprintf(fid, sizeof(fid), "%d", id);
				path = gpath_fid2path(fid, NULL);
				if (path == NULL)
					die("GPATH is corrupted.");
				fprintf(stderr, " [%d/%d] deleting tags of %s\n", seqno++, total, path + 2);
			}
		}
		gtags_delete(data.gtop[GTAGS], deleteset);
		if (data.gtop[GRTAGS] != NULL)
			gtags_delete(data.gtop[GRTAGS], deleteset);
	}
	/*
	 * Set flags.
	 */
	data.gtop[GTAGS]->flags = 0;
	if (extractmethod)
		data.gtop[GTAGS]->flags |= GTAGS_EXTRACTMETHOD;
	data.gtop[GRTAGS]->flags = data.gtop[GTAGS]->flags;
	flags = 0;
	if (debug)
		flags |= PARSER_DEBUG;
	if (wflag)
		flags |= PARSER_WARNING;
	/*
	 * Add tags to GTAGS and GRTAGS.
	 */
	start = strbuf_value(addlist);
	end = start + strbuf_getlen(addlist);
	seqno = 0;
	for (path = start; path < end; path += strlen(path) + 1) {
		gpath_put(path, GPATH_SOURCE);
		data.fid = gpath_path2fid(path, NULL);
		if (data.fid == NULL)
			die("GPATH is corrupted.('%s' not found)", path);
		if (vflag)
			fprintf(stderr, " [%d/%d] extracting tags of %s\n", ++seqno, total, path + 2);
		if (debug)
			fprintf(stderr, "[%s]\n", path + 2);
		parse_file(path, flags, put_syms, &data);
		gtags_flush(data.gtop[GTAGS], data.fid);
		if (data.gtop[GRTAGS] != NULL)
			gtags_flush(data.gtop[GRTAGS], data.fid);
	}
	parser_exit();
	gtags_close(data.gtop[GTAGS]);
	if (data.gtop[GRTAGS] != NULL)
		gtags_close(data.gtop[GRTAGS]);
}
Beispiel #27
0
/**
 * gtags_open: open global tag.
 *
 *	@param[in]	dbpath	dbpath directory
 *	@param[in]	root	root directory (needed when compact format)
 *	@param[in]	db	#GTAGS, #GRTAGS, #GSYMS
 *	@param[in]	mode	#GTAGS_READ: read only <br>
 *			#GTAGS_CREATE: create tag <br>
 *			#GTAGS_MODIFY: modify tag
 *	@param[in]	flags	#GTAGS_COMPACT: compact format
 *	@return		#GTOP structure
 *
 * @note when error occurred, @NAME{gtags_open()} doesn't return.
 */
GTOP *
gtags_open(const char *dbpath, const char *root, int db, int mode, int flags)
{
	GTOP *gtop;
	char tagfile[MAXPATHLEN];
	int dbmode;

	gtop = (GTOP *)check_calloc(sizeof(GTOP), 1);
	gtop->db = db;
	gtop->mode = mode;
	gtop->openflags = flags;
	/*
	 * Open tag file allowing duplicate records.
	 */
	switch (gtop->mode) {
	case GTAGS_READ:
		dbmode = 0;
		break;
	case GTAGS_CREATE:
		dbmode = 1;
		break;
	case GTAGS_MODIFY:
		dbmode = 2;
		break;
	default:
		assert(0);
	}
	/*
	 * GRTAGS and GSYMS are virtual tag file. They are included in a real GRTAGS file.
	 * In fact, GSYMS doesn't exist now.
	 *
	 * GRTAGS:	tags which belongs to GRTAGS, and are defined in GTAGS.
	 * GSYMS:	tags which belongs to GRTAGS, and is not defined in GTAGS.
	 */
	strlimcpy(tagfile, makepath(dbpath, dbname(db == GSYMS ? GRTAGS : db), NULL), sizeof(tagfile));
	gtop->dbop = dbop_open(tagfile, dbmode, 0644, DBOP_DUP|DBOP_SORTED_WRITE);
	if (gtop->dbop == NULL) {
		if (dbmode == 1)
			die("cannot make %s.", dbname(db));
		die("%s not found.", dbname(db));
	}
	if (gtop->mode == GTAGS_READ && db != GTAGS) {
		const char *gtags = makepath(dbpath, dbname(GTAGS), NULL);
		int format_version;

		gtop->gtags = dbop_open(gtags, 0, 0, 0);
		if (gtop->gtags == NULL)
			die("GTAGS not found.");
		format_version = dbop_getversion(gtop->dbop);
		if (format_version > upper_bound_version)
			die("%s seems new format. Please install the latest GLOBAL.", gtags);
		else if (format_version < lower_bound_version)
			die("%s seems older format. Please remake tag files.", gtags);
	}
	if (gtop->mode == GTAGS_CREATE) {
		/*
		 * Decide format.
		 */
		gtop->format = 0;
		gtop->format_version = new_format_version;
		/*
		 * GRTAGS and GSYSM always use compact format.
		 * GTAGS uses compact format only when the -c option specified.
		 */
		if (gtop->db == GRTAGS || gtop->db == GSYMS || gtop->openflags & GTAGS_COMPACT) {
			gtop->format |= GTAGS_COMPACT;
			gtop->format |= GTAGS_COMPLINE;
		} else {
			/* standard format */
			gtop->format |= GTAGS_COMPRESS;
		}
		gtop->format |= GTAGS_COMPNAME;
		if (gtop->format & GTAGS_COMPACT)
			dbop_putoption(gtop->dbop, COMPACTKEY, NULL);
		if (gtop->format & GTAGS_COMPRESS) {
			dbop_putoption(gtop->dbop, COMPRESSKEY, DEFAULT_ABBREVIATION);
			abbrev_open(DEFAULT_ABBREVIATION);
		}
		if (gtop->format & GTAGS_COMPLINE)
			dbop_putoption(gtop->dbop, COMPLINEKEY, NULL);
		if (gtop->format & GTAGS_COMPNAME)
			dbop_putoption(gtop->dbop, COMPNAMEKEY, NULL);
		dbop_putversion(gtop->dbop, gtop->format_version); 
	} else {
		/*
		 * recognize format version of GTAGS. 'format version record'
		 * is saved as a META record in GTAGS and GRTAGS.
		 * if 'format version record' is not found, it's assumed
		 * version 1.
		 */
		const char *p;
		/*
		 * check format version.
		 */
		gtop->format_version = dbop_getversion(gtop->dbop);
		if (gtop->format_version > upper_bound_version)
			die("%s seems new format. Please install the latest GLOBAL.", tagfile);
		else if (gtop->format_version < lower_bound_version)
			die("%s seems older format. Please remake tag files.", tagfile);
		gtop->format = 0;
		if (dbop_getoption(gtop->dbop, COMPACTKEY) != NULL)
			gtop->format |= GTAGS_COMPACT;
		if ((p = dbop_getoption(gtop->dbop, COMPRESSKEY)) != NULL) {
			abbrev_open(p);
			gtop->format |= GTAGS_COMPRESS;
		}
		if (dbop_getoption(gtop->dbop, COMPLINEKEY) != NULL)
			gtop->format |= GTAGS_COMPLINE;
		if (dbop_getoption(gtop->dbop, COMPNAMEKEY) != NULL)
			gtop->format |= GTAGS_COMPNAME;
	}
	if (gpath_open(dbpath, dbmode) < 0) {
		if (dbmode == 1)
			die("cannot create GPATH.");
		else
			die("GPATH not found.");
	}
	if (gtop->mode != GTAGS_READ)
		gtop->sb = strbuf_open(0);	/* This buffer is used for working area. */
	/*
	 * Stuff for compact format.
	 */
	if (gtop->format & GTAGS_COMPACT) {
		assert(root != NULL);
		strlimcpy(gtop->root, root, sizeof(gtop->root));
		if (gtop->mode != GTAGS_READ)
			gtop->path_hash = strhash_open(HASHBUCKETS);
	}
	return gtop;
}
Beispiel #28
0
/**
 * tagsearch: execute tag search
 *
 *	@param[in]	pattern		search pattern
 *	@param[in]	cwd		current directory
 *	@param[in]	root		root of source tree
 *	@param[in]	dbpath		database directory
 *	@param[in]	db		#GTAGS,#GRTAGS,#GSYMS
 */
void
tagsearch(const char *pattern, const char *cwd, const char *root, const char *dbpath, int db)
{
	int count, total = 0;
	char buffer[IDENTLEN], *p = buffer;
	char libdbpath[MAXPATHLEN];

	/*
	 * trim pattern (^<no regex>$ => <no regex>)
	 */
	if (pattern) {
		strlimcpy(p, pattern, sizeof(buffer));
		if (*p++ == '^') {
			char *q = p + strlen(p);
			if (*--q == '$') {
				*q = 0;
				if (*p == 0 || !isregex(p))
					pattern = p;
			}
		}
	}
	/*
	 * search in current source tree.
	 */
	count = search(pattern, root, cwd, dbpath, db);
	total += count;
	/*
	 * search in library path.
	 */
	if (abslib)
		type = PATH_ABSOLUTE;
	if (db == GTAGS && getenv("GTAGSLIBPATH") && (count == 0 || Tflag) && !Sflag) {
		STRBUF *sb = strbuf_open(0);
		char *libdir, *nextp = NULL;

		strbuf_puts(sb, getenv("GTAGSLIBPATH"));
		/*
		 * search for each tree in the library path.
		 */
		for (libdir = strbuf_value(sb); libdir; libdir = nextp) {
			if ((nextp = locatestring(libdir, PATHSEP, MATCH_FIRST)) != NULL)
				*nextp++ = 0;
			if (!gtagsexist(libdir, libdbpath, sizeof(libdbpath), 0))
				continue;
			if (!strcmp(dbpath, libdbpath))
				continue;
			if (!test("f", makepath(libdbpath, dbname(db), NULL)))
				continue;
			/*
			 * search again
			 */
			count = search(pattern, libdir, cwd, libdbpath, db);
			total += count;
			if (count > 0 && !Tflag) {
				/* for verbose message */
				dbpath = libdbpath;
				break;
			}
		}
		strbuf_close(sb);
	}
	if (vflag) {
		print_count(total);
		if (!Tflag)
			fprintf(stderr, " (using '%s')", makepath(dbpath, dbname(db), NULL));
		fputs(".\n", stderr);
	}
}