|  | @@ -181,6 +181,68 @@ bool TryCreateParentDirectory(const string& prefix, const string& filename) {
 | 
	
		
			
				|  |  |    return true;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +// Get the absolute path of this protoc binary.
 | 
	
		
			
				|  |  | +bool GetProtocAbsolutePath(string* path) {
 | 
	
		
			
				|  |  | +#ifdef _WIN32
 | 
	
		
			
				|  |  | +  char buffer[MAX_PATH];
 | 
	
		
			
				|  |  | +  int len = GetModuleFileName(NULL, buffer, MAX_PATH);
 | 
	
		
			
				|  |  | +#else
 | 
	
		
			
				|  |  | +  char buffer[PATH_MAX];
 | 
	
		
			
				|  |  | +  int len = readlink("/proc/self/exe", buffer, PATH_MAX);
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  | +  if (len > 0) {
 | 
	
		
			
				|  |  | +    path->assign(buffer, len);
 | 
	
		
			
				|  |  | +    return true;
 | 
	
		
			
				|  |  | +  } else {
 | 
	
		
			
				|  |  | +    return false;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// Whether a path is where google/protobuf/descriptor.proto and other well-known
 | 
	
		
			
				|  |  | +// type protos are installed.
 | 
	
		
			
				|  |  | +bool IsInstalledProtoPath(const string& path) {
 | 
	
		
			
				|  |  | +  // Checking the descriptor.proto file should be good enough.
 | 
	
		
			
				|  |  | +  string file_path = path + "/google/protobuf/descriptor.proto";
 | 
	
		
			
				|  |  | +  return access(file_path.c_str(), F_OK) != -1;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// Add the paths where google/protobuf/descritor.proto and other well-known
 | 
	
		
			
				|  |  | +// type protos are installed.
 | 
	
		
			
				|  |  | +void AddDefaultProtoPaths(vector<pair<string, string> >* paths) {
 | 
	
		
			
				|  |  | +  // TODO(xiaofeng): The code currently only checks relative paths of where
 | 
	
		
			
				|  |  | +  // the protoc binary is installed. We probably should make it handle more
 | 
	
		
			
				|  |  | +  // cases than that.
 | 
	
		
			
				|  |  | +  string path;
 | 
	
		
			
				|  |  | +  if (!GetProtocAbsolutePath(&path)) {
 | 
	
		
			
				|  |  | +    return;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  // Strip the binary name.
 | 
	
		
			
				|  |  | +  size_t pos = path.find_last_of("/\\");
 | 
	
		
			
				|  |  | +  if (pos == string::npos || pos == 0) {
 | 
	
		
			
				|  |  | +    return;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  path = path.substr(0, pos);
 | 
	
		
			
				|  |  | +  // Check the binary's directory.
 | 
	
		
			
				|  |  | +  if (IsInstalledProtoPath(path)) {
 | 
	
		
			
				|  |  | +    paths->push_back(pair<string, string>("", path));
 | 
	
		
			
				|  |  | +    return;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  // Check if there is an include subdirectory.
 | 
	
		
			
				|  |  | +  if (IsInstalledProtoPath(path + "/include")) {
 | 
	
		
			
				|  |  | +    paths->push_back(pair<string, string>("", path + "/include"));
 | 
	
		
			
				|  |  | +    return;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  // Check if the upper level directory has an "include" subdirectory.
 | 
	
		
			
				|  |  | +  pos = path.find_last_of("/\\");
 | 
	
		
			
				|  |  | +  if (pos == string::npos || pos == 0) {
 | 
	
		
			
				|  |  | +    return;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  path = path.substr(0, pos);
 | 
	
		
			
				|  |  | +  if (IsInstalledProtoPath(path + "/include")) {
 | 
	
		
			
				|  |  | +    paths->push_back(pair<string, string>("", path + "/include"));
 | 
	
		
			
				|  |  | +    return;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  |  }  // namespace
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  // A MultiFileErrorCollector that prints errors to stderr.
 | 
	
	
		
			
				|  | @@ -644,6 +706,8 @@ int CommandLineInterface::Run(int argc, const char* const argv[]) {
 | 
	
		
			
				|  |  |        break;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +  AddDefaultProtoPaths(&proto_path_);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |    // Set up the source tree.
 | 
	
		
			
				|  |  |    DiskSourceTree source_tree;
 | 
	
		
			
				|  |  |    for (int i = 0; i < proto_path_.size(); i++) {
 |