//
// aegis - project change supervisor
// Copyright (C) 2007-2009, 2012 Peter Miller
//
// This program 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.
//
// This program 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 for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see
// .
//
#include
#include
#include
#include
#include
#include
#include
/**
* The merge_uconf function is used internally by
* user_ty::uconf_get to merge two sets of user
* configuration parameters.
*
* @param curdata
* data set that is operated on
* @param defdata
* default data set. used if some fields in curdata is not filled.
*/
static void
merge_uconf(uconf_ty *data, uconf_ty *tmp)
{
trace(("%s\n", __PRETTY_FUNCTION__));
if (!data->default_project_name && tmp->default_project_name)
{
data->default_project_name = str_copy(tmp->default_project_name);
}
if (!data->default_change_number && tmp->default_change_number)
{
data->default_change_number = tmp->default_change_number;
}
if
(
!data->default_development_directory
&&
tmp->default_development_directory
)
{
data->default_development_directory =
str_copy(tmp->default_development_directory);
}
if (!data->default_project_directory && tmp->default_project_directory)
{
data->default_project_directory =
str_copy(tmp->default_project_directory);
}
if
(
!(data->mask & uconf_delete_file_preference_mask)
&&
(tmp->mask & uconf_delete_file_preference_mask)
)
{
data->delete_file_preference = tmp->delete_file_preference;
data->mask |= uconf_delete_file_preference_mask;
}
if
(
!(data->mask & uconf_pager_preference_mask)
&&
(tmp->mask & uconf_pager_preference_mask)
)
{
data->pager_preference = tmp->pager_preference;
data->mask |= uconf_pager_preference_mask;
}
if
(
!(data->mask & uconf_persevere_preference_mask)
&&
(tmp->mask & uconf_persevere_preference_mask)
)
{
data->persevere_preference = tmp->persevere_preference;
data->mask |= uconf_persevere_preference_mask;
}
if
(
!(data->mask & uconf_log_file_preference_mask)
&&
(tmp->mask & uconf_log_file_preference_mask)
)
{
data->log_file_preference = tmp->log_file_preference;
data->mask |= uconf_log_file_preference_mask;
}
if
(
!(data->mask & uconf_lock_wait_preference_mask)
&&
(tmp->mask & uconf_lock_wait_preference_mask)
)
{
data->lock_wait_preference = tmp->lock_wait_preference;
data->mask |= uconf_lock_wait_preference_mask;
}
if (!data->email_address && tmp->email_address)
{
data->email_address = str_copy(tmp->email_address);
}
if
(
!(data->mask & uconf_whiteout_preference_mask)
&&
(tmp->mask & uconf_whiteout_preference_mask)
)
{
data->whiteout_preference = tmp->whiteout_preference;
data->mask |= uconf_whiteout_preference_mask;
}
if (!data->editor_command && tmp->editor_command)
{
data->editor_command = str_copy(tmp->editor_command);
}
if (!data->visual_command && tmp->visual_command)
{
data->visual_command = str_copy(tmp->visual_command);
}
if (!data->pager_command && tmp->pager_command)
{
data->pager_command = str_copy(tmp->pager_command);
}
//
// Merge the attribute lists.
//
if (tmp->attribute && tmp->attribute->length)
{
if (!data->attribute)
{
data->attribute =
(attributes_list_ty *)attributes_list_type.alloc();
}
for (size_t j = 0; j < tmp->attribute->length; ++j)
{
attributes_ty *ap = tmp->attribute->list[j];
if
(
ap->name
&&
ap->value
&&
!attributes_list_find(data->attribute, ap->name->str_text)
)
{
attributes_list_append
(
data->attribute,
ap->name->str_text,
ap->value->str_text
);
}
}
}
}
static void
read_and_merge(uconf_ty *data, const nstring &filename)
{
trace(("%s\n", __PRETTY_FUNCTION__));
uconf_ty *uconf_new;
//
// Read the file.
//
if (os_readable(filename) == 0)
uconf_new = uconf_read_file(filename);
else
uconf_new = (uconf_ty *)uconf_type.alloc();
//
// Merge the two.
//
merge_uconf(data, uconf_new);
uconf_type.free(uconf_new);
}
static void
fix_default_change(uconf_ty *uconf_data)
{
trace(("%s\n", __PRETTY_FUNCTION__));
if
(
(uconf_data->mask & uconf_default_change_number_mask)
&&
uconf_data->default_change_number == 0
)
uconf_data->default_change_number = MAGIC_ZERO;
}
/**
* The user_uconf_get function is used to
* fetch the "uconf" file for this user,
* caching for future reference.
*
* @param up
* pointer to user structure
* @returns
* pointer to uconf structure in dynamic memory
*/
uconf_ty *
user_uconf_get(user_ty::pointer up)
{
trace(("user_uconf_get(up = %p)\n", up.get()));
return up->uconf_get();
}
uconf_ty *
user_ty::uconf_get()
{
trace(("user_ty::uconf_get(this = %p)\n{\n", this));
lock_sync();
if (!uconf_path)
uconf_path = home + "/.aegisrc";
//
// Read in the user preferences. There are several sources of
// preferences, in the following priority order:
//
// $AEGIS_FLAGS
// $HOME/.aegisrc
// $(datadir)/aegisrc
// $(libdir)/aegisrc
//
if (!uconf_data)
{
//
// read the environment variable
//
uconf_data = (uconf_ty *)parse_env("AEGIS_FLAGS", &uconf_type);
//
// Read the user's $HOME/.aegisrc file.
//
become_begin();
read_and_merge(uconf_data, uconf_path);
//
// read system architecture-neutral file
//
nstring datadir_aegisrc =
nstring::format("%s/aegisrc", configured_datadir());
read_and_merge(uconf_data, datadir_aegisrc);
//
// read system architecture-specific file
//
nstring libdir_aegisrc =
nstring::format("%s/aegisrc", configured_libdir());
read_and_merge(uconf_data, libdir_aegisrc);
become_end();
fix_default_change(uconf_data);
}
trace(("return %p;\n", uconf_data));
trace(("}\n"));
return uconf_data;
}
// vim: set ts=8 sw=4 et :