Add documentation for `config`, `dyn_array`, `error`, and `string_buf`.
parent
16e971af0b
commit
7cc11c86e3
|
@ -1,5 +1,6 @@
|
||||||
.cache/
|
.cache/
|
||||||
.direnv/
|
.direnv/
|
||||||
compile_commands.json
|
|
||||||
bootstrap
|
bootstrap
|
||||||
|
compile_commands.json
|
||||||
|
docs/
|
||||||
test/runner
|
test/runner
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
TODO:
|
TODO:
|
||||||
- [ ] Add documentation throughout (ownership, docstrings, etc.).
|
- [ ] Add documentation throughout (ownership, docstrings, etc.).
|
||||||
|
- [ ] Add evaluator tests.
|
||||||
|
- [ ] Color output to console.
|
||||||
|
|
||||||
CLI utility for initializing projects in reproducible ways.
|
CLI utility for initializing projects in reproducible ways.
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
bear
|
bear
|
||||||
clang-tools
|
clang-tools
|
||||||
codelldb
|
codelldb
|
||||||
|
doxygen
|
||||||
];
|
];
|
||||||
buildInputs = with pkgs; [
|
buildInputs = with pkgs; [
|
||||||
ncurses
|
ncurses
|
||||||
|
|
|
@ -1,27 +1,59 @@
|
||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief A `spec` configuration.
|
||||||
|
*/
|
||||||
#ifndef _BOOTSTRAP_CONFIG_H
|
#ifndef _BOOTSTRAP_CONFIG_H
|
||||||
#define _BOOTSTRAP_CONFIG_H
|
#define _BOOTSTRAP_CONFIG_H
|
||||||
|
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief A collection of parameters that identify a `spec`.
|
||||||
|
|
||||||
|
Each member of the @ref Config is expected to outlive the @ref Config instance
|
||||||
|
itself.
|
||||||
|
*/
|
||||||
struct Config {
|
struct Config {
|
||||||
// The directory the `bootstrap` command was run from.
|
/// The directory the `bootstrap` command was run from. Does not take
|
||||||
// OWNERSHIP: Does not own this pointer.
|
/// ownership of this pointer.
|
||||||
const char *cwd;
|
const char *cwd;
|
||||||
// The root directory housing our specs.
|
/// The root directory housing our specs. Does not take ownership of this
|
||||||
// OWNERSHIP: Does not own this pointer.
|
/// pointer.
|
||||||
const char *root_dir;
|
const char *root_dir;
|
||||||
// The name of the spec we want to bootstrap.
|
/// The name of the spec we want to bootstrap. Does not take ownership of
|
||||||
// OWNERSHIP: Does not own this pointer.
|
/// this pointer.
|
||||||
const char *target;
|
const char *target;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Error *config_load(
|
/**
|
||||||
|
@brief Create a new @ref Config instance.
|
||||||
|
|
||||||
|
@param cwd
|
||||||
|
The current working directory the `bootstrap` command was invoked from.
|
||||||
|
@param root_dir
|
||||||
|
An absolute path to the collection of specs `bootstrap` will search through.
|
||||||
|
@param target
|
||||||
|
The `spec` that should be bootstrapped.
|
||||||
|
@return
|
||||||
|
A new @ref Config instance. The caller takes ownership of this value.
|
||||||
|
|
||||||
|
@see config_free
|
||||||
|
*/
|
||||||
|
struct Error *config_new(
|
||||||
const char *cwd,
|
const char *cwd,
|
||||||
const char *root_dir,
|
const char *root_dir,
|
||||||
const char *target,
|
const char *target,
|
||||||
struct Config **config
|
struct Config **config
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief Deallocates a previously allocated @ref Config instance.
|
||||||
|
|
||||||
|
@param config
|
||||||
|
A pointer to a @ref Config instance. If null, this function is a no-op.
|
||||||
|
|
||||||
|
@see config_new
|
||||||
|
*/
|
||||||
void config_free(struct Config *config);
|
void config_free(struct Config *config);
|
||||||
|
|
||||||
#endif /* BOOTSTRAP_CONFIG_H */
|
#endif /* BOOTSTRAP_CONFIG_H */
|
||||||
|
|
|
@ -1,22 +1,72 @@
|
||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Dynamic `void*` arrays.
|
||||||
|
*/
|
||||||
#ifndef _BOOTSTRAP_DYN_ARRAY_H
|
#ifndef _BOOTSTRAP_DYN_ARRAY_H
|
||||||
#define _BOOTSTRAP_DYN_ARRAY_H
|
#define _BOOTSTRAP_DYN_ARRAY_H
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief A dynamic array of generic pointers.
|
||||||
|
|
||||||
|
A `void*` wrapper that grows larger as needed. If more space is needed during an
|
||||||
|
append operation, the capacity of the internal array is doubled.
|
||||||
|
*/
|
||||||
struct DynArray {
|
struct DynArray {
|
||||||
|
/// The underlying `void*` pointer.
|
||||||
void **buf;
|
void **buf;
|
||||||
// The size of @buf excluding `NUL`.
|
/// The size of @ref DynArray.buf.
|
||||||
size_t size;
|
size_t size;
|
||||||
// The allocated size of @buf including `NUL`.
|
// The allocated size of @ref DynArray.buf.
|
||||||
size_t _capacity;
|
size_t _capacity;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief Create a new @ref DynArray instance.
|
||||||
|
|
||||||
|
@param capacity
|
||||||
|
The initial size of the internal array. To avoid too many reallocations, aim to
|
||||||
|
make this value large enough to accommodate the eventual size of the buffer.
|
||||||
|
|
||||||
|
@see dyn_array_free
|
||||||
|
*/
|
||||||
struct DynArray *dyn_array_new(size_t capacity);
|
struct DynArray *dyn_array_new(size_t capacity);
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief Returns the number of items contained in the internal buffer.
|
||||||
|
|
||||||
|
@param a
|
||||||
|
A valid pointer to a @ref DynArray instance.
|
||||||
|
@return
|
||||||
|
The number of items contained in the internal buffer.
|
||||||
|
*/
|
||||||
size_t dyn_array_size(struct DynArray *a);
|
size_t dyn_array_size(struct DynArray *a);
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief Appends a new item onto the end of the internal @ref DynArray.buf.
|
||||||
|
|
||||||
|
This function takes ownership of @p item and will attempt to `free` the
|
||||||
|
parameter when the @ref DynArray is `free`'d. For this reason, only provide
|
||||||
|
entries that have been allocated on the heap.
|
||||||
|
|
||||||
|
@param a
|
||||||
|
A valid pointer to a @ref DynArray instance.
|
||||||
|
@param item
|
||||||
|
A valid pointer to a heap-allocated object.
|
||||||
|
|
||||||
|
@see dyn_array_free
|
||||||
|
*/
|
||||||
void dyn_array_push(struct DynArray *a, void *item);
|
void dyn_array_push(struct DynArray *a, void *item);
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief Deallocates a previously allocated @ref DynArray instance.
|
||||||
|
|
||||||
|
@param a
|
||||||
|
A pointer to a @ref DynArray instance. If null, this function is a no-op.
|
||||||
|
|
||||||
|
@see dyn_array_new
|
||||||
|
*/
|
||||||
void dyn_array_free(struct DynArray *a);
|
void dyn_array_free(struct DynArray *a);
|
||||||
|
|
||||||
#endif /* _BOOTSTRAP_DYN_ARRAY_H */
|
#endif /* _BOOTSTRAP_DYN_ARRAY_H */
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Error handling.
|
||||||
|
*/
|
||||||
#ifndef _BOOTSTRAP_ERROR_H
|
#ifndef _BOOTSTRAP_ERROR_H
|
||||||
#define _BOOTSTRAP_ERROR_H
|
#define _BOOTSTRAP_ERROR_H
|
||||||
|
|
||||||
|
@ -5,27 +9,55 @@
|
||||||
|
|
||||||
#include "string_buf.h"
|
#include "string_buf.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief The various error codes produced by `bootstrap`.
|
||||||
|
*/
|
||||||
enum ErrorCode {
|
enum ErrorCode {
|
||||||
|
/// Could not retrieve the value of `$CWD`.
|
||||||
ERROR_CONFIG_ENV_CWD_INVALID = 1,
|
ERROR_CONFIG_ENV_CWD_INVALID = 1,
|
||||||
|
/// No root directory was specified. This must either be set via the command
|
||||||
|
/// line flag `-d` or environment variable `$BOOTSTRAP_ROOT_DIR`. If both are
|
||||||
|
/// provided, the command line flag takes priority.
|
||||||
ERROR_CONFIG_ENV_ROOT_DIR_INVALID,
|
ERROR_CONFIG_ENV_ROOT_DIR_INVALID,
|
||||||
|
/// There is no file at the location corresponding to the specified spec.
|
||||||
ERROR_CONFIG_TARGET_NOT_FOUND,
|
ERROR_CONFIG_TARGET_NOT_FOUND,
|
||||||
|
/// For generic reasons, `bootstrap` could not access the file at the provided
|
||||||
|
/// spec.
|
||||||
ERROR_CONFIG_TARGET_INVALID,
|
ERROR_CONFIG_TARGET_INVALID,
|
||||||
|
/// The file at the location corresponding to the provided spec is not a
|
||||||
|
/// directory.
|
||||||
ERROR_CONFIG_TARGET_NOT_DIR,
|
ERROR_CONFIG_TARGET_NOT_DIR,
|
||||||
|
|
||||||
|
/// For generic reasons, `bootstrap` could not access the `spec.json` file.
|
||||||
ERROR_PARSER_SPEC_JSON_INVALID,
|
ERROR_PARSER_SPEC_JSON_INVALID,
|
||||||
|
/// The `spec.json` file is not valid JSON.
|
||||||
ERROR_PARSER_SPEC_JSON_INVALID_SYNTAX,
|
ERROR_PARSER_SPEC_JSON_INVALID_SYNTAX,
|
||||||
|
|
||||||
|
/// The top-level JSON object of the `spec.json` file is not an object.
|
||||||
ERROR_VALIDATOR_TOP_LEVEL_NOT_OBJECT,
|
ERROR_VALIDATOR_TOP_LEVEL_NOT_OBJECT,
|
||||||
|
/// A field in `spec.json` is not an object.
|
||||||
ERROR_VALIDATOR_FIELD_NOT_OBJECT,
|
ERROR_VALIDATOR_FIELD_NOT_OBJECT,
|
||||||
|
/// The `type` of a `spec.json` field is not a string.
|
||||||
ERROR_VALIDATOR_FIELD_TYPE_INVALID,
|
ERROR_VALIDATOR_FIELD_TYPE_INVALID,
|
||||||
|
/// The `type` of a `spec.json` field does not correspond to a known prompt
|
||||||
|
/// type.
|
||||||
ERROR_VALIDATOR_FIELD_TYPE_UNKNOWN,
|
ERROR_VALIDATOR_FIELD_TYPE_UNKNOWN,
|
||||||
|
/// The `prompt` of a `spec.json` field is not a string.
|
||||||
ERROR_VALIDATOR_FIELD_PROMPT_INVALID,
|
ERROR_VALIDATOR_FIELD_PROMPT_INVALID,
|
||||||
|
|
||||||
|
/// The `run.sh` file could not be found.
|
||||||
ERROR_EVALUATOR_RUN_SH_NOT_FOUND,
|
ERROR_EVALUATOR_RUN_SH_NOT_FOUND,
|
||||||
|
/// The `run.sh` file is not executable.
|
||||||
ERROR_EVALUATOR_RUN_SH_NOT_EXEC,
|
ERROR_EVALUATOR_RUN_SH_NOT_EXEC,
|
||||||
|
/// A user response to a prompt is not valid.
|
||||||
ERROR_EVALUATOR_RESPONSE_INVALID,
|
ERROR_EVALUATOR_RESPONSE_INVALID,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief A `bootstrap` error.
|
||||||
|
|
||||||
|
@see ERROR_NEW
|
||||||
|
*/
|
||||||
struct Error {
|
struct Error {
|
||||||
enum ErrorCode code;
|
enum ErrorCode code;
|
||||||
const char *message;
|
const char *message;
|
||||||
|
@ -47,10 +79,13 @@ static inline struct Error *priv_error_new(
|
||||||
// clang-format off
|
// clang-format off
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Return the number of elements of `__VA_ARGS__`.
|
@brief Return the number of elements of `__VA_ARGS__`.
|
||||||
|
|
||||||
Take the `__VA_ARGS__` list and append a list of decreasing numbers
|
Take the `__VA_ARGS__` list and append a list of decreasing numbers
|
||||||
31, 30, ..., 0. Then, by using ALEN0, return the 31st element of that list.
|
31, 30, ..., 0.
|
||||||
|
|
||||||
|
@return
|
||||||
|
The number of elements of `__VA_ARGS__`.
|
||||||
*/
|
*/
|
||||||
#define ALEN(...) \
|
#define ALEN(...) \
|
||||||
ALEN0( \
|
ALEN0( \
|
||||||
|
@ -68,7 +103,17 @@ Take the `__VA_ARGS__` list and append a list of decreasing numbers
|
||||||
...) _1F
|
...) _1F
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Create a new `struct Error` instance.
|
@brief Creates a new @ref Error instance.
|
||||||
|
|
||||||
|
It is the responsibility of the caller to free the @ref Error instance.
|
||||||
|
|
||||||
|
@param __VA_ARGS__
|
||||||
|
Allows supplying up to 31 `const char*` instances. These arguments will be
|
||||||
|
concatenated together and supplied to the new @ref Error instance.
|
||||||
|
@return
|
||||||
|
A new @ref Error instance. The caller takes ownership of this value.
|
||||||
|
|
||||||
|
@see error_free
|
||||||
*/
|
*/
|
||||||
#define ERROR_NEW(code, ...) \
|
#define ERROR_NEW(code, ...) \
|
||||||
ERROR_NEW0(code, ALEN(__VA_ARGS__), __VA_ARGS__)
|
ERROR_NEW0(code, ALEN(__VA_ARGS__), __VA_ARGS__)
|
||||||
|
@ -80,6 +125,14 @@ Create a new `struct Error` instance.
|
||||||
|
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief Deallocates a previously allocated @ref Error isntance.
|
||||||
|
|
||||||
|
@param error
|
||||||
|
A pointer to a @ref Error instance. If null, this function is a no-op.
|
||||||
|
|
||||||
|
@see ERROR_NEW
|
||||||
|
*/
|
||||||
void error_free(struct Error *error);
|
void error_free(struct Error *error);
|
||||||
|
|
||||||
#endif /* _BOOTSTRAP_ERROR_H */
|
#endif /* _BOOTSTRAP_ERROR_H */
|
||||||
|
|
|
@ -1,101 +1,99 @@
|
||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Dynamic character arrays.
|
||||||
|
*/
|
||||||
#ifndef _BOOTSTRAP_STRING_BUF_H
|
#ifndef _BOOTSTRAP_STRING_BUF_H
|
||||||
#define _BOOTSTRAP_STRING_BUF_H
|
#define _BOOTSTRAP_STRING_BUF_H
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief A dynamic character array.
|
@brief A dynamic character array.
|
||||||
*
|
|
||||||
* A `char*` wrapper. Appending `char`s or NUL-terminated strings allocates
|
A `char*` wrapper that grows larger as needed. Supports appending individual
|
||||||
* additional space as needed.
|
`char`s or NUL-terminated strings. If more space is needed during an append
|
||||||
|
operation, the capacity is doubled repeatedly until the requested data fits.
|
||||||
*/
|
*/
|
||||||
struct StringBuf {
|
struct StringBuf {
|
||||||
|
/// The underlying `char*` pointer.
|
||||||
char *buf;
|
char *buf;
|
||||||
// The length of @buf excluding `NUL`.
|
/// The size of @ref StringBuf.buf (excluding the `NUL` character).
|
||||||
size_t size;
|
size_t size;
|
||||||
// The allocated size of @buf including `NUL`.
|
/// The allocated size of @ref StringBuf.buf (including the `NUL` character).
|
||||||
size_t _capacity;
|
size_t _capacity;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new `StringBuf` instance.
|
@brief Create a new @ref StringBuf instance.
|
||||||
*
|
|
||||||
* @param capacity
|
@param capacity
|
||||||
* The initial size of the internal array (including the trailing `NUL`
|
The initial size of the internal array (including the trailing `NUL`
|
||||||
* character). To avoid too many reallocations, aim to make this value large
|
character). To avoid too many reallocations, aim to make this value large
|
||||||
* enough to accommodate the size the string is expected to eventually take.
|
enough to accommodate the eventual size of the desired string.
|
||||||
* @return
|
@return
|
||||||
* A new `StringBuf` instance. The caller takes ownership of this value.
|
A new @ref StringBuf instance. The caller takes ownership of this value.
|
||||||
*
|
|
||||||
* @see string_buf_free
|
@see string_buf_free
|
||||||
*/
|
*/
|
||||||
struct StringBuf *string_buf_new(size_t capacity);
|
struct StringBuf *string_buf_new(size_t capacity);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the number of characters contained in the internal buffer.
|
@brief Returns the number of characters contained in the internal buffer
|
||||||
*
|
(excluding the NUL character).
|
||||||
* @param sb
|
|
||||||
* A valid pointer to a `StringBuf` instance.
|
@param sb
|
||||||
* @return
|
A valid pointer to a @ref StringBuf instance.
|
||||||
* The number of characters contained in the internal buffer.
|
@return
|
||||||
|
The number of characters contained in the internal buffer.
|
||||||
*/
|
*/
|
||||||
size_t string_buf_size(struct StringBuf *sb);
|
size_t string_buf_size(struct StringBuf *sb);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the internal `NUL`-terminated string buffer.
|
@brief Appends a character to the end of the provided @ref StringBuf.
|
||||||
*
|
|
||||||
* @param sb
|
|
||||||
* A valid pointer to a `StringBuf` instance.
|
|
||||||
* @return
|
|
||||||
* The internally managed string.
|
|
||||||
*/
|
|
||||||
const char *string_buf_value(struct StringBuf *sb);
|
|
||||||
|
|
||||||
/**
|
If appending would cause the internal buffer to overflow, doubles the capacity
|
||||||
* Append a character to the end of a `StringBuf`.
|
of the internal array to accommodate.
|
||||||
*
|
|
||||||
* If appending would cause the internal buffer to overflow, reallocates the
|
@param sb
|
||||||
* internal array to accommodate.
|
A valid pointer to a @ref StringBuf instance.
|
||||||
*
|
@param c
|
||||||
* @param sb
|
The `char` to append to the end of @p sb.
|
||||||
* A valid pointer to a `StringBuf` instance.
|
|
||||||
* @param c
|
|
||||||
* The `char` to append to the end of `sb`.
|
|
||||||
*/
|
*/
|
||||||
void string_buf_cappend(struct StringBuf *sb, char c);
|
void string_buf_cappend(struct StringBuf *sb, char c);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Append a `NUL`-terminated string to the end of a `StringBuf`.
|
@brief Appends a NUL-terminated string to the end of a @ref StringBuf.
|
||||||
*
|
|
||||||
* If appending would cause the internal buffer to overflow, `realloc`s are
|
If appending would cause the internal buffer to overflow, doubles the capacity
|
||||||
* performed internally to accommodate.
|
of the internal array the necessary number of times to accommodate.
|
||||||
*
|
|
||||||
* @param sb
|
@param sb
|
||||||
* A valid pointer to a `StringBuf` instance.
|
A valid pointer to a @ref StringBuf instance.
|
||||||
* @param s
|
@param s
|
||||||
* The `char*` to append to the end of `sb`.
|
The `char*` to append to the end of @p sb.
|
||||||
*/
|
*/
|
||||||
void string_buf_sappend(struct StringBuf *sb, const char s[static 1]);
|
void string_buf_sappend(struct StringBuf *sb, const char s[static 1]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert a `StringBuf` instance into a `char*`.
|
@brief Converts a @ref StringBuf instance into a `char*`.
|
||||||
*
|
|
||||||
* @param sb
|
This function frees the memory associated with @p sb.
|
||||||
* A valid pointer to a `StringBuf` instance.
|
|
||||||
* @return
|
@param sb
|
||||||
* A null pointer if `sb` is null. Otherwise a `NUL`-terminated string
|
A valid pointer to a @ref StringBuf instance.
|
||||||
* corresponding to the value of `sb`. The caller takes ownership of this
|
@return
|
||||||
* value.
|
A null pointer if @p sb is null. Otherwise a NUL-terminated string
|
||||||
|
corresponding to the value of @p sb. The caller takes ownership of this value.
|
||||||
*/
|
*/
|
||||||
const char *string_buf_convert(struct StringBuf *sb);
|
const char *string_buf_convert(struct StringBuf *sb);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deallocate a previously allocated `StringBuf` instance.
|
@brief Deallocates a previously allocated @ref StringBuf instance.
|
||||||
*
|
|
||||||
* @param sb
|
@param sb
|
||||||
* A valid pointer to a `StringBuf` instance.
|
A pointer to a @ref StringBuf instance. If null, this function is a no-op.
|
||||||
*
|
|
||||||
* @see string_buf_new
|
@see string_buf_new
|
||||||
*/
|
*/
|
||||||
void string_buf_free(struct StringBuf *sb);
|
void string_buf_free(struct StringBuf *sb);
|
||||||
|
|
||||||
|
|
2
main.c
2
main.c
|
@ -21,7 +21,7 @@ static int run(const char *root_dir, const char *target) {
|
||||||
struct Error *error = 0;
|
struct Error *error = 0;
|
||||||
struct Config *config = 0;
|
struct Config *config = 0;
|
||||||
|
|
||||||
if ((error = config_load(cwd, root_dir, target, &config))) {
|
if ((error = config_new(cwd, root_dir, target, &config))) {
|
||||||
fprintf(stderr, "%s", error->message);
|
fprintf(stderr, "%s", error->message);
|
||||||
goto cleanup_cwd;
|
goto cleanup_cwd;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
#include "path.h"
|
#include "path.h"
|
||||||
|
|
||||||
struct Error *config_load(
|
struct Error *config_new(
|
||||||
const char *cwd,
|
const char *cwd,
|
||||||
const char *root_dir,
|
const char *root_dir,
|
||||||
const char *target,
|
const char *target,
|
||||||
|
|
|
@ -18,6 +18,7 @@ size_t dyn_array_size(struct DynArray *a) {
|
||||||
|
|
||||||
void dyn_array_push(struct DynArray *a, void *item) {
|
void dyn_array_push(struct DynArray *a, void *item) {
|
||||||
assert(a);
|
assert(a);
|
||||||
|
assert(item);
|
||||||
if (a->size == a->_capacity) {
|
if (a->size == a->_capacity) {
|
||||||
a->_capacity *= 2;
|
a->_capacity *= 2;
|
||||||
a->buf = realloc(a->buf, sizeof(void *) * a->_capacity);
|
a->buf = realloc(a->buf, sizeof(void *) * a->_capacity);
|
||||||
|
|
|
@ -10,10 +10,10 @@ int main(int argc, char *argv[]) {
|
||||||
sput_start_testing();
|
sput_start_testing();
|
||||||
|
|
||||||
sput_enter_suite("config");
|
sput_enter_suite("config");
|
||||||
sput_run_test(test_config_load_invalid_args);
|
sput_run_test(test_config_new_invalid_args);
|
||||||
sput_run_test(test_config_load_spec_not_found);
|
sput_run_test(test_config_new_spec_not_found);
|
||||||
sput_run_test(test_config_load_spec_not_dir);
|
sput_run_test(test_config_new_spec_not_dir);
|
||||||
sput_run_test(test_config_load_success);
|
sput_run_test(test_config_new_success);
|
||||||
|
|
||||||
sput_enter_suite("dyn_array");
|
sput_enter_suite("dyn_array");
|
||||||
sput_run_test(test_dyn_array_zero_capacity);
|
sput_run_test(test_dyn_array_zero_capacity);
|
||||||
|
|
|
@ -33,16 +33,16 @@ static void test_config_teardown(struct TestConfigFixture *fixture) {
|
||||||
free(fixture);
|
free(fixture);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_config_load_invalid_args() {
|
static void test_config_new_invalid_args() {
|
||||||
struct TestConfigFixture *fixture = test_config_setup();
|
struct TestConfigFixture *fixture = test_config_setup();
|
||||||
|
|
||||||
struct Error *error = 0;
|
struct Error *error = 0;
|
||||||
struct Config *config = 0;
|
struct Config *config = 0;
|
||||||
|
|
||||||
error = config_load(0, fixture->root_dir, fixture->target, &config);
|
error = config_new(0, fixture->root_dir, fixture->target, &config);
|
||||||
sput_fail_unless(error->code == ERROR_CONFIG_ENV_CWD_INVALID, "cwd == 0");
|
sput_fail_unless(error->code == ERROR_CONFIG_ENV_CWD_INVALID, "cwd == 0");
|
||||||
error_free(error);
|
error_free(error);
|
||||||
error = config_load(fixture->cwd, 0, fixture->target, &config);
|
error = config_new(fixture->cwd, 0, fixture->target, &config);
|
||||||
sput_fail_unless(
|
sput_fail_unless(
|
||||||
error->code == ERROR_CONFIG_ENV_ROOT_DIR_INVALID, "root_dir == 0"
|
error->code == ERROR_CONFIG_ENV_ROOT_DIR_INVALID, "root_dir == 0"
|
||||||
);
|
);
|
||||||
|
@ -51,13 +51,13 @@ static void test_config_load_invalid_args() {
|
||||||
test_config_teardown(fixture);
|
test_config_teardown(fixture);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_config_load_spec_not_found() {
|
static void test_config_new_spec_not_found() {
|
||||||
struct TestConfigFixture *fixture = test_config_setup();
|
struct TestConfigFixture *fixture = test_config_setup();
|
||||||
|
|
||||||
struct Error *error = 0;
|
struct Error *error = 0;
|
||||||
struct Config *config = 0;
|
struct Config *config = 0;
|
||||||
|
|
||||||
error = config_load(fixture->cwd, fixture->root_dir, "not_found", &config);
|
error = config_new(fixture->cwd, fixture->root_dir, "not_found", &config);
|
||||||
sput_fail_unless(
|
sput_fail_unless(
|
||||||
error->code == ERROR_CONFIG_TARGET_NOT_FOUND, "target not found"
|
error->code == ERROR_CONFIG_TARGET_NOT_FOUND, "target not found"
|
||||||
);
|
);
|
||||||
|
@ -66,13 +66,13 @@ static void test_config_load_spec_not_found() {
|
||||||
test_config_teardown(fixture);
|
test_config_teardown(fixture);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_config_load_spec_not_dir() {
|
static void test_config_new_spec_not_dir() {
|
||||||
struct TestConfigFixture *fixture = test_config_setup();
|
struct TestConfigFixture *fixture = test_config_setup();
|
||||||
|
|
||||||
struct Error *error = 0;
|
struct Error *error = 0;
|
||||||
struct Config *config = 0;
|
struct Config *config = 0;
|
||||||
|
|
||||||
error = config_load(fixture->cwd, fixture->root_dir, "not_dir", &config);
|
error = config_new(fixture->cwd, fixture->root_dir, "not_dir", &config);
|
||||||
sput_fail_unless(
|
sput_fail_unless(
|
||||||
error->code == ERROR_CONFIG_TARGET_NOT_DIR, "target not dir"
|
error->code == ERROR_CONFIG_TARGET_NOT_DIR, "target not dir"
|
||||||
);
|
);
|
||||||
|
@ -81,21 +81,20 @@ static void test_config_load_spec_not_dir() {
|
||||||
test_config_teardown(fixture);
|
test_config_teardown(fixture);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_config_load_success() {
|
static void test_config_new_success() {
|
||||||
struct TestConfigFixture *fixture = test_config_setup();
|
struct TestConfigFixture *fixture = test_config_setup();
|
||||||
|
|
||||||
struct Error *error = 0;
|
struct Error *error = 0;
|
||||||
struct Config *config = 0;
|
struct Config *config = 0;
|
||||||
|
|
||||||
error =
|
error = config_new(fixture->cwd, fixture->root_dir, fixture->target, &config);
|
||||||
config_load(fixture->cwd, fixture->root_dir, fixture->target, &config);
|
sput_fail_unless(error == 0, "config_new() success");
|
||||||
sput_fail_unless(error == 0, "config_load() success");
|
sput_fail_unless(strcmp(config->cwd, fixture->cwd) == 0, "config_new() cwd");
|
||||||
sput_fail_unless(strcmp(config->cwd, fixture->cwd) == 0, "config_load() cwd");
|
|
||||||
sput_fail_unless(
|
sput_fail_unless(
|
||||||
strcmp(config->root_dir, fixture->root_dir) == 0, "config_load() root_dir"
|
strcmp(config->root_dir, fixture->root_dir) == 0, "config_new() root_dir"
|
||||||
);
|
);
|
||||||
sput_fail_unless(
|
sput_fail_unless(
|
||||||
strcmp(config->target, fixture->target) == 0, "config_load() target"
|
strcmp(config->target, fixture->target) == 0, "config_new() target"
|
||||||
);
|
);
|
||||||
|
|
||||||
config_free(config);
|
config_free(config);
|
||||||
|
|
Loading…
Reference in New Issue