Files
ResInsight/ThirdParty/Ert/lib/util/path_stack.cpp
Magne Sjaastad 04091ad77d #4266 Update libecl
Use commit 0e1e780fd6f18ce93119061e36a4fca9711bc020

Excluded multibuild folder, as this caused git issues
2019-05-09 08:40:32 +02:00

109 lines
2.8 KiB
C++

/*
Copyright (C) 2012 Equinor ASA, Norway.
The file 'path_stack.c' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <vector>
#include <string>
#include <stack>
#include <ert/util/stringlist.hpp>
#include <ert/util/util.h>
#include <ert/util/path_stack.hpp>
/**
This file implements the structure path_stack which is vaguely
inspired by the emacs-lisp scecial form (save-excursion ...). The
intentiation with the 'class' is to push directories onto a stack,
and then each time you pop from the stack the the process will
chdir() back to directory which is popped.
Observe that the constructor path_stack_alloc() and destructor
path_stack_free() do *not* alter the stack or the cwd of the
process.
*/
struct path_stack_struct {
std::stack<std::string, std::vector<std::string>> stack;
};
/**
This will create a new path_stack instance; it will push anything
on the current stack of paths.
*/
path_stack_type * path_stack_alloc() {
path_stack_type * path_stack = new path_stack_type();
return path_stack;
}
void path_stack_free( path_stack_type * path_stack ) {
delete path_stack;
}
/**
This will push a path on to the stack. The function will start by
chdir() to the input path. If the chdir() call fails the function
will return false, and the stack will be unmodified; if the chdir()
succeeds the input @path will be pushed onto the stack.
If path is NULL that is interpreted as cwd.
*/
bool path_stack_push( path_stack_type * path_stack , const char * path ) {
if (path != NULL)
if (util_chdir( path ) != 0)
return false;
path_stack_push_cwd( path_stack );
return true;
}
void path_stack_push_cwd( path_stack_type * path_stack ) {
char * cwd = util_alloc_cwd();
path_stack->stack.push(cwd);
free(cwd);
}
void path_stack_pop( path_stack_type * path_stack ) {
const std::string& path = path_stack->stack.top();
if (util_chdir( path.c_str() ) != 0)
// The directory has become inaccesible ...
util_abort("%s: could not pop back to directory:%s Error:%s\n", __func__ , path.c_str() , strerror( errno ));
path_stack->stack.pop();
}
int path_stack_size( const path_stack_type * path_stack ) {
return path_stack->stack.size();
}