anope

- supernets anope source code & configuration
git clone git://git.acid.vegas/anope.git
Log | Files | Refs | Archive | README

version.cpp (4037B)

      1 /* Build bumper
      2  *
      3  * (C) 2003-2022 Anope Team
      4  * Contact us at team@anope.org
      5  *
      6  * Please read COPYING and README for further details.
      7  *
      8  * Based on the original code of Epona by Lara.
      9  * Based on the original code of Services by Andy Church.
     10  */
     11 
     12 #include <cstdlib>
     13 #include <iostream>
     14 #include <fstream>
     15 #include <sstream>
     16 #include <map>
     17 
     18 static std::string get_git_hash(const std::string &git_dir)
     19 {
     20 	std::fstream fd;
     21 	std::string filebuf;
     22 
     23 	fd.open((git_dir + "/HEAD").c_str(), std::ios::in);
     24 	if (!fd.is_open())
     25 		return "";
     26 	if (!getline(fd, filebuf) || filebuf.find("ref: ") != 0)
     27 	{
     28 		fd.close();
     29 		return "";
     30 	}
     31 
     32 	fd.close();
     33 
     34 	filebuf = filebuf.substr(5);
     35 	fd.open((git_dir + "/" + filebuf).c_str(), std::ios::in);
     36 	if (!fd.is_open())
     37 		return "";
     38 	if (!getline(fd, filebuf))
     39 	{
     40 		fd.close();
     41 		return "";
     42 	}
     43 	fd.close();
     44 
     45 	return "g" + filebuf.substr(0, 7);
     46 }
     47 
     48 static bool read_version_sh(const std::string &version_sh, std::map<std::string, std::string> &versions)
     49 {
     50 	std::fstream fd(version_sh.c_str(), std::ios::in);
     51 	if (!fd.is_open())
     52 	{
     53 		std::cerr << "Error: Unable to open src/version.sh for reading: " << version_sh << std::endl;
     54 		return false;
     55 	}
     56 
     57 	std::string filebuf;
     58 	while (getline(fd, filebuf))
     59 	{
     60 		if (!filebuf.find("VERSION_"))
     61 		{
     62 			size_t eq = filebuf.find('=');
     63 
     64 			std::string type = filebuf.substr(0, eq);
     65 			std::string value = filebuf.substr(eq + 1);
     66 
     67 			versions[type] = value;
     68 		}
     69 	}
     70 
     71 	fd.close();
     72 
     73 	return true;
     74 }
     75 
     76 static bool write_build_h(const std::string &buildh, const std::string &git_version)
     77 {
     78 	std::fstream fd(buildh.c_str(), std::ios::in);
     79 
     80 	std::string build = "#define BUILD	1";
     81 	if (fd.is_open())
     82 	{
     83 		for (std::string filebuf; getline(fd, filebuf);)
     84 		{
     85 			if (!filebuf.find("#define BUILD"))
     86 			{
     87 				size_t tab = filebuf.find('	');
     88 
     89 				int ibuild = atoi(filebuf.substr(tab + 1).c_str()) + 1;
     90 
     91 				std::stringstream ss;
     92 				ss << "#define BUILD	" << ibuild;
     93 				build = ss.str();
     94 			}
     95 		}
     96 
     97 		fd.close();
     98 	}
     99 
    100 	fd.clear();
    101 	fd.open(buildh.c_str(), std::ios::out);
    102 	if (!fd.is_open())
    103 	{
    104 		std::cerr << "Error: Unable to open build.h for writing: " << buildh << std::endl;
    105 		return false;
    106 	}
    107 
    108 	fd << "/* This file is automatically generated by version.cpp - do not edit it! */" << std::endl;
    109 	fd << build << std::endl;
    110 	if (!git_version.empty())
    111 		fd << "#define VERSION_GIT \"" << git_version << "\"" << std::endl;
    112 	fd.close();
    113 
    114 	return true;
    115 }
    116 
    117 static void read_version_h(const std::string &versionh, std::map<std::string, std::string> &versions)
    118 {
    119 	std::fstream fd(versionh.c_str(), std::ios::in);
    120 
    121 	if (!fd.is_open())
    122 		return;
    123 
    124 	for (std::string filebuf; getline(fd, filebuf);)
    125 	{
    126 		if (!filebuf.find("#define VERSION_"))
    127 		{
    128 			size_t space = filebuf.substr(8).find(' ');
    129 
    130 			std::string name = filebuf.substr(8).substr(0, space),
    131 				version = filebuf.substr(8).substr(space + 1);
    132 
    133 			versions[name] = version;
    134 		}
    135 	}
    136 
    137 	fd.close();
    138 }
    139 
    140 static bool write_version_h(const std::string &versionh, const std::map<std::string, std::string> &versions)
    141 {
    142 	std::fstream fd(versionh.c_str(), std::ios::out);
    143 
    144 	if (!fd.is_open())
    145 		return false;
    146 
    147 	for (std::map<std::string, std::string>::const_iterator it = versions.begin(); it != versions.end(); ++it)
    148 	{
    149 		fd << "#define " << it->first << " " << it->second << std::endl;
    150 	}
    151 
    152 	fd.close();
    153 
    154 	return true;
    155 }
    156 
    157 int main(int argc, char *argv[])
    158 {
    159 	if (argc < 4)
    160 	{
    161 		std::cerr << "Syntax: " << argv[0] << " <base> <version.h> <build.h>" << std::endl;
    162 		return 1;
    163 	}
    164 
    165 	std::string version_sh = std::string(argv[1]) + "/src/version.sh";
    166 	std::string git_dir = std::string(argv[1]) + "/.git";
    167 	std::string versionh = argv[2];
    168 	std::string buildh = argv[3];
    169 
    170 	std::map<std::string, std::string> versions, old_versions;
    171 
    172 	if (!read_version_sh(version_sh, versions))
    173 		return -1;
    174 
    175 	std::string git_version = get_git_hash(git_dir);
    176 	if (!write_build_h(buildh, git_version))
    177 		return -1;
    178 
    179 	read_version_h(versionh, old_versions);
    180 
    181 	if (versions == old_versions)
    182 		return 0;
    183 
    184 	if (!write_version_h(versionh, versions))
    185 		return -1;
    186 
    187 	return 0;
    188 }