mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
122 lines
3.5 KiB
C
122 lines
3.5 KiB
C
/*
|
|
Copyright (C) 2012 Statoil 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 <ert/util/stringlist.h>
|
|
#include <ert/util/util.h>
|
|
#include <ert/util/path_stack.h>
|
|
|
|
/**
|
|
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 {
|
|
stringlist_type * stack;
|
|
stringlist_type * storage;
|
|
};
|
|
|
|
|
|
/**
|
|
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 = (path_stack_type*)util_malloc( sizeof * path_stack );
|
|
path_stack->stack = stringlist_alloc_new();
|
|
path_stack->storage = stringlist_alloc_new();
|
|
return path_stack;
|
|
}
|
|
|
|
/*
|
|
This will destroy the storage taken by the current path_stack
|
|
instance. This function will NOT pop any elements off the stack; so
|
|
if you have not manully clerad the stack with the right number of
|
|
path_stack_pop() calls, you will (probably) destroy the path stack
|
|
instance with an incorrect value of cwd.
|
|
*/
|
|
|
|
void path_stack_free( path_stack_type * path_stack ) {
|
|
stringlist_free( path_stack->stack );
|
|
stringlist_free( path_stack->storage );
|
|
free( 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();
|
|
stringlist_append_owned_ref( path_stack->storage , cwd);
|
|
stringlist_append_ref( path_stack->stack , cwd );
|
|
}
|
|
|
|
const char * path_stack_pop( path_stack_type * path_stack ) {
|
|
char * path = stringlist_pop( path_stack->stack );
|
|
if (util_chdir( path ) == 0)
|
|
return path;
|
|
else {
|
|
// The directory has become inaccesible ...
|
|
util_abort("%s: could not pop back to directory:%s Error:%s\n", __func__ , path , strerror( errno ));
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
|
|
int path_stack_size( const path_stack_type * path_stack ) {
|
|
return stringlist_get_size( path_stack->stack );
|
|
}
|
|
|
|
|
|
const char * path_stack_peek( const path_stack_type * path_stack ) {
|
|
return stringlist_get_last( path_stack->stack );
|
|
}
|
|
|