//
// aegis - project change supervisor
// Copyright (C) 2004-2008, 2014 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 .
//
#ifndef AECVSSERVER_MODULE_H
#define AECVSSERVER_MODULE_H
#include
#include
class module_ty; // forward
/**
* The module class is a "smart pointer" to a reference counted
* dynamically allocated module_ty instance.
*/
class module
{
public:
/**
* The destructor.
*
* It is not virtual; thou shalt not derive from this class.
*/
~module();
/**
* The default constructor.
*/
module() : ref(0) { }
/**
* The constructor.
*
* @param arg
* the module_ty instance to be managed. The reference count
* is NOT increaed, it is assumed that you are gibing the smart
* pointer the "dumb" pointer to look after.
*/
module(module_ty *arg);
/**
* The copy constructor.
*/
module(const module &);
/**
* The assignment operator.
*/
module &operator=(const module &);
/**
* This is why it's called a smart pointer: it passes averything to
* the real instance for all the heavy lifting.
*/
inline module_ty *
operator->()
{
return ref;
}
/**
* This is why it's called a smart pointer: it passes averything to
* the real instance for all the heavy lifting.
*/
inline const module_ty *
operator->()
const
{
return ref;
}
/**
* The find class method creates an instance of a suitable module,
* based on the module name. Use module_delete when you are done
* with it.
*
* @param module_name
* The name of the module to search for.
*
* @returns
* A pointer to a module instance.
*/
static module find(string_ty *module_name);
/**
* The find_trim class method creates an instance of a
* suitable module, based on the module name. The module name may
* have a slash and additional path appended to it; this will be
* trimmed before the lookup is performed via module_find. Use
* the reference_count_down method when you are done with it.
*
* @param module_name
* The name of the module to search for; extraneous path will
* be trimmed.
*
* @returns
* A pointer to a module instance.
*/
static module find_trim(string_ty *module_name);
private:
/**
* The ref instance variable is used to remember the memory_ty
* instance being managed.
*/
module_ty *ref;
bool valid() const;
};
struct server_ty; // forward
struct file_info_ty; // forward
/**
* The module class is used to represent an abstract module.
*/
class module_ty
{
protected:
/**
* The destructor.
*
* Not to be called directly. Use the reference_count_down method
* instead.
*/
virtual ~module_ty();
/**
* The default constructor.
*/
module_ty();
public:
/**
* The modified method is used to perform the appropriate actions
* for a "Modified" request.
*
* @param sp
* The server to issue messages and errors to, plus additional
* context if required.
* @param file_name
* The name of the file to operator on. It is relative to the
* base of the named module. It may contain slashes (/).
* @param mode
* The permissions mode of the file.
* @param contents
* An input source from which the contents of the file may be
* read. (You may safely ignore if you want to ignore the file
* contents, what you don't read will be thrown away.)
*/
virtual void modified(server_ty *sp, string_ty *file_name,
file_info_ty *fip, const input::pointer &contents) = 0;
/**
* The is_bogus method is used to ask a module if it feels that it is
* bogus. Such modules return errors for all methods.
*/
virtual bool is_bogus(void) const;
/**
* The name method is used to get the canonical name of the given
* module. DO NOT str_free() the results.
*/
string_ty *name(void);
void reference_count_up();
void reference_count_down();
bool reference_count_valid() const { return (reference_count > 0); }
/**
* The checkout method is used to ask the module to perform the
* appropriate actions for a "co" request.
*
* It actually calls the update method with the appropriate magic
* arguments.
*/
void checkout(server_ty *sp);
/**
* The checkin method is used to ask the module to perform the
* appropriate actions for a "ci" request.
*
* \param sp
* The server which is handling this connection.
* \param client_side
* The client-side name of the file being checked in.
* \param server_side
* The server-side name of the file being checked in.
* \returns
* bool; false if unsuccessful, true if successful.
*/
virtual bool checkin(server_ty *sp, string_ty *client_side,
string_ty *server_side) = 0;
struct options
{
~options();
options();
options(const options &);
options &operator=(const options &);
int A; // Reset any sticky tags/date/kopts.
int C; // Overwrite locally modified files with clean
// repository copies.
string_ty *D; // Set date to update from (is sticky).
int d; // Build directories, like checkout does.
int f; // Force a head revision match if tag/date not
// found.
string_ty *I; // More files to ignore (! to reset).
string_ty *j; // Merge in changes made between current revision
// and rev.
string_ty *k; // Use RCS kopt -k option on checkout. (is sticky)
int l; // Local directory only, no recursion.
string_ty *m; // Message to add to file or transction.
int P; // Prune empty directories.
int p; // Send updates to standard output (avoids
// stickiness).
int R; // Process directories recursively.
string_ty *r; // Update using specified revision/tag (is sticky).
string_ty *W; // Wrappers specification line.
};
/**
* The update method is used to ask the module to perform the
* appropriate actions for an "update" request.
*
* \param sp
* The server which is handling this connection.
* \param client_side
* The client-side name of the file or directory being updated.
* \param server_side
* The server-side name of the file or directory being updated.
* \param opt
* Options specified for this request.
* \returns
* bool; false if unsuccessful, true if successful.
*/
virtual bool update(server_ty *sp, string_ty *client_side,
string_ty *server_side, const options &opt) = 0;
/**
* The add method is used to ask the module to perform the
* appropriate actions for an "add" request.
*
* \param sp
* The server which is handling this connection.
* \param client_side
* The client-side name of the file or directory being added.
* \param server_side
* The server-side name of the file or directory being added.
* \param opt
* Options specified for this request.
* \returns
* bool; false if unsuccessful, true is successful.
*/
virtual bool add(server_ty *sp, string_ty *client_side,
string_ty *server_side, const options &opt) = 0;
/**
* The remove method is used to ask the module to perform the
* appropriate actions for an "remove" request.
*
* \param sp
* The server which is handling this connection.
* \param client_side
* The client-side name of the file or directory being removed.
* \param server_side
* The server-side name of the file or directory being removed.
* \param opt
* Options specified for this request.
* \returns
* zero (false) if unsuccessful, non-zero (true) is successful.
*/
virtual bool remove(server_ty *sp, string_ty *client_side,
string_ty *server_side, const options &opt) = 0;
protected:
/**
* The name method is used to get the canonical name of the given
* module. DO NOT str_free() the results.
*/
virtual string_ty *calculate_canonical_name() const = 0;
private:
/**
* The reference_count instance variable is used to remember
*/
int reference_count;
/**
* The canonical_name instance variable is used to remember
*/
string_ty *canonical_name;
/**
* The copy constructor. Do not use.
*/
module_ty(const module_ty &);
/**
* The assignment operator. Do not use.
*/
module_ty &operator=(const module_ty &);
};
/**
* The is_update_prefix function is used to determine if a file
* is a candidate for update.
*
* \param above
* The server relative name of a file or directory listed on the
* update command line.
* \param below
* The server relative name of a file or directory to be tested to
* determine if it is an update candidate.
* \param deep
* True if all files in all directories below the directory are
* candidates, and false if only files immeditately within the
* directoiry are candidates.
*/
bool is_update_prefix(string_ty *above, string_ty *below, bool deep);
#endif // AECVSSERVER_MODULE_H
// vim: set ts=8 sw=4 et :