Initial commit
85
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,85 @@
|
||||||
|
# specific name of executable generated
|
||||||
|
toh_main_driver
|
||||||
|
toh_test_driver
|
||||||
|
|
||||||
|
# Created by https://www.gitignore.io/api/c++,macos,linux
|
||||||
|
# Edit at https://www.gitignore.io/?templates=c++,macos,linux
|
||||||
|
|
||||||
|
### C++ ###
|
||||||
|
# Prerequisites
|
||||||
|
*.d
|
||||||
|
|
||||||
|
# Compiled Object files
|
||||||
|
*.slo
|
||||||
|
*.lo
|
||||||
|
*.o
|
||||||
|
*.obj
|
||||||
|
|
||||||
|
# Precompiled Headers
|
||||||
|
*.gch
|
||||||
|
*.pch
|
||||||
|
|
||||||
|
# Compiled Dynamic libraries
|
||||||
|
*.so
|
||||||
|
*.dylib
|
||||||
|
*.dll
|
||||||
|
|
||||||
|
# Fortran module files
|
||||||
|
*.mod
|
||||||
|
*.smod
|
||||||
|
|
||||||
|
# Compiled Static libraries
|
||||||
|
*.lai
|
||||||
|
*.la
|
||||||
|
*.a
|
||||||
|
*.lib
|
||||||
|
|
||||||
|
# Executables
|
||||||
|
*.exe
|
||||||
|
*.out
|
||||||
|
*.app
|
||||||
|
|
||||||
|
### Linux ###
|
||||||
|
*~
|
||||||
|
|
||||||
|
# temporary files which can be created if a process still has a handle open of a deleted file
|
||||||
|
.fuse_hidden*
|
||||||
|
|
||||||
|
# KDE directory preferences
|
||||||
|
.directory
|
||||||
|
|
||||||
|
# Linux trash folder which might appear on any partition or disk
|
||||||
|
.Trash-*
|
||||||
|
|
||||||
|
# .nfs files are created when an open file is removed but is still being accessed
|
||||||
|
.nfs*
|
||||||
|
|
||||||
|
### macOS ###
|
||||||
|
# General
|
||||||
|
.DS_Store
|
||||||
|
.AppleDouble
|
||||||
|
.LSOverride
|
||||||
|
|
||||||
|
# Icon must end with two \r
|
||||||
|
Icon
|
||||||
|
|
||||||
|
# Thumbnails
|
||||||
|
._*
|
||||||
|
|
||||||
|
# Files that might appear in the root of a volume
|
||||||
|
.DocumentRevisions-V100
|
||||||
|
.fseventsd
|
||||||
|
.Spotlight-V100
|
||||||
|
.TemporaryItems
|
||||||
|
.Trashes
|
||||||
|
.VolumeIcon.icns
|
||||||
|
.com.apple.timemachine.donotpresent
|
||||||
|
|
||||||
|
# Directories potentially created on remote AFP share
|
||||||
|
.AppleDB
|
||||||
|
.AppleDesktop
|
||||||
|
Network Trash Folder
|
||||||
|
Temporary Items
|
||||||
|
.apdisk
|
||||||
|
|
||||||
|
# End of https://www.gitignore.io/api/c++,macos,linux
|
||||||
5
README.md
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
### if.04.22 Procedural Programming
|
||||||
|
# Assignment – Lists
|
||||||
|
## Simple Singly Linked List
|
||||||
|
With this assignment you shall implement abstract data types for a list in C.\n
|
||||||
|
Clone this assignment, open the index.html, read the assignment instructions and try to make all unit tests green.
|
||||||
108
allocator.c
Normal file
|
|
@ -0,0 +1,108 @@
|
||||||
|
/*----------------------------------------------------------
|
||||||
|
* HTBLA-Leonding
|
||||||
|
* ---------------------------------------------------------
|
||||||
|
* Title: Allocator for lists and list elements.
|
||||||
|
* Author: S. Schraml
|
||||||
|
* ----------------------------------------------------------
|
||||||
|
* Description:
|
||||||
|
* Implementation of memory allocation functions.
|
||||||
|
* ----------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "allocator.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "shortcut.h"
|
||||||
|
|
||||||
|
/* ===================================================================== */
|
||||||
|
/* Private memory allocation functions */
|
||||||
|
#define MAX_BLOCK_CNT 64
|
||||||
|
struct MemAllocStat {
|
||||||
|
bool block_alloc_calls;
|
||||||
|
int alloc_call_cnt;
|
||||||
|
int free_call_cnt;
|
||||||
|
int mem_block_cnt;
|
||||||
|
void* mem_blocks[MAX_BLOCK_CNT];
|
||||||
|
};
|
||||||
|
static struct MemAllocStat mem_stat = {false, 0, 0, 0, {0}};
|
||||||
|
|
||||||
|
void mem_reset_calls() {
|
||||||
|
mem_stat.block_alloc_calls = false;
|
||||||
|
mem_stat.alloc_call_cnt = 0;
|
||||||
|
mem_stat.free_call_cnt = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mem_reset_stat() {
|
||||||
|
mem_reset_calls();
|
||||||
|
memset(mem_stat.mem_blocks, 0, MAX_BLOCK_CNT * sizeof(void*));
|
||||||
|
mem_stat.mem_block_cnt = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mem_get_alloc_idx(void* p) {
|
||||||
|
if (p == 0) {
|
||||||
|
return MAX_BLOCK_CNT;
|
||||||
|
}
|
||||||
|
|
||||||
|
int idx = 0;
|
||||||
|
for (; idx < MAX_BLOCK_CNT && p != mem_stat.mem_blocks[idx]; idx++);
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mem_is_allocated(void* p) {
|
||||||
|
return mem_get_alloc_idx(p) < MAX_BLOCK_CNT;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mem_block_allocs(bool block) {
|
||||||
|
mem_stat.block_alloc_calls = block;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mem_get_alloc_call_cnt() {
|
||||||
|
return mem_stat.alloc_call_cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mem_get_free_call_cnt() {
|
||||||
|
return mem_stat.free_call_cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mem_get_allocated_block_cnt() {
|
||||||
|
return mem_stat.mem_block_cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===================================================================== */
|
||||||
|
|
||||||
|
void* alloc_mem(size_t size) {
|
||||||
|
void* p = 0;
|
||||||
|
mem_stat.alloc_call_cnt++;
|
||||||
|
if (!mem_stat.block_alloc_calls) {
|
||||||
|
p = malloc(size);
|
||||||
|
if (p != 0) {
|
||||||
|
int idx = 0;
|
||||||
|
for (; idx < MAX_BLOCK_CNT && mem_stat.mem_blocks[idx] != 0; idx++);
|
||||||
|
if (idx < MAX_BLOCK_CNT) {
|
||||||
|
mem_stat.mem_blocks[idx] = p;
|
||||||
|
mem_stat.mem_block_cnt++;
|
||||||
|
} else {
|
||||||
|
free(p);
|
||||||
|
p = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_mem(void* p_mem) {
|
||||||
|
mem_stat.free_call_cnt++;
|
||||||
|
if(p_mem == 0) {
|
||||||
|
printf("\tFailure: Freeing 0 (NULL)\n");
|
||||||
|
} else {
|
||||||
|
int mem_block_idx = mem_get_alloc_idx(p_mem);
|
||||||
|
if(mem_block_idx >= MAX_BLOCK_CNT) {
|
||||||
|
printf("\tFailure: Freeing memory that is not allocated [%p]\n", p_mem);
|
||||||
|
} else {
|
||||||
|
mem_stat.mem_blocks[mem_block_idx] = 0;
|
||||||
|
mem_stat.mem_block_cnt--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(p_mem);
|
||||||
|
}
|
||||||
|
|
||||||
50
allocator.h
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*----------------------------------------------------------
|
||||||
|
* HTBLA-Leonding
|
||||||
|
* ---------------------------------------------------------
|
||||||
|
* Title: Dynamic memory allocator.
|
||||||
|
* Author: S. Schraml
|
||||||
|
* ----------------------------------------------------------
|
||||||
|
* Description:
|
||||||
|
* Declaration of memory allocation functions.
|
||||||
|
* ----------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ___ALLOCATOR__H
|
||||||
|
#define ___ALLOCATOR__H
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allocates a memory block of the given size in bytes
|
||||||
|
* in a similar way as `malloc(size)`.
|
||||||
|
*
|
||||||
|
* Note: use `sizeof(X)` function to determines the size
|
||||||
|
* of a specfic type or value.
|
||||||
|
*
|
||||||
|
* @param size The number of bytes to allocate.
|
||||||
|
* @return The pointer to the allocated memory block or 0,
|
||||||
|
* if no memory could be allocated.
|
||||||
|
*/
|
||||||
|
void* alloc_mem(size_t size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Release the addressed memory block that was allocated via function `alloc_mem(...)`.
|
||||||
|
*
|
||||||
|
* @param p_mem The pointer to the memory to free.
|
||||||
|
*/
|
||||||
|
void free_mem(void* p_mem);
|
||||||
|
|
||||||
|
/* ==================================================== */
|
||||||
|
/* functions used for testing only! */
|
||||||
|
|
||||||
|
void mem_reset_calls();
|
||||||
|
void mem_reset_stat();
|
||||||
|
bool mem_is_allocated(void* p);
|
||||||
|
void mem_block_allocs(bool block);
|
||||||
|
int mem_get_alloc_call_cnt();
|
||||||
|
int mem_get_free_call_cnt();
|
||||||
|
int mem_get_allocated_block_cnt();
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
16
config.h
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
/*----------------------------------------------------------
|
||||||
|
* HTBLA-Leonding
|
||||||
|
* ---------------------------------------------------------
|
||||||
|
* Exercise Number: n/a
|
||||||
|
* Title: Configuration Options
|
||||||
|
* Author: S. Schraml
|
||||||
|
* ----------------------------------------------------------
|
||||||
|
* Description:
|
||||||
|
* Global application configuration options
|
||||||
|
* ----------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#ifndef ___CONFIGURATION_H
|
||||||
|
#define ___CONFIGURATION_H
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
14
doxygen_extra.css
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
code {
|
||||||
|
background: #eaeaea;
|
||||||
|
padding: 0 0.3em;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
div.fragment {
|
||||||
|
padding: 0.5em;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin: 1em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.line {
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
20
general.h
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
/*----------------------------------------------------------
|
||||||
|
* HTBLA-Leonding
|
||||||
|
* ---------------------------------------------------------
|
||||||
|
* Exercise Number: n/a
|
||||||
|
* Title: general.h
|
||||||
|
* Author: P. Bauer, S. Schraml
|
||||||
|
* ----------------------------------------------------------
|
||||||
|
* Description:
|
||||||
|
* General usable definitions and types.
|
||||||
|
* ----------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#ifndef ___GENERAL_H
|
||||||
|
#define ___GENERAL_H
|
||||||
|
|
||||||
|
/** Convenience macro do get maximum of two numbers */
|
||||||
|
#define MAX(x, y) ((x) > (y) ? (x) : (y))
|
||||||
|
/** Convenience macro do get maximum of two numbers */
|
||||||
|
#define MIN(x, y) ((x) < (y) ? (x) : (y))
|
||||||
|
|
||||||
|
#endif
|
||||||
BIN
html/bc_s.png
Normal file
|
After Width: | Height: | Size: 676 B |
BIN
html/bdwn.png
Normal file
|
After Width: | Height: | Size: 147 B |
BIN
html/closed.png
Normal file
|
After Width: | Height: | Size: 132 B |
BIN
html/doc.png
Normal file
|
After Width: | Height: | Size: 746 B |
1730
html/doxygen.css
Normal file
BIN
html/doxygen.png
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
14
html/doxygen_extra.css
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
code {
|
||||||
|
background: #eaeaea;
|
||||||
|
padding: 0 0.3em;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
div.fragment {
|
||||||
|
padding: 0.5em;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin: 1em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.line {
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
121
html/dynsections.js
Normal file
|
|
@ -0,0 +1,121 @@
|
||||||
|
/*
|
||||||
|
@licstart The following is the entire license notice for the JavaScript code in this file.
|
||||||
|
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (C) 1997-2020 by Dimitri van Heesch
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software
|
||||||
|
and associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||||
|
including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||||
|
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all copies or
|
||||||
|
substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
|
||||||
|
BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||||
|
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
@licend The above is the entire license notice for the JavaScript code in this file
|
||||||
|
*/
|
||||||
|
function toggleVisibility(linkObj)
|
||||||
|
{
|
||||||
|
var base = $(linkObj).attr('id');
|
||||||
|
var summary = $('#'+base+'-summary');
|
||||||
|
var content = $('#'+base+'-content');
|
||||||
|
var trigger = $('#'+base+'-trigger');
|
||||||
|
var src=$(trigger).attr('src');
|
||||||
|
if (content.is(':visible')===true) {
|
||||||
|
content.hide();
|
||||||
|
summary.show();
|
||||||
|
$(linkObj).addClass('closed').removeClass('opened');
|
||||||
|
$(trigger).attr('src',src.substring(0,src.length-8)+'closed.png');
|
||||||
|
} else {
|
||||||
|
content.show();
|
||||||
|
summary.hide();
|
||||||
|
$(linkObj).removeClass('closed').addClass('opened');
|
||||||
|
$(trigger).attr('src',src.substring(0,src.length-10)+'open.png');
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateStripes()
|
||||||
|
{
|
||||||
|
$('table.directory tr').
|
||||||
|
removeClass('even').filter(':visible:even').addClass('even');
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleLevel(level)
|
||||||
|
{
|
||||||
|
$('table.directory tr').each(function() {
|
||||||
|
var l = this.id.split('_').length-1;
|
||||||
|
var i = $('#img'+this.id.substring(3));
|
||||||
|
var a = $('#arr'+this.id.substring(3));
|
||||||
|
if (l<level+1) {
|
||||||
|
i.removeClass('iconfopen iconfclosed').addClass('iconfopen');
|
||||||
|
a.html('▼');
|
||||||
|
$(this).show();
|
||||||
|
} else if (l==level+1) {
|
||||||
|
i.removeClass('iconfclosed iconfopen').addClass('iconfclosed');
|
||||||
|
a.html('►');
|
||||||
|
$(this).show();
|
||||||
|
} else {
|
||||||
|
$(this).hide();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
updateStripes();
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleFolder(id)
|
||||||
|
{
|
||||||
|
// the clicked row
|
||||||
|
var currentRow = $('#row_'+id);
|
||||||
|
|
||||||
|
// all rows after the clicked row
|
||||||
|
var rows = currentRow.nextAll("tr");
|
||||||
|
|
||||||
|
var re = new RegExp('^row_'+id+'\\d+_$', "i"); //only one sub
|
||||||
|
|
||||||
|
// only match elements AFTER this one (can't hide elements before)
|
||||||
|
var childRows = rows.filter(function() { return this.id.match(re); });
|
||||||
|
|
||||||
|
// first row is visible we are HIDING
|
||||||
|
if (childRows.filter(':first').is(':visible')===true) {
|
||||||
|
// replace down arrow by right arrow for current row
|
||||||
|
var currentRowSpans = currentRow.find("span");
|
||||||
|
currentRowSpans.filter(".iconfopen").removeClass("iconfopen").addClass("iconfclosed");
|
||||||
|
currentRowSpans.filter(".arrow").html('►');
|
||||||
|
rows.filter("[id^=row_"+id+"]").hide(); // hide all children
|
||||||
|
} else { // we are SHOWING
|
||||||
|
// replace right arrow by down arrow for current row
|
||||||
|
var currentRowSpans = currentRow.find("span");
|
||||||
|
currentRowSpans.filter(".iconfclosed").removeClass("iconfclosed").addClass("iconfopen");
|
||||||
|
currentRowSpans.filter(".arrow").html('▼');
|
||||||
|
// replace down arrows by right arrows for child rows
|
||||||
|
var childRowsSpans = childRows.find("span");
|
||||||
|
childRowsSpans.filter(".iconfopen").removeClass("iconfopen").addClass("iconfclosed");
|
||||||
|
childRowsSpans.filter(".arrow").html('►');
|
||||||
|
childRows.show(); //show all children
|
||||||
|
}
|
||||||
|
updateStripes();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function toggleInherit(id)
|
||||||
|
{
|
||||||
|
var rows = $('tr.inherit.'+id);
|
||||||
|
var img = $('tr.inherit_header.'+id+' img');
|
||||||
|
var src = $(img).attr('src');
|
||||||
|
if (rows.filter(':first').is(':visible')===true) {
|
||||||
|
rows.css('display','none');
|
||||||
|
$(img).attr('src',src.substring(0,src.length-8)+'closed.png');
|
||||||
|
} else {
|
||||||
|
rows.css('display','table-row'); // using show() causes jump in firefox
|
||||||
|
$(img).attr('src',src.substring(0,src.length-10)+'open.png');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* @license-end */
|
||||||
82
html/files.html
Normal file
|
|
@ -0,0 +1,82 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
|
||||||
|
<meta name="generator" content="Doxygen 1.8.18"/>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||||
|
<title>Simple Singly Linked List: File List</title>
|
||||||
|
<link href="tabs.css" rel="stylesheet" type="text/css"/>
|
||||||
|
<script type="text/javascript" src="jquery.js"></script>
|
||||||
|
<script type="text/javascript" src="dynsections.js"></script>
|
||||||
|
<link href="search/search.css" rel="stylesheet" type="text/css"/>
|
||||||
|
<script type="text/javascript" src="search/searchdata.js"></script>
|
||||||
|
<script type="text/javascript" src="search/search.js"></script>
|
||||||
|
<link href="doxygen.css" rel="stylesheet" type="text/css" />
|
||||||
|
<link href="doxygen_extra.css" rel="stylesheet" type="text/css"/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
|
||||||
|
<div id="titlearea">
|
||||||
|
<table cellspacing="0" cellpadding="0">
|
||||||
|
<tbody>
|
||||||
|
<tr style="height: 56px;">
|
||||||
|
<td id="projectalign" style="padding-left: 0.5em;">
|
||||||
|
<div id="projectname">Simple Singly Linked List
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<!-- end header part -->
|
||||||
|
<!-- Generated by Doxygen 1.8.18 -->
|
||||||
|
<script type="text/javascript">
|
||||||
|
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
|
||||||
|
var searchBox = new SearchBox("searchBox", "search",false,'Search');
|
||||||
|
/* @license-end */
|
||||||
|
</script>
|
||||||
|
<script type="text/javascript" src="menudata.js"></script>
|
||||||
|
<script type="text/javascript" src="menu.js"></script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
|
||||||
|
$(function() {
|
||||||
|
initMenu('',true,false,'search.php','Search');
|
||||||
|
$(document).ready(function() { init_search(); });
|
||||||
|
});
|
||||||
|
/* @license-end */</script>
|
||||||
|
<div id="main-nav"></div>
|
||||||
|
</div><!-- top -->
|
||||||
|
<!-- window showing the filter options -->
|
||||||
|
<div id="MSearchSelectWindow"
|
||||||
|
onmouseover="return searchBox.OnSearchSelectShow()"
|
||||||
|
onmouseout="return searchBox.OnSearchSelectHide()"
|
||||||
|
onkeydown="return searchBox.OnSearchSelectKey(event)">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- iframe showing the search results (closed by default) -->
|
||||||
|
<div id="MSearchResultsWindow">
|
||||||
|
<iframe src="javascript:void(0)" frameborder="0"
|
||||||
|
name="MSearchResults" id="MSearchResults">
|
||||||
|
</iframe>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="header">
|
||||||
|
<div class="headertitle">
|
||||||
|
<div class="title">File List</div> </div>
|
||||||
|
</div><!--header-->
|
||||||
|
<div class="contents">
|
||||||
|
<div class="textblock">Here is a list of all files with brief descriptions:</div><div class="directory">
|
||||||
|
<table class="directory">
|
||||||
|
<tr id="row_0_" class="even"><td class="entry"><span style="width:16px;display:inline-block;"> </span><a href="mainpage_8h_source.html"><span class="icondoc"></span></a><a class="el" href="mainpage_8h.html" target="_self">mainpage.h</a></td><td class="desc"></td></tr>
|
||||||
|
</table>
|
||||||
|
</div><!-- directory -->
|
||||||
|
</div><!-- contents -->
|
||||||
|
<!-- start footer part -->
|
||||||
|
<hr class="footer"/><address class="footer"><small>
|
||||||
|
Generated on Mon Feb 15 2021 16:00:18 for Simple Singly Linked List by  <a href="http://www.doxygen.org/index.html">
|
||||||
|
<img class="footer" src="doxygen.png" alt="doxygen"/>
|
||||||
|
</a> 1.8.18
|
||||||
|
</small></address>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
BIN
html/folderclosed.png
Normal file
|
After Width: | Height: | Size: 616 B |
BIN
html/folderopen.png
Normal file
|
After Width: | Height: | Size: 597 B |
111
html/index.html
Normal file
|
|
@ -0,0 +1,111 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
|
||||||
|
<meta name="generator" content="Doxygen 1.8.18"/>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||||
|
<title>Simple Singly Linked List: Main Page</title>
|
||||||
|
<link href="tabs.css" rel="stylesheet" type="text/css"/>
|
||||||
|
<script type="text/javascript" src="jquery.js"></script>
|
||||||
|
<script type="text/javascript" src="dynsections.js"></script>
|
||||||
|
<link href="search/search.css" rel="stylesheet" type="text/css"/>
|
||||||
|
<script type="text/javascript" src="search/searchdata.js"></script>
|
||||||
|
<script type="text/javascript" src="search/search.js"></script>
|
||||||
|
<link href="doxygen.css" rel="stylesheet" type="text/css" />
|
||||||
|
<link href="doxygen_extra.css" rel="stylesheet" type="text/css"/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
|
||||||
|
<div id="titlearea">
|
||||||
|
<table cellspacing="0" cellpadding="0">
|
||||||
|
<tbody>
|
||||||
|
<tr style="height: 56px;">
|
||||||
|
<td id="projectalign" style="padding-left: 0.5em;">
|
||||||
|
<div id="projectname">Simple Singly Linked List
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<!-- end header part -->
|
||||||
|
<!-- Generated by Doxygen 1.8.18 -->
|
||||||
|
<script type="text/javascript">
|
||||||
|
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
|
||||||
|
var searchBox = new SearchBox("searchBox", "search",false,'Search');
|
||||||
|
/* @license-end */
|
||||||
|
</script>
|
||||||
|
<script type="text/javascript" src="menudata.js"></script>
|
||||||
|
<script type="text/javascript" src="menu.js"></script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
|
||||||
|
$(function() {
|
||||||
|
initMenu('',true,false,'search.php','Search');
|
||||||
|
$(document).ready(function() { init_search(); });
|
||||||
|
});
|
||||||
|
/* @license-end */</script>
|
||||||
|
<div id="main-nav"></div>
|
||||||
|
</div><!-- top -->
|
||||||
|
<!-- window showing the filter options -->
|
||||||
|
<div id="MSearchSelectWindow"
|
||||||
|
onmouseover="return searchBox.OnSearchSelectShow()"
|
||||||
|
onmouseout="return searchBox.OnSearchSelectHide()"
|
||||||
|
onkeydown="return searchBox.OnSearchSelectKey(event)">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- iframe showing the search results (closed by default) -->
|
||||||
|
<div id="MSearchResultsWindow">
|
||||||
|
<iframe src="javascript:void(0)" frameborder="0"
|
||||||
|
name="MSearchResults" id="MSearchResults">
|
||||||
|
</iframe>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="PageDoc"><div class="header">
|
||||||
|
<div class="headertitle">
|
||||||
|
<div class="title">Simple Singly Linked List Documentation</div> </div>
|
||||||
|
</div><!--header-->
|
||||||
|
<div class="contents">
|
||||||
|
<div class="textblock"><h1><a class="anchor" id="intro"></a>
|
||||||
|
Introduction</h1>
|
||||||
|
<p>The implementation of a "Simple Singly Linked List".</p>
|
||||||
|
<h1><a class="anchor" id="objective"></a>
|
||||||
|
Assignment Objective</h1>
|
||||||
|
<p>In this assignment an Abstract Data Type of a "Simple Singly Linked List" shall be implemented against the defined common interface of a list. This interface is declared within file 'list.h'. It is intended to be used by applications or other libraries and aims to abstract the 'list' functionality as far as possible.</p>
|
||||||
|
<p>The term 'simple' in 'Simple Singly Linked List' refers to the limited members of the list data: the pointer to the list head node is the only member of list data.</p>
|
||||||
|
<p><b>Configuration</b></p>
|
||||||
|
<p>There is no configuration required.</p>
|
||||||
|
<h1><a class="anchor" id="assignment"></a>
|
||||||
|
Assignment</h1>
|
||||||
|
<p>The 'Simple Singly Linked List' shall be implemented in file 'simple_singly_linked_list.c'. The corresponding header file includes the common interface 'list.h' but does not add functions by its own.</p>
|
||||||
|
<p>The library 'allocator' is provided for memory allocation functionality that integrates with unit testing. Behind the facade, allocats memory dynamically similar to <code>malloc</code>. Allocated memory must be freed when it is not used anymore. The 'allocator' library must be used for memory alloction operations, otherwise unit tests will fail.</p>
|
||||||
|
<ol type="1">
|
||||||
|
<li>Implement 'simple_singly_linked_list.c' against interface indirectly declared in 'list.h': Make the program and tests compile: Implement all functions in all relevant files declared in the headers EMTPY (return nothing, 0, false, ... as required).<ul>
|
||||||
|
<li>All unit tests shall run but FAIL after this step</li>
|
||||||
|
<li><b>–COMMIT–</b></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li>Implement the empty functions one by one to make the unit tests pass one by one.<ul>
|
||||||
|
<li>The purpose of a function is specified as API documentation within the header files.</li>
|
||||||
|
<li>Obey comments in source files. Run the unit tests frequently and fix failures.</li>
|
||||||
|
<li><b>–COMMIT– after each implemented function.</b></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
<p>Main driver is not required in this assignment.</p>
|
||||||
|
<h1><a class="anchor" id="notes"></a>
|
||||||
|
Notes</h1>
|
||||||
|
<ol type="1">
|
||||||
|
<li>make cleantest: This new make target for clearing the console, building, and running unit test is available.</li>
|
||||||
|
<li>Sometimes changes are not properly detected by incremental builds. If something very strange happens during compilation, try to run <code>make clean</code> followed by <code>make</code> to start a clean build. This approach is also recommended after everthing is done, because some compiler warning appears only in clean builds. </li>
|
||||||
|
</ol>
|
||||||
|
</div></div><!-- PageDoc -->
|
||||||
|
</div><!-- contents -->
|
||||||
|
<!-- start footer part -->
|
||||||
|
<hr class="footer"/><address class="footer"><small>
|
||||||
|
Generated on Mon Feb 15 2021 16:00:18 for Simple Singly Linked List by  <a href="http://www.doxygen.org/index.html">
|
||||||
|
<img class="footer" src="doxygen.png" alt="doxygen"/>
|
||||||
|
</a> 1.8.18
|
||||||
|
</small></address>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
35
html/jquery.js
vendored
Normal file
79
html/mainpage_8h.html
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
|
||||||
|
<meta name="generator" content="Doxygen 1.8.18"/>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||||
|
<title>Simple Singly Linked List: mainpage.h File Reference</title>
|
||||||
|
<link href="tabs.css" rel="stylesheet" type="text/css"/>
|
||||||
|
<script type="text/javascript" src="jquery.js"></script>
|
||||||
|
<script type="text/javascript" src="dynsections.js"></script>
|
||||||
|
<link href="search/search.css" rel="stylesheet" type="text/css"/>
|
||||||
|
<script type="text/javascript" src="search/searchdata.js"></script>
|
||||||
|
<script type="text/javascript" src="search/search.js"></script>
|
||||||
|
<link href="doxygen.css" rel="stylesheet" type="text/css" />
|
||||||
|
<link href="doxygen_extra.css" rel="stylesheet" type="text/css"/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
|
||||||
|
<div id="titlearea">
|
||||||
|
<table cellspacing="0" cellpadding="0">
|
||||||
|
<tbody>
|
||||||
|
<tr style="height: 56px;">
|
||||||
|
<td id="projectalign" style="padding-left: 0.5em;">
|
||||||
|
<div id="projectname">Simple Singly Linked List
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<!-- end header part -->
|
||||||
|
<!-- Generated by Doxygen 1.8.18 -->
|
||||||
|
<script type="text/javascript">
|
||||||
|
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
|
||||||
|
var searchBox = new SearchBox("searchBox", "search",false,'Search');
|
||||||
|
/* @license-end */
|
||||||
|
</script>
|
||||||
|
<script type="text/javascript" src="menudata.js"></script>
|
||||||
|
<script type="text/javascript" src="menu.js"></script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
|
||||||
|
$(function() {
|
||||||
|
initMenu('',true,false,'search.php','Search');
|
||||||
|
$(document).ready(function() { init_search(); });
|
||||||
|
});
|
||||||
|
/* @license-end */</script>
|
||||||
|
<div id="main-nav"></div>
|
||||||
|
<!-- window showing the filter options -->
|
||||||
|
<div id="MSearchSelectWindow"
|
||||||
|
onmouseover="return searchBox.OnSearchSelectShow()"
|
||||||
|
onmouseout="return searchBox.OnSearchSelectHide()"
|
||||||
|
onkeydown="return searchBox.OnSearchSelectKey(event)">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- iframe showing the search results (closed by default) -->
|
||||||
|
<div id="MSearchResultsWindow">
|
||||||
|
<iframe src="javascript:void(0)" frameborder="0"
|
||||||
|
name="MSearchResults" id="MSearchResults">
|
||||||
|
</iframe>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div><!-- top -->
|
||||||
|
<div class="header">
|
||||||
|
<div class="headertitle">
|
||||||
|
<div class="title">mainpage.h File Reference</div> </div>
|
||||||
|
</div><!--header-->
|
||||||
|
<div class="contents">
|
||||||
|
|
||||||
|
<p><a href="mainpage_8h_source.html">Go to the source code of this file.</a></p>
|
||||||
|
</div><!-- contents -->
|
||||||
|
<!-- start footer part -->
|
||||||
|
<hr class="footer"/><address class="footer"><small>
|
||||||
|
Generated on Mon Feb 15 2021 16:00:18 for Simple Singly Linked List by  <a href="http://www.doxygen.org/index.html">
|
||||||
|
<img class="footer" src="doxygen.png" alt="doxygen"/>
|
||||||
|
</a> 1.8.18
|
||||||
|
</small></address>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
78
html/mainpage_8h_source.html
Normal file
|
|
@ -0,0 +1,78 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
|
||||||
|
<meta name="generator" content="Doxygen 1.8.18"/>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||||
|
<title>Simple Singly Linked List: mainpage.h Source File</title>
|
||||||
|
<link href="tabs.css" rel="stylesheet" type="text/css"/>
|
||||||
|
<script type="text/javascript" src="jquery.js"></script>
|
||||||
|
<script type="text/javascript" src="dynsections.js"></script>
|
||||||
|
<link href="search/search.css" rel="stylesheet" type="text/css"/>
|
||||||
|
<script type="text/javascript" src="search/searchdata.js"></script>
|
||||||
|
<script type="text/javascript" src="search/search.js"></script>
|
||||||
|
<link href="doxygen.css" rel="stylesheet" type="text/css" />
|
||||||
|
<link href="doxygen_extra.css" rel="stylesheet" type="text/css"/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
|
||||||
|
<div id="titlearea">
|
||||||
|
<table cellspacing="0" cellpadding="0">
|
||||||
|
<tbody>
|
||||||
|
<tr style="height: 56px;">
|
||||||
|
<td id="projectalign" style="padding-left: 0.5em;">
|
||||||
|
<div id="projectname">Simple Singly Linked List
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<!-- end header part -->
|
||||||
|
<!-- Generated by Doxygen 1.8.18 -->
|
||||||
|
<script type="text/javascript">
|
||||||
|
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
|
||||||
|
var searchBox = new SearchBox("searchBox", "search",false,'Search');
|
||||||
|
/* @license-end */
|
||||||
|
</script>
|
||||||
|
<script type="text/javascript" src="menudata.js"></script>
|
||||||
|
<script type="text/javascript" src="menu.js"></script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
|
||||||
|
$(function() {
|
||||||
|
initMenu('',true,false,'search.php','Search');
|
||||||
|
$(document).ready(function() { init_search(); });
|
||||||
|
});
|
||||||
|
/* @license-end */</script>
|
||||||
|
<div id="main-nav"></div>
|
||||||
|
</div><!-- top -->
|
||||||
|
<!-- window showing the filter options -->
|
||||||
|
<div id="MSearchSelectWindow"
|
||||||
|
onmouseover="return searchBox.OnSearchSelectShow()"
|
||||||
|
onmouseout="return searchBox.OnSearchSelectHide()"
|
||||||
|
onkeydown="return searchBox.OnSearchSelectKey(event)">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- iframe showing the search results (closed by default) -->
|
||||||
|
<div id="MSearchResultsWindow">
|
||||||
|
<iframe src="javascript:void(0)" frameborder="0"
|
||||||
|
name="MSearchResults" id="MSearchResults">
|
||||||
|
</iframe>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="header">
|
||||||
|
<div class="headertitle">
|
||||||
|
<div class="title">mainpage.h</div> </div>
|
||||||
|
</div><!--header-->
|
||||||
|
<div class="contents">
|
||||||
|
<a href="mainpage_8h.html">Go to the documentation of this file.</a><div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno"> 1</span>  </div>
|
||||||
|
</div><!-- fragment --></div><!-- contents -->
|
||||||
|
<!-- start footer part -->
|
||||||
|
<hr class="footer"/><address class="footer"><small>
|
||||||
|
Generated on Mon Feb 15 2021 16:00:18 for Simple Singly Linked List by  <a href="http://www.doxygen.org/index.html">
|
||||||
|
<img class="footer" src="doxygen.png" alt="doxygen"/>
|
||||||
|
</a> 1.8.18
|
||||||
|
</small></address>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
51
html/menu.js
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
@licstart The following is the entire license notice for the JavaScript code in this file.
|
||||||
|
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (C) 1997-2020 by Dimitri van Heesch
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software
|
||||||
|
and associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||||
|
including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||||
|
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all copies or
|
||||||
|
substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
|
||||||
|
BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||||
|
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
@licend The above is the entire license notice for the JavaScript code in this file
|
||||||
|
*/
|
||||||
|
function initMenu(relPath,searchEnabled,serverSide,searchPage,search) {
|
||||||
|
function makeTree(data,relPath) {
|
||||||
|
var result='';
|
||||||
|
if ('children' in data) {
|
||||||
|
result+='<ul>';
|
||||||
|
for (var i in data.children) {
|
||||||
|
result+='<li><a href="'+relPath+data.children[i].url+'">'+
|
||||||
|
data.children[i].text+'</a>'+
|
||||||
|
makeTree(data.children[i],relPath)+'</li>';
|
||||||
|
}
|
||||||
|
result+='</ul>';
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#main-nav').append(makeTree(menudata,relPath));
|
||||||
|
$('#main-nav').children(':first').addClass('sm sm-dox').attr('id','main-menu');
|
||||||
|
if (searchEnabled) {
|
||||||
|
if (serverSide) {
|
||||||
|
$('#main-menu').append('<li style="float:right"><div id="MSearchBox" class="MSearchBoxInactive"><div class="left"><form id="FSearchBox" action="'+relPath+searchPage+'" method="get"><img id="MSearchSelect" src="'+relPath+'search/mag.png" alt=""/><input type="text" id="MSearchField" name="query" value="'+search+'" size="20" accesskey="S" onfocus="searchBox.OnSearchFieldFocus(true)" onblur="searchBox.OnSearchFieldFocus(false)"></form></div><div class="right"></div></div></li>');
|
||||||
|
} else {
|
||||||
|
$('#main-menu').append('<li style="float:right"><div id="MSearchBox" class="MSearchBoxInactive"><span class="left"><img id="MSearchSelect" src="'+relPath+'search/mag_sel.png" onmouseover="return searchBox.OnSearchSelectShow()" onmouseout="return searchBox.OnSearchSelectHide()" alt=""/><input type="text" id="MSearchField" value="'+search+'" accesskey="S" onfocus="searchBox.OnSearchFieldFocus(true)" onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/></span><span class="right"><a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="'+relPath+'search/close.png" alt=""/></a></span></div></li>');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$('#main-menu').smartmenus();
|
||||||
|
}
|
||||||
|
/* @license-end */
|
||||||
28
html/menudata.js
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
@licstart The following is the entire license notice for the JavaScript code in this file.
|
||||||
|
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (C) 1997-2020 by Dimitri van Heesch
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software
|
||||||
|
and associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||||
|
including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||||
|
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all copies or
|
||||||
|
substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
|
||||||
|
BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||||
|
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
@licend The above is the entire license notice for the JavaScript code in this file
|
||||||
|
*/
|
||||||
|
var menudata={children:[
|
||||||
|
{text:"Main Page",url:"index.html"},
|
||||||
|
{text:"Files",url:"files.html",children:[
|
||||||
|
{text:"File List",url:"files.html"}]}]}
|
||||||
BIN
html/nav_f.png
Normal file
|
After Width: | Height: | Size: 153 B |
BIN
html/nav_g.png
Normal file
|
After Width: | Height: | Size: 95 B |
BIN
html/nav_h.png
Normal file
|
After Width: | Height: | Size: 98 B |
BIN
html/open.png
Normal file
|
After Width: | Height: | Size: 123 B |
36
html/search/all_0.html
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
<html><head><title></title>
|
||||||
|
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
|
||||||
|
<meta name="generator" content="Doxygen 1.8.18"/>
|
||||||
|
<link rel="stylesheet" type="text/css" href="search.css"/>
|
||||||
|
<script type="text/javascript" src="all_0.js"></script>
|
||||||
|
<script type="text/javascript" src="search.js"></script>
|
||||||
|
</head>
|
||||||
|
<body class="SRPage">
|
||||||
|
<div id="SRIndex">
|
||||||
|
<div class="SRStatus" id="Loading">Loading...</div>
|
||||||
|
<div id="SRResults"></div>
|
||||||
|
<script type="text/javascript"><!--
|
||||||
|
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
|
||||||
|
createResults();
|
||||||
|
/* @license-end */
|
||||||
|
--></script>
|
||||||
|
<div class="SRStatus" id="Searching">Searching...</div>
|
||||||
|
<div class="SRStatus" id="NoMatches">No Matches</div>
|
||||||
|
<script type="text/javascript"><!--
|
||||||
|
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
|
||||||
|
document.getElementById("Loading").style.display="none";
|
||||||
|
document.getElementById("NoMatches").style.display="none";
|
||||||
|
var searchResults = new SearchResults("searchResults");
|
||||||
|
searchResults.Search();
|
||||||
|
window.addEventListener("message", function(event) {
|
||||||
|
if (event.data == "take_focus") {
|
||||||
|
var elem = searchResults.NavNext(0);
|
||||||
|
if (elem) elem.focus();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
/* @license-end */
|
||||||
|
--></script>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
4
html/search/all_0.js
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
var searchData=
|
||||||
|
[
|
||||||
|
['mainpage_2eh_0',['mainpage.h',['../mainpage_8h.html',1,'']]]
|
||||||
|
];
|
||||||
BIN
html/search/close.png
Normal file
|
After Width: | Height: | Size: 273 B |
36
html/search/files_0.html
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
<html><head><title></title>
|
||||||
|
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
|
||||||
|
<meta name="generator" content="Doxygen 1.8.18"/>
|
||||||
|
<link rel="stylesheet" type="text/css" href="search.css"/>
|
||||||
|
<script type="text/javascript" src="files_0.js"></script>
|
||||||
|
<script type="text/javascript" src="search.js"></script>
|
||||||
|
</head>
|
||||||
|
<body class="SRPage">
|
||||||
|
<div id="SRIndex">
|
||||||
|
<div class="SRStatus" id="Loading">Loading...</div>
|
||||||
|
<div id="SRResults"></div>
|
||||||
|
<script type="text/javascript"><!--
|
||||||
|
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
|
||||||
|
createResults();
|
||||||
|
/* @license-end */
|
||||||
|
--></script>
|
||||||
|
<div class="SRStatus" id="Searching">Searching...</div>
|
||||||
|
<div class="SRStatus" id="NoMatches">No Matches</div>
|
||||||
|
<script type="text/javascript"><!--
|
||||||
|
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
|
||||||
|
document.getElementById("Loading").style.display="none";
|
||||||
|
document.getElementById("NoMatches").style.display="none";
|
||||||
|
var searchResults = new SearchResults("searchResults");
|
||||||
|
searchResults.Search();
|
||||||
|
window.addEventListener("message", function(event) {
|
||||||
|
if (event.data == "take_focus") {
|
||||||
|
var elem = searchResults.NavNext(0);
|
||||||
|
if (elem) elem.focus();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
/* @license-end */
|
||||||
|
--></script>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
4
html/search/files_0.js
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
var searchData=
|
||||||
|
[
|
||||||
|
['mainpage_2eh_1',['mainpage.h',['../mainpage_8h.html',1,'']]]
|
||||||
|
];
|
||||||
BIN
html/search/mag_sel.png
Normal file
|
After Width: | Height: | Size: 465 B |
12
html/search/nomatches.html
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
<html><head><title></title>
|
||||||
|
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
|
||||||
|
<link rel="stylesheet" type="text/css" href="search.css"/>
|
||||||
|
<script type="text/javascript" src="search.js"></script>
|
||||||
|
</head>
|
||||||
|
<body class="SRPage">
|
||||||
|
<div id="SRIndex">
|
||||||
|
<div class="SRStatus" id="NoMatches">No Matches</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
271
html/search/search.css
Normal file
|
|
@ -0,0 +1,271 @@
|
||||||
|
/*---------------- Search Box */
|
||||||
|
|
||||||
|
#FSearchBox {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
#MSearchBox {
|
||||||
|
white-space : nowrap;
|
||||||
|
float: none;
|
||||||
|
margin-top: 8px;
|
||||||
|
right: 0px;
|
||||||
|
width: 170px;
|
||||||
|
height: 24px;
|
||||||
|
z-index: 102;
|
||||||
|
}
|
||||||
|
|
||||||
|
#MSearchBox .left
|
||||||
|
{
|
||||||
|
display:block;
|
||||||
|
position:absolute;
|
||||||
|
left:10px;
|
||||||
|
width:20px;
|
||||||
|
height:19px;
|
||||||
|
background:url('search_l.png') no-repeat;
|
||||||
|
background-position:right;
|
||||||
|
}
|
||||||
|
|
||||||
|
#MSearchSelect {
|
||||||
|
display:block;
|
||||||
|
position:absolute;
|
||||||
|
width:20px;
|
||||||
|
height:19px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left #MSearchSelect {
|
||||||
|
left:4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right #MSearchSelect {
|
||||||
|
right:5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#MSearchField {
|
||||||
|
display:block;
|
||||||
|
position:absolute;
|
||||||
|
height:19px;
|
||||||
|
background:url('search_m.png') repeat-x;
|
||||||
|
border:none;
|
||||||
|
width:115px;
|
||||||
|
margin-left:20px;
|
||||||
|
padding-left:4px;
|
||||||
|
color: #909090;
|
||||||
|
outline: none;
|
||||||
|
font: 9pt Arial, Verdana, sans-serif;
|
||||||
|
-webkit-border-radius: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#FSearchBox #MSearchField {
|
||||||
|
margin-left:15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#MSearchBox .right {
|
||||||
|
display:block;
|
||||||
|
position:absolute;
|
||||||
|
right:10px;
|
||||||
|
top:8px;
|
||||||
|
width:20px;
|
||||||
|
height:19px;
|
||||||
|
background:url('search_r.png') no-repeat;
|
||||||
|
background-position:left;
|
||||||
|
}
|
||||||
|
|
||||||
|
#MSearchClose {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
top: 4px;
|
||||||
|
background : none;
|
||||||
|
border: none;
|
||||||
|
margin: 0px 4px 0px 0px;
|
||||||
|
padding: 0px 0px;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left #MSearchClose {
|
||||||
|
left: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right #MSearchClose {
|
||||||
|
right: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.MSearchBoxActive #MSearchField {
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------- Search filter selection */
|
||||||
|
|
||||||
|
#MSearchSelectWindow {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
left: 0; top: 0;
|
||||||
|
border: 1px solid #90A5CE;
|
||||||
|
background-color: #F9FAFC;
|
||||||
|
z-index: 10001;
|
||||||
|
padding-top: 4px;
|
||||||
|
padding-bottom: 4px;
|
||||||
|
-moz-border-radius: 4px;
|
||||||
|
-webkit-border-top-left-radius: 4px;
|
||||||
|
-webkit-border-top-right-radius: 4px;
|
||||||
|
-webkit-border-bottom-left-radius: 4px;
|
||||||
|
-webkit-border-bottom-right-radius: 4px;
|
||||||
|
-webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.SelectItem {
|
||||||
|
font: 8pt Arial, Verdana, sans-serif;
|
||||||
|
padding-left: 2px;
|
||||||
|
padding-right: 12px;
|
||||||
|
border: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span.SelectionMark {
|
||||||
|
margin-right: 4px;
|
||||||
|
font-family: monospace;
|
||||||
|
outline-style: none;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.SelectItem {
|
||||||
|
display: block;
|
||||||
|
outline-style: none;
|
||||||
|
color: #000000;
|
||||||
|
text-decoration: none;
|
||||||
|
padding-left: 6px;
|
||||||
|
padding-right: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.SelectItem:focus,
|
||||||
|
a.SelectItem:active {
|
||||||
|
color: #000000;
|
||||||
|
outline-style: none;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.SelectItem:hover {
|
||||||
|
color: #FFFFFF;
|
||||||
|
background-color: #3D578C;
|
||||||
|
outline-style: none;
|
||||||
|
text-decoration: none;
|
||||||
|
cursor: pointer;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------- Search results window */
|
||||||
|
|
||||||
|
iframe#MSearchResults {
|
||||||
|
width: 60ex;
|
||||||
|
height: 15em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#MSearchResultsWindow {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
left: 0; top: 0;
|
||||||
|
border: 1px solid #000;
|
||||||
|
background-color: #EEF1F7;
|
||||||
|
z-index:10000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
#SRIndex {
|
||||||
|
clear:both;
|
||||||
|
padding-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.SREntry {
|
||||||
|
font-size: 10pt;
|
||||||
|
padding-left: 1ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.SRPage .SREntry {
|
||||||
|
font-size: 8pt;
|
||||||
|
padding: 1px 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.SRPage {
|
||||||
|
margin: 5px 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.SRChildren {
|
||||||
|
padding-left: 3ex; padding-bottom: .5em
|
||||||
|
}
|
||||||
|
|
||||||
|
.SRPage .SRChildren {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.SRSymbol {
|
||||||
|
font-weight: bold;
|
||||||
|
color: #425E97;
|
||||||
|
font-family: Arial, Verdana, sans-serif;
|
||||||
|
text-decoration: none;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.SRScope {
|
||||||
|
display: block;
|
||||||
|
color: #425E97;
|
||||||
|
font-family: Arial, Verdana, sans-serif;
|
||||||
|
text-decoration: none;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.SRSymbol:focus, a.SRSymbol:active,
|
||||||
|
a.SRScope:focus, a.SRScope:active {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
span.SRScope {
|
||||||
|
padding-left: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.SRPage .SRStatus {
|
||||||
|
padding: 2px 5px;
|
||||||
|
font-size: 8pt;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.SRResult {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
DIV.searchresults {
|
||||||
|
margin-left: 10px;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------- External search page results */
|
||||||
|
|
||||||
|
.searchresult {
|
||||||
|
background-color: #F0F3F8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pages b {
|
||||||
|
color: white;
|
||||||
|
padding: 5px 5px 3px 5px;
|
||||||
|
background-image: url("../tab_a.png");
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
text-shadow: 0 1px 1px #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pages {
|
||||||
|
line-height: 17px;
|
||||||
|
margin-left: 4px;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hl {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
#searchresults {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.searchpages {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
814
html/search/search.js
Normal file
|
|
@ -0,0 +1,814 @@
|
||||||
|
/*
|
||||||
|
@licstart The following is the entire license notice for the JavaScript code in this file.
|
||||||
|
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (C) 1997-2020 by Dimitri van Heesch
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software
|
||||||
|
and associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||||
|
including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||||
|
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all copies or
|
||||||
|
substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
|
||||||
|
BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||||
|
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
@licend The above is the entire license notice for the JavaScript code in this file
|
||||||
|
*/
|
||||||
|
function convertToId(search)
|
||||||
|
{
|
||||||
|
var result = '';
|
||||||
|
for (i=0;i<search.length;i++)
|
||||||
|
{
|
||||||
|
var c = search.charAt(i);
|
||||||
|
var cn = c.charCodeAt(0);
|
||||||
|
if (c.match(/[a-z0-9\u0080-\uFFFF]/))
|
||||||
|
{
|
||||||
|
result+=c;
|
||||||
|
}
|
||||||
|
else if (cn<16)
|
||||||
|
{
|
||||||
|
result+="_0"+cn.toString(16);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result+="_"+cn.toString(16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getXPos(item)
|
||||||
|
{
|
||||||
|
var x = 0;
|
||||||
|
if (item.offsetWidth)
|
||||||
|
{
|
||||||
|
while (item && item!=document.body)
|
||||||
|
{
|
||||||
|
x += item.offsetLeft;
|
||||||
|
item = item.offsetParent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getYPos(item)
|
||||||
|
{
|
||||||
|
var y = 0;
|
||||||
|
if (item.offsetWidth)
|
||||||
|
{
|
||||||
|
while (item && item!=document.body)
|
||||||
|
{
|
||||||
|
y += item.offsetTop;
|
||||||
|
item = item.offsetParent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* A class handling everything associated with the search panel.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
name - The name of the global variable that will be
|
||||||
|
storing this instance. Is needed to be able to set timeouts.
|
||||||
|
resultPath - path to use for external files
|
||||||
|
*/
|
||||||
|
function SearchBox(name, resultsPath, inFrame, label)
|
||||||
|
{
|
||||||
|
if (!name || !resultsPath) { alert("Missing parameters to SearchBox."); }
|
||||||
|
|
||||||
|
// ---------- Instance variables
|
||||||
|
this.name = name;
|
||||||
|
this.resultsPath = resultsPath;
|
||||||
|
this.keyTimeout = 0;
|
||||||
|
this.keyTimeoutLength = 500;
|
||||||
|
this.closeSelectionTimeout = 300;
|
||||||
|
this.lastSearchValue = "";
|
||||||
|
this.lastResultsPage = "";
|
||||||
|
this.hideTimeout = 0;
|
||||||
|
this.searchIndex = 0;
|
||||||
|
this.searchActive = false;
|
||||||
|
this.insideFrame = inFrame;
|
||||||
|
this.searchLabel = label;
|
||||||
|
|
||||||
|
// ----------- DOM Elements
|
||||||
|
|
||||||
|
this.DOMSearchField = function()
|
||||||
|
{ return document.getElementById("MSearchField"); }
|
||||||
|
|
||||||
|
this.DOMSearchSelect = function()
|
||||||
|
{ return document.getElementById("MSearchSelect"); }
|
||||||
|
|
||||||
|
this.DOMSearchSelectWindow = function()
|
||||||
|
{ return document.getElementById("MSearchSelectWindow"); }
|
||||||
|
|
||||||
|
this.DOMPopupSearchResults = function()
|
||||||
|
{ return document.getElementById("MSearchResults"); }
|
||||||
|
|
||||||
|
this.DOMPopupSearchResultsWindow = function()
|
||||||
|
{ return document.getElementById("MSearchResultsWindow"); }
|
||||||
|
|
||||||
|
this.DOMSearchClose = function()
|
||||||
|
{ return document.getElementById("MSearchClose"); }
|
||||||
|
|
||||||
|
this.DOMSearchBox = function()
|
||||||
|
{ return document.getElementById("MSearchBox"); }
|
||||||
|
|
||||||
|
// ------------ Event Handlers
|
||||||
|
|
||||||
|
// Called when focus is added or removed from the search field.
|
||||||
|
this.OnSearchFieldFocus = function(isActive)
|
||||||
|
{
|
||||||
|
this.Activate(isActive);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.OnSearchSelectShow = function()
|
||||||
|
{
|
||||||
|
var searchSelectWindow = this.DOMSearchSelectWindow();
|
||||||
|
var searchField = this.DOMSearchSelect();
|
||||||
|
|
||||||
|
if (this.insideFrame)
|
||||||
|
{
|
||||||
|
var left = getXPos(searchField);
|
||||||
|
var top = getYPos(searchField);
|
||||||
|
left += searchField.offsetWidth + 6;
|
||||||
|
top += searchField.offsetHeight;
|
||||||
|
|
||||||
|
// show search selection popup
|
||||||
|
searchSelectWindow.style.display='block';
|
||||||
|
left -= searchSelectWindow.offsetWidth;
|
||||||
|
searchSelectWindow.style.left = left + 'px';
|
||||||
|
searchSelectWindow.style.top = top + 'px';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var left = getXPos(searchField);
|
||||||
|
var top = getYPos(searchField);
|
||||||
|
top += searchField.offsetHeight;
|
||||||
|
|
||||||
|
// show search selection popup
|
||||||
|
searchSelectWindow.style.display='block';
|
||||||
|
searchSelectWindow.style.left = left + 'px';
|
||||||
|
searchSelectWindow.style.top = top + 'px';
|
||||||
|
}
|
||||||
|
|
||||||
|
// stop selection hide timer
|
||||||
|
if (this.hideTimeout)
|
||||||
|
{
|
||||||
|
clearTimeout(this.hideTimeout);
|
||||||
|
this.hideTimeout=0;
|
||||||
|
}
|
||||||
|
return false; // to avoid "image drag" default event
|
||||||
|
}
|
||||||
|
|
||||||
|
this.OnSearchSelectHide = function()
|
||||||
|
{
|
||||||
|
this.hideTimeout = setTimeout(this.name +".CloseSelectionWindow()",
|
||||||
|
this.closeSelectionTimeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called when the content of the search field is changed.
|
||||||
|
this.OnSearchFieldChange = function(evt)
|
||||||
|
{
|
||||||
|
if (this.keyTimeout) // kill running timer
|
||||||
|
{
|
||||||
|
clearTimeout(this.keyTimeout);
|
||||||
|
this.keyTimeout = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
var e = (evt) ? evt : window.event; // for IE
|
||||||
|
if (e.keyCode==40 || e.keyCode==13)
|
||||||
|
{
|
||||||
|
if (e.shiftKey==1)
|
||||||
|
{
|
||||||
|
this.OnSearchSelectShow();
|
||||||
|
var win=this.DOMSearchSelectWindow();
|
||||||
|
for (i=0;i<win.childNodes.length;i++)
|
||||||
|
{
|
||||||
|
var child = win.childNodes[i]; // get span within a
|
||||||
|
if (child.className=='SelectItem')
|
||||||
|
{
|
||||||
|
child.focus();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
window.frames.MSearchResults.postMessage("take_focus", "*");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (e.keyCode==27) // Escape out of the search field
|
||||||
|
{
|
||||||
|
this.DOMSearchField().blur();
|
||||||
|
this.DOMPopupSearchResultsWindow().style.display = 'none';
|
||||||
|
this.DOMSearchClose().style.display = 'none';
|
||||||
|
this.lastSearchValue = '';
|
||||||
|
this.Activate(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// strip whitespaces
|
||||||
|
var searchValue = this.DOMSearchField().value.replace(/ +/g, "");
|
||||||
|
|
||||||
|
if (searchValue != this.lastSearchValue) // search value has changed
|
||||||
|
{
|
||||||
|
if (searchValue != "") // non-empty search
|
||||||
|
{
|
||||||
|
// set timer for search update
|
||||||
|
this.keyTimeout = setTimeout(this.name + '.Search()',
|
||||||
|
this.keyTimeoutLength);
|
||||||
|
}
|
||||||
|
else // empty search field
|
||||||
|
{
|
||||||
|
this.DOMPopupSearchResultsWindow().style.display = 'none';
|
||||||
|
this.DOMSearchClose().style.display = 'none';
|
||||||
|
this.lastSearchValue = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.SelectItemCount = function(id)
|
||||||
|
{
|
||||||
|
var count=0;
|
||||||
|
var win=this.DOMSearchSelectWindow();
|
||||||
|
for (i=0;i<win.childNodes.length;i++)
|
||||||
|
{
|
||||||
|
var child = win.childNodes[i]; // get span within a
|
||||||
|
if (child.className=='SelectItem')
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.SelectItemSet = function(id)
|
||||||
|
{
|
||||||
|
var i,j=0;
|
||||||
|
var win=this.DOMSearchSelectWindow();
|
||||||
|
for (i=0;i<win.childNodes.length;i++)
|
||||||
|
{
|
||||||
|
var child = win.childNodes[i]; // get span within a
|
||||||
|
if (child.className=='SelectItem')
|
||||||
|
{
|
||||||
|
var node = child.firstChild;
|
||||||
|
if (j==id)
|
||||||
|
{
|
||||||
|
node.innerHTML='•';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
node.innerHTML=' ';
|
||||||
|
}
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called when an search filter selection is made.
|
||||||
|
// set item with index id as the active item
|
||||||
|
this.OnSelectItem = function(id)
|
||||||
|
{
|
||||||
|
this.searchIndex = id;
|
||||||
|
this.SelectItemSet(id);
|
||||||
|
var searchValue = this.DOMSearchField().value.replace(/ +/g, "");
|
||||||
|
if (searchValue!="" && this.searchActive) // something was found -> do a search
|
||||||
|
{
|
||||||
|
this.Search();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.OnSearchSelectKey = function(evt)
|
||||||
|
{
|
||||||
|
var e = (evt) ? evt : window.event; // for IE
|
||||||
|
if (e.keyCode==40 && this.searchIndex<this.SelectItemCount()) // Down
|
||||||
|
{
|
||||||
|
this.searchIndex++;
|
||||||
|
this.OnSelectItem(this.searchIndex);
|
||||||
|
}
|
||||||
|
else if (e.keyCode==38 && this.searchIndex>0) // Up
|
||||||
|
{
|
||||||
|
this.searchIndex--;
|
||||||
|
this.OnSelectItem(this.searchIndex);
|
||||||
|
}
|
||||||
|
else if (e.keyCode==13 || e.keyCode==27)
|
||||||
|
{
|
||||||
|
this.OnSelectItem(this.searchIndex);
|
||||||
|
this.CloseSelectionWindow();
|
||||||
|
this.DOMSearchField().focus();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------- Actions
|
||||||
|
|
||||||
|
// Closes the results window.
|
||||||
|
this.CloseResultsWindow = function()
|
||||||
|
{
|
||||||
|
this.DOMPopupSearchResultsWindow().style.display = 'none';
|
||||||
|
this.DOMSearchClose().style.display = 'none';
|
||||||
|
this.Activate(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.CloseSelectionWindow = function()
|
||||||
|
{
|
||||||
|
this.DOMSearchSelectWindow().style.display = 'none';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Performs a search.
|
||||||
|
this.Search = function()
|
||||||
|
{
|
||||||
|
this.keyTimeout = 0;
|
||||||
|
|
||||||
|
// strip leading whitespace
|
||||||
|
var searchValue = this.DOMSearchField().value.replace(/^ +/, "");
|
||||||
|
|
||||||
|
var code = searchValue.toLowerCase().charCodeAt(0);
|
||||||
|
var idxChar = searchValue.substr(0, 1).toLowerCase();
|
||||||
|
if ( 0xD800 <= code && code <= 0xDBFF && searchValue > 1) // surrogate pair
|
||||||
|
{
|
||||||
|
idxChar = searchValue.substr(0, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
var resultsPage;
|
||||||
|
var resultsPageWithSearch;
|
||||||
|
var hasResultsPage;
|
||||||
|
|
||||||
|
var idx = indexSectionsWithContent[this.searchIndex].indexOf(idxChar);
|
||||||
|
if (idx!=-1)
|
||||||
|
{
|
||||||
|
var hexCode=idx.toString(16);
|
||||||
|
resultsPage = this.resultsPath + '/' + indexSectionNames[this.searchIndex] + '_' + hexCode + '.html';
|
||||||
|
resultsPageWithSearch = resultsPage+'?'+escape(searchValue);
|
||||||
|
hasResultsPage = true;
|
||||||
|
}
|
||||||
|
else // nothing available for this search term
|
||||||
|
{
|
||||||
|
resultsPage = this.resultsPath + '/nomatches.html';
|
||||||
|
resultsPageWithSearch = resultsPage;
|
||||||
|
hasResultsPage = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.frames.MSearchResults.location = resultsPageWithSearch;
|
||||||
|
var domPopupSearchResultsWindow = this.DOMPopupSearchResultsWindow();
|
||||||
|
|
||||||
|
if (domPopupSearchResultsWindow.style.display!='block')
|
||||||
|
{
|
||||||
|
var domSearchBox = this.DOMSearchBox();
|
||||||
|
this.DOMSearchClose().style.display = 'inline';
|
||||||
|
if (this.insideFrame)
|
||||||
|
{
|
||||||
|
var domPopupSearchResults = this.DOMPopupSearchResults();
|
||||||
|
domPopupSearchResultsWindow.style.position = 'relative';
|
||||||
|
domPopupSearchResultsWindow.style.display = 'block';
|
||||||
|
var width = document.body.clientWidth - 8; // the -8 is for IE :-(
|
||||||
|
domPopupSearchResultsWindow.style.width = width + 'px';
|
||||||
|
domPopupSearchResults.style.width = width + 'px';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var domPopupSearchResults = this.DOMPopupSearchResults();
|
||||||
|
var left = getXPos(domSearchBox) + 150; // domSearchBox.offsetWidth;
|
||||||
|
var top = getYPos(domSearchBox) + 20; // domSearchBox.offsetHeight + 1;
|
||||||
|
domPopupSearchResultsWindow.style.display = 'block';
|
||||||
|
left -= domPopupSearchResults.offsetWidth;
|
||||||
|
domPopupSearchResultsWindow.style.top = top + 'px';
|
||||||
|
domPopupSearchResultsWindow.style.left = left + 'px';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.lastSearchValue = searchValue;
|
||||||
|
this.lastResultsPage = resultsPage;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------- Activation Functions
|
||||||
|
|
||||||
|
// Activates or deactivates the search panel, resetting things to
|
||||||
|
// their default values if necessary.
|
||||||
|
this.Activate = function(isActive)
|
||||||
|
{
|
||||||
|
if (isActive || // open it
|
||||||
|
this.DOMPopupSearchResultsWindow().style.display == 'block'
|
||||||
|
)
|
||||||
|
{
|
||||||
|
this.DOMSearchBox().className = 'MSearchBoxActive';
|
||||||
|
|
||||||
|
var searchField = this.DOMSearchField();
|
||||||
|
|
||||||
|
if (searchField.value == this.searchLabel) // clear "Search" term upon entry
|
||||||
|
{
|
||||||
|
searchField.value = '';
|
||||||
|
this.searchActive = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!isActive) // directly remove the panel
|
||||||
|
{
|
||||||
|
this.DOMSearchBox().className = 'MSearchBoxInactive';
|
||||||
|
this.DOMSearchField().value = this.searchLabel;
|
||||||
|
this.searchActive = false;
|
||||||
|
this.lastSearchValue = ''
|
||||||
|
this.lastResultsPage = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------
|
||||||
|
|
||||||
|
// The class that handles everything on the search results page.
|
||||||
|
function SearchResults(name)
|
||||||
|
{
|
||||||
|
// The number of matches from the last run of <Search()>.
|
||||||
|
this.lastMatchCount = 0;
|
||||||
|
this.lastKey = 0;
|
||||||
|
this.repeatOn = false;
|
||||||
|
|
||||||
|
// Toggles the visibility of the passed element ID.
|
||||||
|
this.FindChildElement = function(id)
|
||||||
|
{
|
||||||
|
var parentElement = document.getElementById(id);
|
||||||
|
var element = parentElement.firstChild;
|
||||||
|
|
||||||
|
while (element && element!=parentElement)
|
||||||
|
{
|
||||||
|
if (element.nodeName == 'DIV' && element.className == 'SRChildren')
|
||||||
|
{
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (element.nodeName == 'DIV' && element.hasChildNodes())
|
||||||
|
{
|
||||||
|
element = element.firstChild;
|
||||||
|
}
|
||||||
|
else if (element.nextSibling)
|
||||||
|
{
|
||||||
|
element = element.nextSibling;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
element = element.parentNode;
|
||||||
|
}
|
||||||
|
while (element && element!=parentElement && !element.nextSibling);
|
||||||
|
|
||||||
|
if (element && element!=parentElement)
|
||||||
|
{
|
||||||
|
element = element.nextSibling;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.Toggle = function(id)
|
||||||
|
{
|
||||||
|
var element = this.FindChildElement(id);
|
||||||
|
if (element)
|
||||||
|
{
|
||||||
|
if (element.style.display == 'block')
|
||||||
|
{
|
||||||
|
element.style.display = 'none';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
element.style.display = 'block';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Searches for the passed string. If there is no parameter,
|
||||||
|
// it takes it from the URL query.
|
||||||
|
//
|
||||||
|
// Always returns true, since other documents may try to call it
|
||||||
|
// and that may or may not be possible.
|
||||||
|
this.Search = function(search)
|
||||||
|
{
|
||||||
|
if (!search) // get search word from URL
|
||||||
|
{
|
||||||
|
search = window.location.search;
|
||||||
|
search = search.substring(1); // Remove the leading '?'
|
||||||
|
search = unescape(search);
|
||||||
|
}
|
||||||
|
|
||||||
|
search = search.replace(/^ +/, ""); // strip leading spaces
|
||||||
|
search = search.replace(/ +$/, ""); // strip trailing spaces
|
||||||
|
search = search.toLowerCase();
|
||||||
|
search = convertToId(search);
|
||||||
|
|
||||||
|
var resultRows = document.getElementsByTagName("div");
|
||||||
|
var matches = 0;
|
||||||
|
|
||||||
|
var i = 0;
|
||||||
|
while (i < resultRows.length)
|
||||||
|
{
|
||||||
|
var row = resultRows.item(i);
|
||||||
|
if (row.className == "SRResult")
|
||||||
|
{
|
||||||
|
var rowMatchName = row.id.toLowerCase();
|
||||||
|
rowMatchName = rowMatchName.replace(/^sr\d*_/, ''); // strip 'sr123_'
|
||||||
|
|
||||||
|
if (search.length<=rowMatchName.length &&
|
||||||
|
rowMatchName.substr(0, search.length)==search)
|
||||||
|
{
|
||||||
|
row.style.display = 'block';
|
||||||
|
matches++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
row.style.display = 'none';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
document.getElementById("Searching").style.display='none';
|
||||||
|
if (matches == 0) // no results
|
||||||
|
{
|
||||||
|
document.getElementById("NoMatches").style.display='block';
|
||||||
|
}
|
||||||
|
else // at least one result
|
||||||
|
{
|
||||||
|
document.getElementById("NoMatches").style.display='none';
|
||||||
|
}
|
||||||
|
this.lastMatchCount = matches;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// return the first item with index index or higher that is visible
|
||||||
|
this.NavNext = function(index)
|
||||||
|
{
|
||||||
|
var focusItem;
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
var focusName = 'Item'+index;
|
||||||
|
focusItem = document.getElementById(focusName);
|
||||||
|
if (focusItem && focusItem.parentNode.parentNode.style.display=='block')
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (!focusItem) // last element
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
focusItem=null;
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
return focusItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.NavPrev = function(index)
|
||||||
|
{
|
||||||
|
var focusItem;
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
var focusName = 'Item'+index;
|
||||||
|
focusItem = document.getElementById(focusName);
|
||||||
|
if (focusItem && focusItem.parentNode.parentNode.style.display=='block')
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (!focusItem) // last element
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
focusItem=null;
|
||||||
|
index--;
|
||||||
|
}
|
||||||
|
return focusItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.ProcessKeys = function(e)
|
||||||
|
{
|
||||||
|
if (e.type == "keydown")
|
||||||
|
{
|
||||||
|
this.repeatOn = false;
|
||||||
|
this.lastKey = e.keyCode;
|
||||||
|
}
|
||||||
|
else if (e.type == "keypress")
|
||||||
|
{
|
||||||
|
if (!this.repeatOn)
|
||||||
|
{
|
||||||
|
if (this.lastKey) this.repeatOn = true;
|
||||||
|
return false; // ignore first keypress after keydown
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (e.type == "keyup")
|
||||||
|
{
|
||||||
|
this.lastKey = 0;
|
||||||
|
this.repeatOn = false;
|
||||||
|
}
|
||||||
|
return this.lastKey!=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.Nav = function(evt,itemIndex)
|
||||||
|
{
|
||||||
|
var e = (evt) ? evt : window.event; // for IE
|
||||||
|
if (e.keyCode==13) return true;
|
||||||
|
if (!this.ProcessKeys(e)) return false;
|
||||||
|
|
||||||
|
if (this.lastKey==38) // Up
|
||||||
|
{
|
||||||
|
var newIndex = itemIndex-1;
|
||||||
|
var focusItem = this.NavPrev(newIndex);
|
||||||
|
if (focusItem)
|
||||||
|
{
|
||||||
|
var child = this.FindChildElement(focusItem.parentNode.parentNode.id);
|
||||||
|
if (child && child.style.display == 'block') // children visible
|
||||||
|
{
|
||||||
|
var n=0;
|
||||||
|
var tmpElem;
|
||||||
|
while (1) // search for last child
|
||||||
|
{
|
||||||
|
tmpElem = document.getElementById('Item'+newIndex+'_c'+n);
|
||||||
|
if (tmpElem)
|
||||||
|
{
|
||||||
|
focusItem = tmpElem;
|
||||||
|
}
|
||||||
|
else // found it!
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (focusItem)
|
||||||
|
{
|
||||||
|
focusItem.focus();
|
||||||
|
}
|
||||||
|
else // return focus to search field
|
||||||
|
{
|
||||||
|
parent.document.getElementById("MSearchField").focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (this.lastKey==40) // Down
|
||||||
|
{
|
||||||
|
var newIndex = itemIndex+1;
|
||||||
|
var focusItem;
|
||||||
|
var item = document.getElementById('Item'+itemIndex);
|
||||||
|
var elem = this.FindChildElement(item.parentNode.parentNode.id);
|
||||||
|
if (elem && elem.style.display == 'block') // children visible
|
||||||
|
{
|
||||||
|
focusItem = document.getElementById('Item'+itemIndex+'_c0');
|
||||||
|
}
|
||||||
|
if (!focusItem) focusItem = this.NavNext(newIndex);
|
||||||
|
if (focusItem) focusItem.focus();
|
||||||
|
}
|
||||||
|
else if (this.lastKey==39) // Right
|
||||||
|
{
|
||||||
|
var item = document.getElementById('Item'+itemIndex);
|
||||||
|
var elem = this.FindChildElement(item.parentNode.parentNode.id);
|
||||||
|
if (elem) elem.style.display = 'block';
|
||||||
|
}
|
||||||
|
else if (this.lastKey==37) // Left
|
||||||
|
{
|
||||||
|
var item = document.getElementById('Item'+itemIndex);
|
||||||
|
var elem = this.FindChildElement(item.parentNode.parentNode.id);
|
||||||
|
if (elem) elem.style.display = 'none';
|
||||||
|
}
|
||||||
|
else if (this.lastKey==27) // Escape
|
||||||
|
{
|
||||||
|
parent.searchBox.CloseResultsWindow();
|
||||||
|
parent.document.getElementById("MSearchField").focus();
|
||||||
|
}
|
||||||
|
else if (this.lastKey==13) // Enter
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.NavChild = function(evt,itemIndex,childIndex)
|
||||||
|
{
|
||||||
|
var e = (evt) ? evt : window.event; // for IE
|
||||||
|
if (e.keyCode==13) return true;
|
||||||
|
if (!this.ProcessKeys(e)) return false;
|
||||||
|
|
||||||
|
if (this.lastKey==38) // Up
|
||||||
|
{
|
||||||
|
if (childIndex>0)
|
||||||
|
{
|
||||||
|
var newIndex = childIndex-1;
|
||||||
|
document.getElementById('Item'+itemIndex+'_c'+newIndex).focus();
|
||||||
|
}
|
||||||
|
else // already at first child, jump to parent
|
||||||
|
{
|
||||||
|
document.getElementById('Item'+itemIndex).focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (this.lastKey==40) // Down
|
||||||
|
{
|
||||||
|
var newIndex = childIndex+1;
|
||||||
|
var elem = document.getElementById('Item'+itemIndex+'_c'+newIndex);
|
||||||
|
if (!elem) // last child, jump to parent next parent
|
||||||
|
{
|
||||||
|
elem = this.NavNext(itemIndex+1);
|
||||||
|
}
|
||||||
|
if (elem)
|
||||||
|
{
|
||||||
|
elem.focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (this.lastKey==27) // Escape
|
||||||
|
{
|
||||||
|
parent.searchBox.CloseResultsWindow();
|
||||||
|
parent.document.getElementById("MSearchField").focus();
|
||||||
|
}
|
||||||
|
else if (this.lastKey==13) // Enter
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setKeyActions(elem,action)
|
||||||
|
{
|
||||||
|
elem.setAttribute('onkeydown',action);
|
||||||
|
elem.setAttribute('onkeypress',action);
|
||||||
|
elem.setAttribute('onkeyup',action);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setClassAttr(elem,attr)
|
||||||
|
{
|
||||||
|
elem.setAttribute('class',attr);
|
||||||
|
elem.setAttribute('className',attr);
|
||||||
|
}
|
||||||
|
|
||||||
|
function createResults()
|
||||||
|
{
|
||||||
|
var results = document.getElementById("SRResults");
|
||||||
|
for (var e=0; e<searchData.length; e++)
|
||||||
|
{
|
||||||
|
var id = searchData[e][0];
|
||||||
|
var srResult = document.createElement('div');
|
||||||
|
srResult.setAttribute('id','SR_'+id);
|
||||||
|
setClassAttr(srResult,'SRResult');
|
||||||
|
var srEntry = document.createElement('div');
|
||||||
|
setClassAttr(srEntry,'SREntry');
|
||||||
|
var srLink = document.createElement('a');
|
||||||
|
srLink.setAttribute('id','Item'+e);
|
||||||
|
setKeyActions(srLink,'return searchResults.Nav(event,'+e+')');
|
||||||
|
setClassAttr(srLink,'SRSymbol');
|
||||||
|
srLink.innerHTML = searchData[e][1][0];
|
||||||
|
srEntry.appendChild(srLink);
|
||||||
|
if (searchData[e][1].length==2) // single result
|
||||||
|
{
|
||||||
|
srLink.setAttribute('href',searchData[e][1][1][0]);
|
||||||
|
if (searchData[e][1][1][1])
|
||||||
|
{
|
||||||
|
srLink.setAttribute('target','_parent');
|
||||||
|
}
|
||||||
|
var srScope = document.createElement('span');
|
||||||
|
setClassAttr(srScope,'SRScope');
|
||||||
|
srScope.innerHTML = searchData[e][1][1][2];
|
||||||
|
srEntry.appendChild(srScope);
|
||||||
|
}
|
||||||
|
else // multiple results
|
||||||
|
{
|
||||||
|
srLink.setAttribute('href','javascript:searchResults.Toggle("SR_'+id+'")');
|
||||||
|
var srChildren = document.createElement('div');
|
||||||
|
setClassAttr(srChildren,'SRChildren');
|
||||||
|
for (var c=0; c<searchData[e][1].length-1; c++)
|
||||||
|
{
|
||||||
|
var srChild = document.createElement('a');
|
||||||
|
srChild.setAttribute('id','Item'+e+'_c'+c);
|
||||||
|
setKeyActions(srChild,'return searchResults.NavChild(event,'+e+','+c+')');
|
||||||
|
setClassAttr(srChild,'SRScope');
|
||||||
|
srChild.setAttribute('href',searchData[e][1][c+1][0]);
|
||||||
|
if (searchData[e][1][c+1][1])
|
||||||
|
{
|
||||||
|
srChild.setAttribute('target','_parent');
|
||||||
|
}
|
||||||
|
srChild.innerHTML = searchData[e][1][c+1][2];
|
||||||
|
srChildren.appendChild(srChild);
|
||||||
|
}
|
||||||
|
srEntry.appendChild(srChildren);
|
||||||
|
}
|
||||||
|
srResult.appendChild(srEntry);
|
||||||
|
results.appendChild(srResult);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function init_search()
|
||||||
|
{
|
||||||
|
var results = document.getElementById("MSearchSelectWindow");
|
||||||
|
for (var key in indexSectionLabels)
|
||||||
|
{
|
||||||
|
var link = document.createElement('a');
|
||||||
|
link.setAttribute('class','SelectItem');
|
||||||
|
link.setAttribute('onclick','searchBox.OnSelectItem('+key+')');
|
||||||
|
link.href='javascript:void(0)';
|
||||||
|
link.innerHTML='<span class="SelectionMark"> </span>'+indexSectionLabels[key];
|
||||||
|
results.appendChild(link);
|
||||||
|
}
|
||||||
|
searchBox.OnSelectItem(0);
|
||||||
|
}
|
||||||
|
/* @license-end */
|
||||||
BIN
html/search/search_l.png
Normal file
|
After Width: | Height: | Size: 567 B |
BIN
html/search/search_m.png
Normal file
|
After Width: | Height: | Size: 158 B |
BIN
html/search/search_r.png
Normal file
|
After Width: | Height: | Size: 553 B |
18
html/search/searchdata.js
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
var indexSectionsWithContent =
|
||||||
|
{
|
||||||
|
0: "m",
|
||||||
|
1: "m"
|
||||||
|
};
|
||||||
|
|
||||||
|
var indexSectionNames =
|
||||||
|
{
|
||||||
|
0: "all",
|
||||||
|
1: "files"
|
||||||
|
};
|
||||||
|
|
||||||
|
var indexSectionLabels =
|
||||||
|
{
|
||||||
|
0: "All",
|
||||||
|
1: "Files"
|
||||||
|
};
|
||||||
|
|
||||||
BIN
html/splitbar.png
Normal file
|
After Width: | Height: | Size: 314 B |
BIN
html/sync_off.png
Normal file
|
After Width: | Height: | Size: 853 B |
BIN
html/sync_on.png
Normal file
|
After Width: | Height: | Size: 845 B |
BIN
html/tab_a.png
Normal file
|
After Width: | Height: | Size: 142 B |
BIN
html/tab_b.png
Normal file
|
After Width: | Height: | Size: 169 B |
BIN
html/tab_h.png
Normal file
|
After Width: | Height: | Size: 177 B |
BIN
html/tab_s.png
Normal file
|
After Width: | Height: | Size: 184 B |
1
html/tabs.css
Normal file
160
list.h
Normal file
|
|
@ -0,0 +1,160 @@
|
||||||
|
/*----------------------------------------------------------
|
||||||
|
* HTBLA-Leonding / Class: <your class>
|
||||||
|
* ---------------------------------------------------------
|
||||||
|
* Exercise Number: S01
|
||||||
|
* Title: Linked List Inteface
|
||||||
|
* Author: S. Schraml
|
||||||
|
* ----------------------------------------------------------
|
||||||
|
* Description:
|
||||||
|
* The declaration of a linked list abstract data type.
|
||||||
|
* ----------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ___LIST__H
|
||||||
|
#define ___LIST__H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
/** The type of the integer list. */
|
||||||
|
typedef struct IntListData* IntList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtains ('creates') and provides a 'new' list instance.
|
||||||
|
* Any list obtained via this function MUST be released using
|
||||||
|
* function `release_list()`.
|
||||||
|
*
|
||||||
|
* Note: This function does not make any assumptions
|
||||||
|
* about how list components, esp. nodes, are allocated.
|
||||||
|
*
|
||||||
|
* @return IntList The list instance or 0, if no list could by instantiated.
|
||||||
|
*/
|
||||||
|
IntList list_obtain();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Releases a list that was obtained earlier via function `obtain_list`.
|
||||||
|
* Released lists MUST NOT be used anymore.
|
||||||
|
*
|
||||||
|
* Note: The implementation of this function does not make any assumptions
|
||||||
|
* about the allocation method of list elements, but MUST match the implementation
|
||||||
|
* of function `obtain_list` as its inverse function.
|
||||||
|
*
|
||||||
|
* @param p_list The pointer to the list to release. The value of the pointer
|
||||||
|
* is set to 0, if the list was successfully released, otherwise it is left untouched.
|
||||||
|
*/
|
||||||
|
void list_release(IntList* p_list);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines whether or not the given list is valid.
|
||||||
|
*
|
||||||
|
* @param list The list to evaluate.
|
||||||
|
* @return `True` if the list is valid, false otherwise.
|
||||||
|
*/
|
||||||
|
bool list_is_valid(IntList list);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines whether or not the list contains at least one item.
|
||||||
|
*
|
||||||
|
* @param list The list to evaluate.
|
||||||
|
* @return `False` if the list contains one or more items, `true` otherwise.
|
||||||
|
*/
|
||||||
|
bool list_is_empty(IntList list);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the number of values stored in the list.
|
||||||
|
*
|
||||||
|
* @param list The list to evaluate.
|
||||||
|
* @return The number of values the list contains.
|
||||||
|
*/
|
||||||
|
int list_get_size(IntList list);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines whether or not the list given list contains the queried value
|
||||||
|
* at least once.
|
||||||
|
*
|
||||||
|
* @param list The list to query.
|
||||||
|
* @param value The value.
|
||||||
|
* @return `True` if the list contains at least one instance of the value,
|
||||||
|
* `false ` otherwise.
|
||||||
|
*/
|
||||||
|
bool list_contains(IntList list, int value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the value stored in the list at the given position.
|
||||||
|
*
|
||||||
|
* @param list The list from which the value shall be retrieved.
|
||||||
|
* @param index The zero-based position index of the value to retrieve.
|
||||||
|
* @return The value stored at the given position or 0, if the position
|
||||||
|
* is not available.
|
||||||
|
*/
|
||||||
|
int list_get_at(IntList list, unsigned int index);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts the given value at the end of the given list.
|
||||||
|
*
|
||||||
|
* @param list The list to which the value shall be appended.
|
||||||
|
* @param value The value to append to the list.
|
||||||
|
*/
|
||||||
|
void list_insert(IntList list, int value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts the given value at the indexed position in a way the
|
||||||
|
* the inserted value is on that position. The index is
|
||||||
|
* - similar to arrays - zero-based. If the the list is shorter
|
||||||
|
* than the indexed position, the value is inserted at the end
|
||||||
|
* of the list.
|
||||||
|
*
|
||||||
|
* @param list The list into which the value shall be appended.
|
||||||
|
* @param index The position index of the value to insert.
|
||||||
|
* @param value The value to insert.
|
||||||
|
*/
|
||||||
|
void list_insert_at(IntList list, unsigned int index, int value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Appends the `list_to_append` at the end of the given `list`.
|
||||||
|
* The appended list is empty afterwards, because all nodes of that list
|
||||||
|
* have been transferred to `list`.
|
||||||
|
*
|
||||||
|
* @param list The list that receives the other list.
|
||||||
|
* @param list_to_append The list that is appended to `list`.
|
||||||
|
*/
|
||||||
|
void list_append(IntList list, IntList list_to_append);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the first occurrance of `value` from the given list.
|
||||||
|
* If the list does not contain that value, the list shall not
|
||||||
|
* be modified.
|
||||||
|
*
|
||||||
|
* @param list The list from which the given value shall be removed.
|
||||||
|
* @param value The value to remove from the list.
|
||||||
|
*/
|
||||||
|
void list_remove(IntList list, int value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes all occurrances of `value` from the list.
|
||||||
|
* If the list does not contain that value, the list shall not
|
||||||
|
* be modified.
|
||||||
|
*
|
||||||
|
* @param list The list from which all occurrances of `value` shall be removed.
|
||||||
|
* @param value The `value` to remove throughout the list.
|
||||||
|
*/
|
||||||
|
void list_remove_all(IntList list, int value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the value at the indexed position from the given list
|
||||||
|
* and provides that value. If the list does not have a value
|
||||||
|
* at that position, the list remains unmodified.
|
||||||
|
*
|
||||||
|
* @param list The list from which the value at the given index shall be returned.
|
||||||
|
* @param index The zero-based index of the value to return.
|
||||||
|
* @return The removed value or 0 in case of errors.
|
||||||
|
*/
|
||||||
|
int list_remove_at(IntList list, unsigned int index);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears the given list by removing all values from the list.
|
||||||
|
*
|
||||||
|
* @param list The list to clear.
|
||||||
|
*/
|
||||||
|
void list_clear(IntList list);
|
||||||
|
|
||||||
|
#endif
|
||||||
17
list_main_driver.c
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
/*-----------------------------------------------------------------------------
|
||||||
|
* HTBLA-Leonding / Class: <your class name here>
|
||||||
|
*-----------------------------------------------------------------------------
|
||||||
|
* Exercise Number: S01
|
||||||
|
*-----------------------------------------------------------------------------
|
||||||
|
* Description:
|
||||||
|
* The assignment does not require to implement an application.
|
||||||
|
* Run 'make test' to build and execute all required unit tests.
|
||||||
|
*-----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
printf("The assignment does not require to implement an application.\n");
|
||||||
|
printf("Run 'make test' to build and execute all required unit tests.\n");
|
||||||
|
}
|
||||||
102
list_test_driver.c
Normal file
|
|
@ -0,0 +1,102 @@
|
||||||
|
/*----------------------------------------------------------
|
||||||
|
* HTBLA-Leonding
|
||||||
|
* ---------------------------------------------------------
|
||||||
|
* Title: Tests implementation of a Liked List.
|
||||||
|
* Author: S. Schraml
|
||||||
|
* ----------------------------------------------------------
|
||||||
|
* Description:
|
||||||
|
* Unit tests for a linked list implemenation.
|
||||||
|
* ----------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "shortcut.h"
|
||||||
|
#include "test_list.h"
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
ADD_TEST(test_list_obtain__shall_allocate_a_list);
|
||||||
|
ADD_TEST(test_list_obtain__shall_allocate_a_fresh_list);
|
||||||
|
ADD_TEST(test_list_obtain__shall_allocate_a_different_list);
|
||||||
|
ADD_TEST(test_list_obtain_failed__shall_not_allocate_a_list);
|
||||||
|
|
||||||
|
ADD_TEST(test_list_release__shall_release_a_valid_empty_list);
|
||||||
|
ADD_TEST(test_list_release__shall_release_a_valid_filled_list);
|
||||||
|
ADD_TEST(test_list_release__shall_ignore_release_of_an_invalid_list);
|
||||||
|
|
||||||
|
ADD_TEST(test_list_is_valid__shall_be_true_for_valid_list);
|
||||||
|
ADD_TEST(test_list_is_valid__shall_be_false_for_invalid_list);
|
||||||
|
|
||||||
|
ADD_TEST(test_list_insert__shall_add_one_value_to_empty_list);
|
||||||
|
ADD_TEST(test_list_insert__shall_add_multiple_values);
|
||||||
|
ADD_TEST(test_list_insert__shall_ignore_invalid_list);
|
||||||
|
|
||||||
|
ADD_TEST(test_list_remove__shall_not_remove_from_empty_list);
|
||||||
|
ADD_TEST(test_list_remove__shall_remove_only_value);
|
||||||
|
ADD_TEST(test_list_remove__shall_remove_one_value);
|
||||||
|
ADD_TEST(test_list_remove__shall_remove_first_value);
|
||||||
|
ADD_TEST(test_list_remove__shall_remove_value_in_the_middle);
|
||||||
|
ADD_TEST(test_list_remove__shall_remove_value_at_the_end);
|
||||||
|
ADD_TEST(test_list_remove__shall_not_remove_missing_value);
|
||||||
|
|
||||||
|
ADD_TEST(test_list_remove_all__shall_not_remove_from_empty_list);
|
||||||
|
ADD_TEST(test_list_remove_all__shall_remove_only_value);
|
||||||
|
ADD_TEST(test_list_remove_all__shall_remove_all_values);
|
||||||
|
ADD_TEST(test_list_remove_all__shall_remove_one_value);
|
||||||
|
ADD_TEST(test_list_remove_all__shall_remove_all_values_in_a_row);
|
||||||
|
ADD_TEST(test_list_remove_all__shall_remove_all_distributed_values);
|
||||||
|
ADD_TEST(test_list_remove_all__shall_not_remove_missing_value);
|
||||||
|
ADD_TEST(test_list_remove_all__shall_ignore_invalid_list);
|
||||||
|
|
||||||
|
ADD_TEST(test_list_insert_at__shall_insert_single_value_in_empty_list);
|
||||||
|
ADD_TEST(test_list_insert_at__shall_insert_value_at_the_beginning);
|
||||||
|
ADD_TEST(test_list_insert_at__shall_insert_value_in_the_middle);
|
||||||
|
ADD_TEST(test_list_insert_at__shall_insert_value_at_the_end);
|
||||||
|
ADD_TEST(test_list_insert_at__shall_insert_value_after_the_end);
|
||||||
|
ADD_TEST(test_list_insert_at__shall_ignore_invalid_list);
|
||||||
|
|
||||||
|
ADD_TEST(test_list_remove_at__shall_not_remove_from_empty_list);
|
||||||
|
ADD_TEST(test_list_remove_at__shall_remove_value_at_the_beginning);
|
||||||
|
ADD_TEST(test_list_remove_at__shall_remove_value_in_the_middle);
|
||||||
|
ADD_TEST(test_list_remove_at__shall_not_remove_from_empty_list);
|
||||||
|
ADD_TEST(test_list_remove_at__shall_remove_value_at_the_end);
|
||||||
|
ADD_TEST(test_list_remove_at__shall_not_remove_value_after_the_end);
|
||||||
|
ADD_TEST(test_list_remove_at__shall_ignore_invalid_list);
|
||||||
|
|
||||||
|
ADD_TEST(test_list_clear__shall_clear_empty_list);
|
||||||
|
ADD_TEST(test_list_clear__shall_clear_list_with_one_value);
|
||||||
|
ADD_TEST(test_list_clear__shall_clear_list_with_multiple_values);
|
||||||
|
ADD_TEST(test_list_clear__shall_ingore_invalid_list);
|
||||||
|
|
||||||
|
ADD_TEST(test_list_is_empty__shall_be_true__for_newly_obtained_list);
|
||||||
|
ADD_TEST(test_list_is_empty__shall_be_false__after_adding_values);
|
||||||
|
ADD_TEST(test_list_is_empty__shall_be_true_for_invalid_list);
|
||||||
|
|
||||||
|
ADD_TEST(test_list_get_size__shall_be_0_for_newly_obtained_list);
|
||||||
|
ADD_TEST(test_list_get_size__shall_reflect_number_of_values_after_adding_values);
|
||||||
|
ADD_TEST(test_list_get_size__shall_reflect_number_of_values_after_removing_values);
|
||||||
|
ADD_TEST(test_list_get_size__shall_be_0_after_clear);
|
||||||
|
ADD_TEST(test_list_get_size__shall_be_0_for_invalid_list);
|
||||||
|
|
||||||
|
ADD_TEST(test_list_contains__shall_be_false_for_empty_list);
|
||||||
|
ADD_TEST(test_list_contains__shall_be_true_for_one_value);
|
||||||
|
ADD_TEST(test_list_contains__shall_be_true_for_multiple_values);
|
||||||
|
ADD_TEST(test_list_contains__shall_be_false_form_missing_value);
|
||||||
|
ADD_TEST(test_list_contains__shall_be_false_for_invalid_list);
|
||||||
|
|
||||||
|
ADD_TEST(test_list_get_at__shall_return_0_for_empty_list);
|
||||||
|
ADD_TEST(test_list_get_at__shall_return_single_value);
|
||||||
|
ADD_TEST(test_list_get_at__shall_return_first_value);
|
||||||
|
ADD_TEST(test_list_get_at__shall_return_values_in_added_order);
|
||||||
|
ADD_TEST(test_list_get_at__shall_return_0_for_invalid_list);
|
||||||
|
|
||||||
|
ADD_TEST(test_list_append__shall_append_empty_list_to_empty_list);
|
||||||
|
ADD_TEST(test_list_append__shall_append_filled_list_to_empty_list);
|
||||||
|
ADD_TEST(test_list_append__shall_append_empty_list_to_filled_list);
|
||||||
|
ADD_TEST(test_list_append__shall_append_filled_list_to_filled_list);
|
||||||
|
ADD_TEST(test_list_append__shall_ignore_invalid_lists);
|
||||||
|
|
||||||
|
run_tests();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
46
mainpage.h
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
/**
|
||||||
|
* @mainpage
|
||||||
|
* @section intro Introduction
|
||||||
|
*
|
||||||
|
* The implementation of a "Simple Singly Linked List".
|
||||||
|
*
|
||||||
|
* @section objective Assignment Objective
|
||||||
|
* In this assignment an Abstract Data Type of a "Simple Singly Linked List" shall be implemented against
|
||||||
|
* the defined common interface of a list. This interface is declared within file 'list.h'. It is intended
|
||||||
|
* to be used by applications or other libraries and aims to abstract the 'list' functionality as far as possible.
|
||||||
|
*
|
||||||
|
* The term 'simple' in 'Simple Singly Linked List' refers to the limited members of the list data:
|
||||||
|
* the pointer to the list head node is the only member of list data.
|
||||||
|
*
|
||||||
|
* **Configuration**
|
||||||
|
*
|
||||||
|
* There is no configuration required.
|
||||||
|
*
|
||||||
|
* @section assignment Assignment
|
||||||
|
* The 'Simple Singly Linked List' shall be implemented in file 'simple_singly_linked_list.c'. The corresponding header file
|
||||||
|
* includes the common interface 'list.h' but does not add functions by its own.
|
||||||
|
*
|
||||||
|
* The library 'allocator' is provided for memory allocation functionality that integrates with unit testing. Behind the facade,
|
||||||
|
* allocats memory dynamically similar to `malloc`. Allocated memory must be freed when it is not used anymore. The 'allocator'
|
||||||
|
* library must be used for memory alloction operations, otherwise unit tests will fail.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* -# Implement 'simple_singly_linked_list.c' against interface indirectly declared in 'list.h':
|
||||||
|
* Make the program and tests compile: Implement all functions in all relevant files declared in the headers
|
||||||
|
* EMTPY (return nothing, 0, false, ... as required).
|
||||||
|
* - All unit tests shall run but FAIL after this step
|
||||||
|
* - **--COMMIT--**
|
||||||
|
* -# Implement the empty functions one by one to make the unit tests pass one by one.
|
||||||
|
* - The purpose of a function is specified as API documentation within the header files.
|
||||||
|
* - Obey comments in source files. Run the unit tests frequently and fix failures.
|
||||||
|
* - **--COMMIT-- after each implemented function.**
|
||||||
|
*
|
||||||
|
* Main driver is not required in this assignment.
|
||||||
|
*
|
||||||
|
* @section notes Notes
|
||||||
|
* -# make cleantest: This new make target for clearing the console, building, and running unit test is available.
|
||||||
|
* -# Sometimes changes are not properly detected by incremental builds. If something very strange
|
||||||
|
* happens during compilation, try to run `make clean` followed by `make` to start a clean build.
|
||||||
|
* This approach is also recommended after everthing is done, because some compiler warning appears
|
||||||
|
* only in clean builds.
|
||||||
|
*/
|
||||||
99
makefile
Normal file
|
|
@ -0,0 +1,99 @@
|
||||||
|
CC = gcc
|
||||||
|
CCLINK = g++
|
||||||
|
LIBS =
|
||||||
|
CCOPTIONS = -Wall -pedantic -std=gnu11 -g
|
||||||
|
LDOPTIONS =
|
||||||
|
|
||||||
|
BUILD_DIR = build
|
||||||
|
|
||||||
|
TEST = test_simple_singly_linked_list
|
||||||
|
PROGRAM = simple_singly_linked_list
|
||||||
|
|
||||||
|
COMMON_HDRS = config.h general.h list.h
|
||||||
|
LIBRARY_FILES = shortcut allocator
|
||||||
|
ASSIGNMENT_HDRS =
|
||||||
|
ASSIGNMENT_FILES = simple_singly_linked_list
|
||||||
|
TEST_FILES = test_list
|
||||||
|
MAIN_DRIVER = list_main_driver
|
||||||
|
TEST_DRIVER = list_test_driver
|
||||||
|
|
||||||
|
LIBRARY_H = $(addsuffix .h, $(LIBRARY_FILES))
|
||||||
|
ASSIGNMENT_H = $(addsuffix .h, $(ASSIGNMENT_FILES)) $(ASSIGNMENT_HDRS)
|
||||||
|
ASSIGNMENT_C = $(addsuffix .c, $(ASSIGNMENT_FILES)) $(MAIN_DRIVER).c
|
||||||
|
|
||||||
|
HDRS = $(ASSIGNEMT_H) $(SHARED_HDRS) $(COMMON_HDRS) $(LIBRARY_H)
|
||||||
|
TESTOBJECT = $(addprefix $(BUILD_DIR)/, $(TEST_DRIVER).o)
|
||||||
|
MAINOBJECT = $(addprefix $(BUILD_DIR)/, $(MAIN_DRIVER).o)
|
||||||
|
LIBRARY_OBJS = $(addprefix $(BUILD_DIR)/, $(addsuffix .o, $(LIBRARY_FILES)))
|
||||||
|
TEST_OBJS = $(addprefix $(BUILD_DIR)/, $(addsuffix .o, $(TEST_FILES)))
|
||||||
|
MAIN_OBJ = $(addprefix $(BUILD_DIR)/, $(addsuffix .o, $(ASSIGNMENT_FILES)))
|
||||||
|
OBJS = $(LIBRARY_OBJS) $(MAIN_OBJ) $(TEST_OBJS)
|
||||||
|
|
||||||
|
DOXY = doxygen
|
||||||
|
|
||||||
|
all: $(PROGRAM)
|
||||||
|
./$(PROGRAM)
|
||||||
|
|
||||||
|
$(TEST): $(BUILD_DIR) $(OBJS) $(TESTOBJECT)
|
||||||
|
$(CCLINK) -o $@ $(LDOPTIONS) $(OBJS) $(TESTOBJECT)
|
||||||
|
|
||||||
|
$(PROGRAM): $(BUILD_DIR) $(OBJS) $(MAINOBJECT)
|
||||||
|
$(CCLINK) -o $@ $(LDOPTIONS) $(OBJS) $(MAINOBJECT)
|
||||||
|
|
||||||
|
.PHONY: clean cleanall doxy test setsample setassignment definesample defineassignment assignmentfolder
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(PROGRAM) $(TEST) $(TESTOBJECT) $(MAINOBJECT) $(OBJS)
|
||||||
|
rm -rf $(BUILD_DIR)
|
||||||
|
rm -f *.o
|
||||||
|
|
||||||
|
cleanall: clean
|
||||||
|
rm -f index.html
|
||||||
|
rm -rf html
|
||||||
|
|
||||||
|
|
||||||
|
doxy:
|
||||||
|
$(DOXY)
|
||||||
|
rm -f index.html
|
||||||
|
ln -s html/index.html index.html
|
||||||
|
|
||||||
|
test: $(TEST)
|
||||||
|
./$(TEST)
|
||||||
|
|
||||||
|
cleantest: clean
|
||||||
|
clear
|
||||||
|
make test
|
||||||
|
|
||||||
|
$(BUILD_DIR):
|
||||||
|
mkdir -p $(BUILD_DIR)
|
||||||
|
|
||||||
|
$(BUILD_DIR)/%.o: %.c
|
||||||
|
$(CC) $(CCOPTIONS) -c -o $@ $<
|
||||||
|
|
||||||
|
#sets project as sample solution
|
||||||
|
setsample:
|
||||||
|
$(foreach name, $(ASSIGNMENT_H) $(ASSIGNMENT_C), cp $(name).sample $(name);)
|
||||||
|
|
||||||
|
#sets project as assignment
|
||||||
|
setassignment:
|
||||||
|
$(foreach name, $(ASSIGNMENT_H) $(ASSIGNMENT_C), cp $(name).assignment $(name);)
|
||||||
|
|
||||||
|
# defines current state of project as sample solution
|
||||||
|
definesample:
|
||||||
|
$(foreach name, $(ASSIGNMENT_H) $(ASSIGNMENT_C), cp $(name) $(name).sample;)
|
||||||
|
|
||||||
|
# defines current sate of project as assignment
|
||||||
|
defineassignment :
|
||||||
|
$(foreach name, $(ASSIGNMENT_H) $(ASSIGNMENT_C), cp $(name) $(name).assignment;)
|
||||||
|
|
||||||
|
# creates a folder which can serve as a publishable assignment
|
||||||
|
assignmentfolder:
|
||||||
|
make setassignment
|
||||||
|
make doxy
|
||||||
|
rm -rf ../assignment
|
||||||
|
mkdir ../assignment
|
||||||
|
cp -R * ../assignment
|
||||||
|
cp .gitignore ../assignment
|
||||||
|
rm ../assignment/*.sample
|
||||||
|
rm ../assignment/*.assignment
|
||||||
|
make cleanall
|
||||||
151
shortcut.c
Normal file
|
|
@ -0,0 +1,151 @@
|
||||||
|
/*----------------------------------------------------------
|
||||||
|
* HTBLA-Leonding
|
||||||
|
* ---------------------------------------------------------
|
||||||
|
* Title: shortcut.c
|
||||||
|
* Author: P. Bauer
|
||||||
|
* Date: November 08, 2010
|
||||||
|
* ----------------------------------------------------------
|
||||||
|
* Description:
|
||||||
|
* Test driver.
|
||||||
|
* ----------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include "shortcut.h"
|
||||||
|
|
||||||
|
#define MAX_TEST_FUNCTIONS 256
|
||||||
|
|
||||||
|
static char assert_msg_buffer[1024];
|
||||||
|
static int tc_count = 0;
|
||||||
|
static int tc_fail_count = 0;
|
||||||
|
|
||||||
|
static struct TestCase test_cases[MAX_TEST_FUNCTIONS];
|
||||||
|
|
||||||
|
const char* version()
|
||||||
|
{
|
||||||
|
return "ShortCut v. 1.3.0";
|
||||||
|
}
|
||||||
|
|
||||||
|
char* format_msg(char* format, ...) {
|
||||||
|
va_list args;
|
||||||
|
va_start (args, format);
|
||||||
|
vsprintf(assert_msg_buffer, format, args);
|
||||||
|
return assert_msg_buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void assert_true(bool bool_expr, struct TestCase *tc, const char *msg,
|
||||||
|
const char* file, int line)
|
||||||
|
{
|
||||||
|
if (!bool_expr) {
|
||||||
|
if (tc->success) {
|
||||||
|
tc->success = false;
|
||||||
|
tc_fail_count++;
|
||||||
|
}
|
||||||
|
printf("\n\tFailure (file: %s, line %d): %s: %s", file, line, tc->name, msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void assert_false(bool bool_expr, struct TestCase *tc, const char *msg,
|
||||||
|
const char* file, int line)
|
||||||
|
{
|
||||||
|
assert_true(!bool_expr, tc, msg, file, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void assert_string_failure(const char *expected, char *actual, struct TestCase *tc,
|
||||||
|
const char *msg, const char* file, int line);
|
||||||
|
|
||||||
|
void assert_equals_str(const char *expected, char *actual, struct TestCase *tc,
|
||||||
|
const char *msg, const char* file, int line)
|
||||||
|
{
|
||||||
|
if (expected == actual) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expected == 0 || actual == 0) {
|
||||||
|
assert_string_failure(expected, actual, tc, msg, file, line);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(actual, expected) != 0) {
|
||||||
|
assert_string_failure(expected, actual, tc, msg, file, line);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MAX_MSG_LEN 128
|
||||||
|
static void assert_string_failure(const char *expected, char *actual, struct TestCase *tc,
|
||||||
|
const char *msg, const char* file, int line)
|
||||||
|
{
|
||||||
|
char new_msg[MAX_MSG_LEN];
|
||||||
|
|
||||||
|
sprintf(new_msg, "Expected \"%s\", actual \"%s\". %s", expected, actual, msg);
|
||||||
|
assert_true(false, tc, new_msg, file, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
void assert_equals(int expected, int actual, struct TestCase *tc,
|
||||||
|
const char *msg, const char* file, int line)
|
||||||
|
{
|
||||||
|
char new_msg[MAX_MSG_LEN];
|
||||||
|
sprintf(new_msg, "Expected %d, actual %d. %s", expected, actual, msg);
|
||||||
|
assert_true(expected == actual, tc, new_msg, file, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
void assert_equals_f(double expected, double actual, double tolerance, struct TestCase* tc,
|
||||||
|
const char* msg, const char* file, int line)
|
||||||
|
{
|
||||||
|
char new_msg[MAX_MSG_LEN];
|
||||||
|
sprintf(new_msg, "Expected %f, actual %f. %s", expected, actual, msg);
|
||||||
|
double min_val = expected - tolerance;
|
||||||
|
double max_val = expected + tolerance;
|
||||||
|
assert_true(min_val <= actual && actual <= max_val, tc, new_msg, file, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_test_count()
|
||||||
|
{
|
||||||
|
return tc_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool add_test(void (*test_function)(struct TestCase *tc), const char *test_name)
|
||||||
|
{
|
||||||
|
if (tc_count == MAX_TEST_FUNCTIONS) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
test_cases[tc_count].success = true;
|
||||||
|
test_cases[tc_count].name = test_name;
|
||||||
|
test_cases[tc_count].test_function = test_function;
|
||||||
|
tc_count++;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void run_tests()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
printf("\n%s: Running tests\n", version());
|
||||||
|
|
||||||
|
for (i = 0; i < get_test_count(); i++) {
|
||||||
|
printf("Running test %s ...", test_cases[i].name);
|
||||||
|
test_cases[i].test_function(&test_cases[i]);
|
||||||
|
if (test_cases[i].success) {
|
||||||
|
printf("\033[32m OK\033[m");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("\033[31m ... FAIL\033[m");
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\nTotal tests run: %d\n", tc_count);
|
||||||
|
if (tc_fail_count > 0) {
|
||||||
|
printf("\033[31mTests failed: %d\033[m\n", tc_fail_count);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("\033[32mAll tests run successfully\033[m\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
110
shortcut.h
Normal file
|
|
@ -0,0 +1,110 @@
|
||||||
|
/*----------------------------------------------------------
|
||||||
|
* HTBLA-Leonding
|
||||||
|
* ---------------------------------------------------------
|
||||||
|
* Title: shortcut
|
||||||
|
* Author: P. Bauer
|
||||||
|
* Date: November 03, 2010
|
||||||
|
* ----------------------------------------------------------
|
||||||
|
* Description:
|
||||||
|
* A simple unit testing frame work for C.
|
||||||
|
* ----------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#ifndef ___SHORTCUT_H
|
||||||
|
#define ___SHORTCUT_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
/** TestCase is the struct to define one test case. A test case can
|
||||||
|
*** be added to a test. If the test is run all added test cases are
|
||||||
|
*** run and the result of the run of each test case is checked automatically.
|
||||||
|
*/
|
||||||
|
struct TestCase {
|
||||||
|
const char *name;
|
||||||
|
/** true if the test passed, false otherwise. */
|
||||||
|
bool success;
|
||||||
|
|
||||||
|
/** The test function which is executed by the test framework. */
|
||||||
|
void (*test_function)(struct TestCase *tc);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*** @return Version of shortcut as string
|
||||||
|
***/
|
||||||
|
const char* version();
|
||||||
|
|
||||||
|
/**
|
||||||
|
*** @return The fromated string as generated using sprintf(format, ...)
|
||||||
|
***/
|
||||||
|
char* format_msg(char* format, ...);
|
||||||
|
|
||||||
|
/** assert_true checks, whether a boolean expression passed is true or false.
|
||||||
|
*** in case it is false the test case stating the assertion is marked
|
||||||
|
*** as failed and msg is printed.
|
||||||
|
*** @param bool_expr Expression which is evaluated.
|
||||||
|
*** @param tc Pointer to the test case which states this assertion.
|
||||||
|
*** @param msg Message to be printed if assertion evaluates to false.
|
||||||
|
*** @param file File in which the assert is given.
|
||||||
|
*** @param line Line in which the assert is given.
|
||||||
|
*/
|
||||||
|
void assert_true(bool bool_expr, struct TestCase *tc, const char *msg,
|
||||||
|
const char* file, int line);
|
||||||
|
|
||||||
|
/** assert_false does the same as assert() but the boolean expression
|
||||||
|
*** has to evaluate to false. If it evaluates to true the assertion
|
||||||
|
*** fails.
|
||||||
|
*** @see assert
|
||||||
|
*/
|
||||||
|
void assert_false(bool bool_expr, struct TestCase* tc, const char* msg,
|
||||||
|
const char* file, int line);
|
||||||
|
|
||||||
|
/** assert_equals checks whether two values are equal. Currently the following
|
||||||
|
*** data formats are supported:
|
||||||
|
*** - strings
|
||||||
|
*** - integer
|
||||||
|
*** @param expected The expected string value
|
||||||
|
*** @param actual The actual string value
|
||||||
|
*** @param tc Pointer to the test case which states this assertion.
|
||||||
|
*** @param msg Message to be printed if assertion evaluates to false.
|
||||||
|
*** @param file File in which the assert is given.
|
||||||
|
*** @param line Line in which the assert is given.
|
||||||
|
*** @see assert
|
||||||
|
*/
|
||||||
|
void assert_equals(int expected, int actual, struct TestCase* tc,
|
||||||
|
const char* msg, const char* file, int line);
|
||||||
|
void assert_equals_str(const char* expected, char* actual, struct TestCase* tc,
|
||||||
|
const char* msg, const char* file, int line);
|
||||||
|
void assert_equals_f(double expected, double actual, double tolerance, struct TestCase* tc,
|
||||||
|
const char* msg, const char* file, int line);
|
||||||
|
|
||||||
|
/** @return The total number of test cases added to the test.
|
||||||
|
*/
|
||||||
|
int get_test_count();
|
||||||
|
|
||||||
|
/** add_test creates a new test case and adds the a test function to
|
||||||
|
*** this test case.
|
||||||
|
*** @param test_function Pointer to the test function to be added
|
||||||
|
*** to the newly created test case.
|
||||||
|
*** @param test_case_name Name which should be assigned to the newly
|
||||||
|
*** created test case.
|
||||||
|
*/
|
||||||
|
bool add_test(void (*test_function)(struct TestCase *tc), const char *test_case_name);
|
||||||
|
|
||||||
|
void run_tests();
|
||||||
|
|
||||||
|
#define TEST(testname) void testname(struct TestCase *tc)
|
||||||
|
|
||||||
|
#define MSG(format, ...) format_msg(format, ##__VA_ARGS__)
|
||||||
|
|
||||||
|
#define ASSERT_TRUE(condition, msg) assert_true(condition, tc, msg, __FILE__, __LINE__)
|
||||||
|
|
||||||
|
#define ASSERT_FALSE(condition, msg) assert_false(condition, tc, msg, __FILE__, __LINE__)
|
||||||
|
|
||||||
|
#define ASSERT_EQUALS(expected, actual) assert_equals(expected, actual, tc, "", __FILE__, __LINE__)
|
||||||
|
|
||||||
|
#define ASSERT_EQUALS_STR(expected, actual) assert_equals_str(expected, actual, tc, "", __FILE__, __LINE__)
|
||||||
|
|
||||||
|
#define ASSERT_EQUALS_TOLERANCE(expected, actual, tolerance) assert_equals_f(expected, actual, tolerance, tc, "", __FILE__, __LINE__)
|
||||||
|
|
||||||
|
#define ADD_TEST(testfunction) add_test(testfunction, #testfunction)
|
||||||
|
|
||||||
|
#endif
|
||||||
57
simple_singly_linked_list.c
Normal file
|
|
@ -0,0 +1,57 @@
|
||||||
|
/*----------------------------------------------------------
|
||||||
|
* HTBLA-Leonding / Class: <your class>
|
||||||
|
* ---------------------------------------------------------
|
||||||
|
* Exercise Number: S01
|
||||||
|
* Title: Simple Singly Linked List implementation
|
||||||
|
* Author: */<your name>;/*
|
||||||
|
* ----------------------------------------------------------
|
||||||
|
* Description:
|
||||||
|
* Implementation of a simple singly linked list.
|
||||||
|
* ----------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Implementation notes:
|
||||||
|
|
||||||
|
1) The 'ListData' struct of this linked list SHALL have
|
||||||
|
a pointer to the head node of the list as only member!
|
||||||
|
|
||||||
|
2) List and list node allocation:
|
||||||
|
Use functions `mem_alloc(…)` and `mem_free(…)`
|
||||||
|
declared in `allocator.h`. DO NOT use `malloc(…)` and `free(…)` directly
|
||||||
|
as unit tests will fail.
|
||||||
|
|
||||||
|
3) Use 'limits.h' to get maximum and minimum values for numeric types, if needed.
|
||||||
|
|
||||||
|
4) Avoid code duplication wherever (reasonably) possible.
|
||||||
|
This is valid for implementation of similar functions as well
|
||||||
|
as for reoccurring code patterns, such as list iteration.
|
||||||
|
Nevertheless, aim for efficiency, e.g. `remove_all` shall traverse
|
||||||
|
the list only once and not use `remove` as defined, because
|
||||||
|
the later would start at the beginning of the list for each iteration.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "simple_singly_linked_list.h"
|
||||||
|
|
||||||
|
/** The type of list nodes */
|
||||||
|
|
||||||
|
/** The implementation of list node data */
|
||||||
|
|
||||||
|
/** The implementation of list data */
|
||||||
|
|
||||||
|
|
||||||
|
/* ===================================================================== */
|
||||||
|
/* private list functions */
|
||||||
|
|
||||||
|
/* abstract away and generalize also memory allocation for list nodes */
|
||||||
|
static <node-type> list_obtain_node(<params>) {
|
||||||
|
}
|
||||||
|
|
||||||
|
static void list_release_node(<node-type>) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/* optional: implement a function for printing the content of the list - may be useful for debugging */
|
||||||
|
void list_dump(char* prefix, IntList list) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===================================================================== */
|
||||||
28
simple_singly_linked_list.h
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*----------------------------------------------------------
|
||||||
|
* HTBLA-Leonding / Class: <your class>
|
||||||
|
* ---------------------------------------------------------
|
||||||
|
* Exercise Number: S01
|
||||||
|
* Title: Simple Singly Linked List
|
||||||
|
* Author: */<your name>;/*
|
||||||
|
* ----------------------------------------------------------
|
||||||
|
* Description:
|
||||||
|
* The declaration of a linked list abstract data type
|
||||||
|
* based on an implementation of a simple singly linked list.
|
||||||
|
* ----------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ___SIMPLE_SINGLY_LINKED_LIST__H
|
||||||
|
#define ___SIMPLE_SINGLY_LINKED_LIST__H
|
||||||
|
|
||||||
|
#include "list.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This header file maps only the common 'list' interface
|
||||||
|
* into naming conventions for simple singly linked list implementation.
|
||||||
|
*
|
||||||
|
* It does (for now) not extend or alter the function prototypes of the
|
||||||
|
* common interface.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#endif
|
||||||
768
test_list.c
Normal file
|
|
@ -0,0 +1,768 @@
|
||||||
|
/*----------------------------------------------------------
|
||||||
|
* HTBLA-Leonding / Klasse: n/a
|
||||||
|
* ---------------------------------------------------------
|
||||||
|
* Title: Implementation of UTs for lists
|
||||||
|
* Author: S. Schraml
|
||||||
|
* ----------------------------------------------------------
|
||||||
|
* Description:
|
||||||
|
* Tests functions of a list.
|
||||||
|
* ----------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "test_list.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "shortcut.h"
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "list.h"
|
||||||
|
#include "allocator.h"
|
||||||
|
|
||||||
|
#define ASSERT_NEW_VALID_LIST() _assert_new_valid_list(tc)
|
||||||
|
IntList _assert_new_valid_list(struct TestCase* tc) {
|
||||||
|
int exp_alloc_cnt = mem_get_alloc_call_cnt() + 1;
|
||||||
|
IntList list = list_obtain();
|
||||||
|
ASSERT_TRUE(list != 0, MSG("Expected non-null list"));
|
||||||
|
ASSERT_TRUE(list_is_valid(list), MSG("Expected a valid list"));
|
||||||
|
ASSERT_TRUE(list_is_empty(list), MSG("Expected an empty list"));
|
||||||
|
ASSERT_TRUE(mem_get_alloc_call_cnt() == exp_alloc_cnt, MSG("Expected mem_alloc being called exactly once, but was called %d time(s)", mem_get_alloc_call_cnt() - exp_alloc_cnt - 1));
|
||||||
|
ASSERT_TRUE(mem_is_allocated(list), MSG("Expected obtained list1 is allocated using mem_alloc"));
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ASSERT_RESET_AND_NEW_VALID_LIST() _assert_reset_and_new_valid_list(tc)
|
||||||
|
IntList _assert_reset_and_new_valid_list(struct TestCase* tc) {
|
||||||
|
mem_reset_stat();
|
||||||
|
return _assert_new_valid_list(tc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define ASSERT_FREE_VALID_LIST(p_list) _assert_free_valid_list(tc, p_list)
|
||||||
|
void _assert_free_valid_list(struct TestCase* tc, IntList* p_list) {
|
||||||
|
ASSERT_TRUE(p_list != 0 && list_is_valid(*p_list), MSG("Expected a valid list"));
|
||||||
|
int additional_free_calls = 1 + list_get_size(*p_list);
|
||||||
|
int exp_alloc_cnt = mem_get_alloc_call_cnt();
|
||||||
|
int exp_free_cnt = mem_get_free_call_cnt() + additional_free_calls;
|
||||||
|
ASSERT_TRUE(mem_is_allocated(*p_list), MSG("Expected that list to release was allocated using mem_alloc"));
|
||||||
|
list_release(p_list);
|
||||||
|
ASSERT_TRUE(p_list != 0 && *p_list == 0, MSG("Expected that list was set to 0"));
|
||||||
|
ASSERT_TRUE(mem_get_alloc_call_cnt() == exp_alloc_cnt, MSG("Expected mem_alloc being NOT called, but was called %d time(s)", mem_get_alloc_call_cnt() - exp_alloc_cnt));
|
||||||
|
ASSERT_TRUE(mem_get_free_call_cnt() == exp_free_cnt, MSG("Expected mem_free being called exactly %d time(s), but was called %d time(s)", mem_get_free_call_cnt() - exp_free_cnt - additional_free_calls));
|
||||||
|
ASSERT_FALSE(mem_is_allocated(*p_list), MSG("Expected that released list is not allocated anymore after release"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ASSERT_MEM_STATUS_EXT(exp_alloc_call_cnt, exp_free_call_cnt, exp_block_cnt) _assert_mem_status_ext(tc, exp_alloc_call_cnt, exp_free_call_cnt, exp_block_cnt)
|
||||||
|
void _assert_mem_status_ext(struct TestCase* tc, int exp_alloc_call_cnt, int exp_free_call_cnt, int exp_block_cnt) {
|
||||||
|
ASSERT_TRUE(mem_get_allocated_block_cnt() == exp_block_cnt, MSG("Expected %d allocated memory block(s), but is %d", exp_block_cnt, mem_get_allocated_block_cnt()));
|
||||||
|
ASSERT_TRUE(mem_get_alloc_call_cnt() == exp_alloc_call_cnt, MSG("Expected %d mem_alloc() call(s), but is %d", exp_alloc_call_cnt, mem_get_alloc_call_cnt()));
|
||||||
|
ASSERT_TRUE(mem_get_free_call_cnt() == exp_free_call_cnt, MSG("Expected %d mem_free() call(s), but is %d", exp_free_call_cnt, mem_get_free_call_cnt()));
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ASSERT_MEM_STATUS(exp_alloc_call_cnt, exp_free_call_cnt) _assert_mem_status_ext(tc, exp_alloc_call_cnt, exp_free_call_cnt, (exp_alloc_call_cnt - exp_free_call_cnt))
|
||||||
|
/* ------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
TEST(test_list_obtain__shall_allocate_a_list) {
|
||||||
|
int exp_alloc_cnt = 1;
|
||||||
|
mem_reset_stat();
|
||||||
|
IntList list = list_obtain();
|
||||||
|
ASSERT_TRUE(list != 0, MSG("Expected non-null list"));
|
||||||
|
ASSERT_TRUE(mem_get_alloc_call_cnt() == exp_alloc_cnt, MSG("Expected mem_alloc being called exactly %d time(s)", exp_alloc_cnt));
|
||||||
|
ASSERT_TRUE(mem_is_allocated(list), MSG("Expected obtained list is allocated using mem_alloc"));
|
||||||
|
if (list != 0) {
|
||||||
|
free(list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(test_list_obtain__shall_allocate_a_fresh_list) {
|
||||||
|
IntList list = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
if (list != 0) {
|
||||||
|
free(list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(test_list_obtain__shall_allocate_a_different_list) {
|
||||||
|
IntList list1 = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
IntList list2 = ASSERT_NEW_VALID_LIST();
|
||||||
|
ASSERT_TRUE(list1 != list2, MSG("Expected different lists"));
|
||||||
|
if (list1 != 0) {
|
||||||
|
free(list1);
|
||||||
|
}
|
||||||
|
if (list2 != 0) {
|
||||||
|
free(list2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(test_list_obtain_failed__shall_not_allocate_a_list) {
|
||||||
|
IntList list1 = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
int exp_alloc_cnt = 1;
|
||||||
|
mem_reset_calls();
|
||||||
|
mem_block_allocs(true);
|
||||||
|
IntList list = list_obtain();
|
||||||
|
ASSERT_TRUE(list == 0, MSG("Expected null list"));
|
||||||
|
ASSERT_TRUE(mem_get_alloc_call_cnt() == exp_alloc_cnt, MSG("Expected mem_alloc being called exactly %d time(s)", exp_alloc_cnt));
|
||||||
|
if (list != 0) {
|
||||||
|
free(list);
|
||||||
|
}
|
||||||
|
free(list1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
TEST(test_list_release__shall_release_a_valid_empty_list) {
|
||||||
|
IntList list = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
ASSERT_FREE_VALID_LIST(&list);
|
||||||
|
ASSERT_TRUE(list == 0, MSG("Expected that list is set to 0"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(test_list_release__shall_release_a_valid_filled_list) {
|
||||||
|
IntList list = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
list_insert(list, 11);
|
||||||
|
list_insert(list, 12);
|
||||||
|
ASSERT_FREE_VALID_LIST(&list);
|
||||||
|
ASSERT_TRUE(list == 0, MSG("Expected that list is set to 0"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(test_list_release__shall_ignore_release_of_an_invalid_list) {
|
||||||
|
IntList tmp = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
int block_cnt = mem_get_allocated_block_cnt();
|
||||||
|
IntList* p_list = 0;
|
||||||
|
list_release(p_list);
|
||||||
|
ASSERT_TRUE(mem_get_allocated_block_cnt() == block_cnt, MSG("Expected unchanged memory allocation"));
|
||||||
|
ASSERT_TRUE(mem_get_free_call_cnt() == 0, MSG("Expected NO mem_free() call, but was called %d time(s)", mem_get_free_call_cnt()));
|
||||||
|
|
||||||
|
IntList list = 0;
|
||||||
|
p_list = &list;
|
||||||
|
list_release(p_list);
|
||||||
|
ASSERT_TRUE(mem_get_allocated_block_cnt() == block_cnt, MSG("Expected unchanged memory allocation"));
|
||||||
|
ASSERT_TRUE(mem_get_free_call_cnt() == 0, MSG("Expected NO mem_free() call, but was called %d time(s)", mem_get_free_call_cnt()));
|
||||||
|
|
||||||
|
list_release(&tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
TEST(test_list_is_valid__shall_be_true_for_valid_list) {
|
||||||
|
IntList list = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
ASSERT_TRUE(list_is_valid(list), MSG("Expected list to be valid"));
|
||||||
|
ASSERT_FREE_VALID_LIST(&list);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(test_list_is_valid__shall_be_false_for_invalid_list) {
|
||||||
|
ASSERT_FALSE(list_is_valid(0), MSG("Expected list to be invalid"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
TEST(test_list_insert__shall_add_one_value_to_empty_list) {
|
||||||
|
IntList list = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
int exp_block_cnt = 2; // list and one node
|
||||||
|
list_insert(list, 11);
|
||||||
|
ASSERT_MEM_STATUS(exp_block_cnt, 0);
|
||||||
|
ASSERT_FREE_VALID_LIST(&list);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(test_list_insert__shall_add_multiple_values) {
|
||||||
|
IntList list = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
int exp_block_cnt = 2; // list and one node
|
||||||
|
list_insert(list, 11);
|
||||||
|
ASSERT_MEM_STATUS(exp_block_cnt, 0);
|
||||||
|
list_insert(list, 12);
|
||||||
|
exp_block_cnt++;
|
||||||
|
ASSERT_MEM_STATUS(exp_block_cnt, 0);
|
||||||
|
list_insert(list, 13);
|
||||||
|
exp_block_cnt++;
|
||||||
|
ASSERT_MEM_STATUS(exp_block_cnt, 0);
|
||||||
|
ASSERT_FREE_VALID_LIST(&list);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(test_list_insert__shall_ignore_invalid_list) {
|
||||||
|
IntList tmp = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
list_insert(0, 11);
|
||||||
|
ASSERT_FREE_VALID_LIST(&tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
TEST(test_list_remove__shall_not_remove_from_empty_list) {
|
||||||
|
IntList list = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
int exp_block_cnt = 1; // list
|
||||||
|
list_remove(list, 11);
|
||||||
|
ASSERT_MEM_STATUS(exp_block_cnt, 0);
|
||||||
|
ASSERT_FREE_VALID_LIST(&list);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(test_list_remove__shall_remove_only_value) {
|
||||||
|
IntList list = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
list_insert(list, 11);
|
||||||
|
list_remove(list, 11);
|
||||||
|
ASSERT_MEM_STATUS(2, 1); // list and node alloc, node free
|
||||||
|
ASSERT_FREE_VALID_LIST(&list);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(test_list_remove__shall_remove_one_value) {
|
||||||
|
IntList list = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
list_insert(list, 11);
|
||||||
|
list_insert(list, 12);
|
||||||
|
list_insert(list, 11);
|
||||||
|
list_insert(list, 11);
|
||||||
|
list_remove(list, 11);
|
||||||
|
ASSERT_TRUE(list_get_at(list, 0) == 12, MSG("Expected that the fist occurrance was removed"));
|
||||||
|
ASSERT_MEM_STATUS(5, 1); // list and node alloc, node free
|
||||||
|
ASSERT_FREE_VALID_LIST(&list);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(test_list_remove__shall_remove_first_value) {
|
||||||
|
IntList list = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
list_insert(list, 11);
|
||||||
|
list_insert(list, 12);
|
||||||
|
list_insert(list, 13);
|
||||||
|
list_remove(list, 11);
|
||||||
|
ASSERT_MEM_STATUS(4, 1); // list and node alloc, node free
|
||||||
|
ASSERT_FREE_VALID_LIST(&list);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(test_list_remove__shall_remove_value_in_the_middle) {
|
||||||
|
IntList list = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
list_insert(list, 11);
|
||||||
|
list_insert(list, 12);
|
||||||
|
list_insert(list, 13);
|
||||||
|
list_remove(list, 12);
|
||||||
|
ASSERT_MEM_STATUS(4, 1); // list and node alloc, node free
|
||||||
|
ASSERT_FREE_VALID_LIST(&list);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(test_list_remove__shall_remove_value_at_the_end) {
|
||||||
|
IntList list = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
list_insert(list, 11);
|
||||||
|
list_insert(list, 12);
|
||||||
|
list_insert(list, 13);
|
||||||
|
list_remove(list, 13);
|
||||||
|
ASSERT_MEM_STATUS(4, 1); // list and node alloc, node free
|
||||||
|
ASSERT_FREE_VALID_LIST(&list);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(test_list_remove__shall_not_remove_missing_value) {
|
||||||
|
IntList list = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
list_insert(list, 11);
|
||||||
|
list_insert(list, 12);
|
||||||
|
list_insert(list, 13);
|
||||||
|
list_remove(list, 14);
|
||||||
|
ASSERT_MEM_STATUS(4, 0); // list and node alloc, node free
|
||||||
|
ASSERT_FREE_VALID_LIST(&list);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(test_list_remove__shall_ignore_invalid_list) {
|
||||||
|
IntList tmp = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
list_remove(0, 11);
|
||||||
|
ASSERT_MEM_STATUS(1, 0);
|
||||||
|
ASSERT_FREE_VALID_LIST(&tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
TEST(test_list_remove_all__shall_not_remove_from_empty_list) {
|
||||||
|
IntList list = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
int exp_block_cnt = 1; // list
|
||||||
|
list_remove_all(list, 21);
|
||||||
|
ASSERT_MEM_STATUS(exp_block_cnt, 0);
|
||||||
|
ASSERT_FREE_VALID_LIST(&list);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(test_list_remove_all__shall_remove_only_value) {
|
||||||
|
IntList list = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
list_insert(list, 21);
|
||||||
|
list_remove_all(list, 21);
|
||||||
|
ASSERT_MEM_STATUS(2, 1); // list and node alloc, node free
|
||||||
|
ASSERT_FREE_VALID_LIST(&list);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(test_list_remove_all__shall_remove_all_values) {
|
||||||
|
IntList list = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
list_insert(list, 21);
|
||||||
|
list_insert(list, 21);
|
||||||
|
list_insert(list, 21);
|
||||||
|
list_remove_all(list, 21);
|
||||||
|
ASSERT_TRUE(list_is_empty(list), MSG("Expected list is empty after removal of all nodes"));
|
||||||
|
ASSERT_MEM_STATUS(4, 3); // list and node alloc, node free
|
||||||
|
ASSERT_FREE_VALID_LIST(&list);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(test_list_remove_all__shall_remove_one_value) {
|
||||||
|
IntList list = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
list_insert(list, 21);
|
||||||
|
list_insert(list, 22);
|
||||||
|
list_insert(list, 21);
|
||||||
|
list_remove_all(list, 22);
|
||||||
|
ASSERT_MEM_STATUS(4, 1); // list and node alloc, node free
|
||||||
|
ASSERT_FREE_VALID_LIST(&list);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(test_list_remove_all__shall_remove_all_values_in_a_row) {
|
||||||
|
IntList list = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
list_insert(list, 21);
|
||||||
|
list_insert(list, 22);
|
||||||
|
list_insert(list, 22);
|
||||||
|
list_insert(list, 22);
|
||||||
|
list_insert(list, 23);
|
||||||
|
list_remove_all(list, 22);
|
||||||
|
ASSERT_MEM_STATUS(6, 3); // list and node alloc, node free
|
||||||
|
ASSERT_FREE_VALID_LIST(&list);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(test_list_remove_all__shall_remove_all_distributed_values) {
|
||||||
|
IntList list = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
list_insert(list, 22);
|
||||||
|
list_insert(list, 23);
|
||||||
|
list_insert(list, 22);
|
||||||
|
list_insert(list, 24);
|
||||||
|
list_insert(list, 22);
|
||||||
|
list_remove_all(list, 22);
|
||||||
|
ASSERT_MEM_STATUS(6, 3); // list and node alloc, node free
|
||||||
|
ASSERT_FREE_VALID_LIST(&list);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(test_list_remove_all__shall_not_remove_missing_value) {
|
||||||
|
IntList list = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
list_insert(list, 22);
|
||||||
|
list_insert(list, 23);
|
||||||
|
list_insert(list, 22);
|
||||||
|
list_insert(list, 24);
|
||||||
|
list_insert(list, 22);
|
||||||
|
list_remove_all(list, 21);
|
||||||
|
ASSERT_MEM_STATUS(6, 0); // list and node alloc, node free
|
||||||
|
ASSERT_FREE_VALID_LIST(&list);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(test_list_remove_all__shall_ignore_invalid_list) {
|
||||||
|
IntList tmp = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
list_remove_all(0, 21);
|
||||||
|
ASSERT_MEM_STATUS(1, 0);
|
||||||
|
ASSERT_FREE_VALID_LIST(&tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
TEST(test_list_insert_at__shall_insert_single_value_in_empty_list) {
|
||||||
|
IntList list = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
list_insert_at(list, 0, 31);
|
||||||
|
ASSERT_MEM_STATUS(2, 0);
|
||||||
|
ASSERT_FREE_VALID_LIST(&list);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(test_list_insert_at__shall_insert_value_at_the_beginning) {
|
||||||
|
IntList list = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
list_insert(list, 11);
|
||||||
|
list_insert(list, 12);
|
||||||
|
list_insert(list, 13);
|
||||||
|
list_insert_at(list, 0, 31);
|
||||||
|
ASSERT_MEM_STATUS(5, 0);
|
||||||
|
ASSERT_TRUE(list_get_at(list, 0) == 31, MSG("Expected value was inserted at the beginning of the list"));
|
||||||
|
ASSERT_FREE_VALID_LIST(&list);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(test_list_insert_at__shall_insert_value_in_the_middle) {
|
||||||
|
IntList list = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
list_insert(list, 11);
|
||||||
|
list_insert(list, 12);
|
||||||
|
list_insert(list, 13);
|
||||||
|
list_insert_at(list, 1, 31);
|
||||||
|
ASSERT_MEM_STATUS(5, 0);
|
||||||
|
ASSERT_TRUE(list_get_at(list, 1) == 31, MSG("Expected value was inserted in the middle of the list"));
|
||||||
|
ASSERT_FREE_VALID_LIST(&list);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(test_list_insert_at__shall_insert_value_at_the_end) {
|
||||||
|
IntList list = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
list_insert(list, 11);
|
||||||
|
list_insert(list, 12);
|
||||||
|
list_insert(list, 13);
|
||||||
|
list_insert_at(list, 3, 31);
|
||||||
|
ASSERT_MEM_STATUS(5, 0);
|
||||||
|
ASSERT_TRUE(list_get_at(list, 3) == 31, MSG("Expected value was inserted before at the end of the list"));
|
||||||
|
ASSERT_FREE_VALID_LIST(&list);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(test_list_insert_at__shall_insert_value_after_the_end) {
|
||||||
|
IntList list = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
list_insert(list, 11);
|
||||||
|
list_insert(list, 12);
|
||||||
|
list_insert(list, 13);
|
||||||
|
list_insert_at(list, 99, 31);
|
||||||
|
ASSERT_MEM_STATUS(5, 0);
|
||||||
|
ASSERT_TRUE(list_get_at(list, 3) == 31, MSG("Expected value was inserted before at the end of the list"));
|
||||||
|
ASSERT_FREE_VALID_LIST(&list);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(test_list_insert_at__shall_ignore_invalid_list) {
|
||||||
|
IntList tmp = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
list_insert_at(0, 2, 31);
|
||||||
|
ASSERT_MEM_STATUS(1, 0);
|
||||||
|
ASSERT_FREE_VALID_LIST(&tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
TEST(test_list_remove_at__shall_not_remove_from_empty_list) {
|
||||||
|
IntList list = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
list_remove_at(list, 0);
|
||||||
|
ASSERT_MEM_STATUS(1, 0);
|
||||||
|
ASSERT_FREE_VALID_LIST(&list);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(test_list_remove_at__shall_remove_value_at_the_beginning) {
|
||||||
|
IntList list = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
list_insert(list, 41);
|
||||||
|
list_insert(list, 42);
|
||||||
|
list_insert(list, 43);
|
||||||
|
int val = list_remove_at(list, 0);
|
||||||
|
ASSERT_MEM_STATUS(4, 1);
|
||||||
|
ASSERT_TRUE(list_get_at(list, 0) == 42, MSG("Expected value was removed form the beginning of the list"));
|
||||||
|
ASSERT_TRUE(val == 41, MSG("Expected value %d was removed, but got %d", 41, val));
|
||||||
|
ASSERT_FREE_VALID_LIST(&list);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(test_list_remove_at__shall_remove_value_in_the_middle) {
|
||||||
|
IntList list = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
list_insert(list, 41);
|
||||||
|
list_insert(list, 42);
|
||||||
|
list_insert(list, 43);
|
||||||
|
int val = list_remove_at(list, 1);
|
||||||
|
ASSERT_MEM_STATUS(4, 1);
|
||||||
|
ASSERT_TRUE(list_get_at(list, 1) == 43, MSG("Expected value was removed form the middle of the list"));
|
||||||
|
ASSERT_TRUE(val == 42, MSG("Expected value %d was removed, but got %d", 42, val));
|
||||||
|
ASSERT_FREE_VALID_LIST(&list);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(test_list_remove_at__shall_remove_value_at_the_end) {
|
||||||
|
IntList list = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
list_insert(list, 41);
|
||||||
|
list_insert(list, 42);
|
||||||
|
list_insert(list, 43);
|
||||||
|
int val = list_remove_at(list, 2);
|
||||||
|
ASSERT_MEM_STATUS(4, 1);
|
||||||
|
ASSERT_TRUE(list_get_at(list, 1) == 42, MSG("Expected value was removed form the end of the list"));
|
||||||
|
ASSERT_TRUE(val == 43, MSG("Expected value %d was removed, but got %d", 43, val));
|
||||||
|
ASSERT_FREE_VALID_LIST(&list);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(test_list_remove_at__shall_not_remove_value_after_the_end) {
|
||||||
|
IntList list = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
list_insert(list, 41);
|
||||||
|
list_insert(list, 42);
|
||||||
|
list_insert(list, 43);
|
||||||
|
int val = list_remove_at(list, 3);
|
||||||
|
ASSERT_MEM_STATUS(4, 0);
|
||||||
|
ASSERT_TRUE(val == 0, MSG("Expected that no value (0) was removed, but got %d", val));
|
||||||
|
ASSERT_FREE_VALID_LIST(&list);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(test_list_remove_at__shall_ignore_invalid_list) {
|
||||||
|
IntList tmp = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
int val = list_remove_at(0, 0);
|
||||||
|
ASSERT_TRUE(val == 0, MSG("Expected that no value (0) was removed, but got %d", val));
|
||||||
|
ASSERT_MEM_STATUS(1, 0);
|
||||||
|
ASSERT_FREE_VALID_LIST(&tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
TEST(test_list_clear__shall_clear_empty_list) {
|
||||||
|
IntList list = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
list_clear(list);
|
||||||
|
ASSERT_MEM_STATUS(1, 0);
|
||||||
|
ASSERT_FREE_VALID_LIST(&list);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(test_list_clear__shall_clear_list_with_one_value) {
|
||||||
|
IntList list = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
list_insert(list, 51);
|
||||||
|
list_clear(list);
|
||||||
|
ASSERT_MEM_STATUS(2, 1);
|
||||||
|
ASSERT_FREE_VALID_LIST(&list);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(test_list_clear__shall_clear_list_with_multiple_values) {
|
||||||
|
IntList list = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
list_insert(list, 51);
|
||||||
|
list_insert(list, 52);
|
||||||
|
list_insert(list, 53);
|
||||||
|
list_clear(list);
|
||||||
|
ASSERT_MEM_STATUS(4, 3);
|
||||||
|
ASSERT_FREE_VALID_LIST(&list);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(test_list_clear__shall_ingore_invalid_list) {
|
||||||
|
IntList tmp = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
list_clear(0);
|
||||||
|
ASSERT_MEM_STATUS(1, 0);
|
||||||
|
ASSERT_FREE_VALID_LIST(&tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
TEST(test_list_is_empty__shall_be_true__for_newly_obtained_list) {
|
||||||
|
IntList list = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
ASSERT_TRUE(list_is_empty(0), MSG("Expected that new list IS empty"));
|
||||||
|
ASSERT_MEM_STATUS(1, 0);
|
||||||
|
ASSERT_FREE_VALID_LIST(&list);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(test_list_is_empty__shall_be_false__after_adding_values) {
|
||||||
|
IntList list = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
list_insert(list, 61);
|
||||||
|
ASSERT_FALSE(list_is_empty(list), MSG("Expected that list with values IS NOT empty"));
|
||||||
|
ASSERT_MEM_STATUS(2, 0);
|
||||||
|
ASSERT_FREE_VALID_LIST(&list);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(test_list_is_empty__shall_be_true__after_clear) {
|
||||||
|
IntList list = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
list_insert(list, 51);
|
||||||
|
list_insert(list, 52);
|
||||||
|
list_insert(list, 53);
|
||||||
|
list_clear(list);
|
||||||
|
ASSERT_FALSE(list_is_empty(0), MSG("Expected that list IS empty after list_clear"));
|
||||||
|
ASSERT_MEM_STATUS(4, 3);
|
||||||
|
ASSERT_FREE_VALID_LIST(&list);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(test_list_is_empty__shall_be_true_for_invalid_list) {
|
||||||
|
IntList tmp = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
ASSERT_TRUE(list_is_empty(0), MSG("Expected that invalid list IS empty"));
|
||||||
|
ASSERT_MEM_STATUS(1, 0);
|
||||||
|
ASSERT_FREE_VALID_LIST(&tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
TEST(test_list_get_size__shall_be_0_for_newly_obtained_list) {
|
||||||
|
IntList list = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
ASSERT_TRUE(list_get_size(list) == 0, MSG("Expected that size of new list is 0"));
|
||||||
|
ASSERT_MEM_STATUS(1, 0);
|
||||||
|
ASSERT_FREE_VALID_LIST(&list);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(test_list_get_size__shall_reflect_number_of_values_after_adding_values) {
|
||||||
|
IntList list = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
list_insert(list, 71);
|
||||||
|
ASSERT_TRUE(list_get_size(list) == 1, MSG("Expected that size of list is 1 after adding first value"));
|
||||||
|
list_insert(list, 72);
|
||||||
|
ASSERT_TRUE(list_get_size(list) == 2, MSG("Expected that size of list is 2 after adding second value"));
|
||||||
|
list_insert(list, 73);
|
||||||
|
ASSERT_TRUE(list_get_size(list) == 3, MSG("Expected that size of list is 3 after adding third value"));
|
||||||
|
ASSERT_MEM_STATUS(4, 0);
|
||||||
|
ASSERT_FREE_VALID_LIST(&list);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(test_list_get_size__shall_reflect_number_of_values_after_removing_values) {
|
||||||
|
IntList list = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
list_insert(list, 81);
|
||||||
|
list_insert(list, 82);
|
||||||
|
list_insert(list, 83);
|
||||||
|
list_remove_at(list, 0);
|
||||||
|
ASSERT_TRUE(list_get_size(list) == 2, MSG("Expected that size of list is 2 after removing first value"));
|
||||||
|
list_remove_at(list, 1);
|
||||||
|
ASSERT_TRUE(list_get_size(list) == 1, MSG("Expected that size of list is 1 after removing second value"));
|
||||||
|
list_remove_at(list, 0);
|
||||||
|
ASSERT_TRUE(list_get_size(list) == 0, MSG("Expected that size of list is 0 after removing third value"));
|
||||||
|
ASSERT_MEM_STATUS(4, 3);
|
||||||
|
ASSERT_FREE_VALID_LIST(&list);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(test_list_get_size__shall_be_0_after_clear) {
|
||||||
|
IntList list = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
list_insert(list, 81);
|
||||||
|
list_insert(list, 82);
|
||||||
|
list_insert(list, 83);
|
||||||
|
list_clear(list);
|
||||||
|
ASSERT_TRUE(list_get_size(list) == 0, MSG("Expected that size of list is 0 after clearing the list"));
|
||||||
|
ASSERT_MEM_STATUS(4, 3);
|
||||||
|
ASSERT_FREE_VALID_LIST(&list);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(test_list_get_size__shall_be_0_for_invalid_list) {
|
||||||
|
IntList tmp = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
ASSERT_TRUE(list_get_size(0) == 0, MSG("Expected that size of invalid list is 0"));
|
||||||
|
ASSERT_MEM_STATUS(1, 0);
|
||||||
|
ASSERT_FREE_VALID_LIST(&tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
TEST(test_list_contains__shall_be_false_for_empty_list) {
|
||||||
|
IntList list = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
ASSERT_FALSE(list_contains(list, 91), MSG("Expected that empty list does not contain any value"));
|
||||||
|
ASSERT_MEM_STATUS(1, 0);
|
||||||
|
ASSERT_FREE_VALID_LIST(&list);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(test_list_contains__shall_be_true_for_one_value) {
|
||||||
|
IntList list = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
list_insert(list, 91);
|
||||||
|
ASSERT_TRUE(list_contains(list, 91), MSG("Expected that list does contain the value"));
|
||||||
|
list_insert(list, 92);
|
||||||
|
ASSERT_TRUE(list_contains(list, 91), MSG("Expected that list does contain the value"));
|
||||||
|
ASSERT_TRUE(list_contains(list, 92), MSG("Expected that list does contain the value"));
|
||||||
|
ASSERT_MEM_STATUS(3, 0);
|
||||||
|
ASSERT_FREE_VALID_LIST(&list);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(test_list_contains__shall_be_true_for_multiple_values) {
|
||||||
|
IntList list = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
list_insert(list, 91);
|
||||||
|
ASSERT_TRUE(list_contains(list, 91), MSG("Expected that list does contain the value"));
|
||||||
|
list_insert(list, 91);
|
||||||
|
ASSERT_TRUE(list_contains(list, 91), MSG("Expected that list does contain the value"));
|
||||||
|
ASSERT_MEM_STATUS(3, 0);
|
||||||
|
ASSERT_FREE_VALID_LIST(&list);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(test_list_contains__shall_be_false_form_missing_value) {
|
||||||
|
IntList list = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
list_insert(list, 91);
|
||||||
|
ASSERT_FALSE(list_contains(list, 94), MSG("Expected that list does NOT contain the value"));
|
||||||
|
list_insert(list, 92);
|
||||||
|
ASSERT_FALSE(list_contains(list, 94), MSG("Expected that list does NOT contain the value"));
|
||||||
|
ASSERT_FREE_VALID_LIST(&list);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(test_list_contains__shall_be_false_for_invalid_list) {
|
||||||
|
IntList tmp = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
ASSERT_FALSE(list_contains(0, 0), MSG("Expected that invalid list does not contain any value"));
|
||||||
|
ASSERT_MEM_STATUS(1, 0);
|
||||||
|
ASSERT_FREE_VALID_LIST(&tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
TEST(test_list_get_at__shall_return_0_for_empty_list) {
|
||||||
|
IntList list = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
ASSERT_TRUE(list_get_at(list, 0) == 0, MSG("Expected that empty list provides always 0"));
|
||||||
|
ASSERT_TRUE(list_get_at(list, 1) == 0, MSG("Expected that empty list provides always 0"));
|
||||||
|
ASSERT_MEM_STATUS(1, 0);
|
||||||
|
ASSERT_FREE_VALID_LIST(&list);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(test_list_get_at__shall_return_single_value) {
|
||||||
|
IntList list = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
list_insert(list, 101);
|
||||||
|
ASSERT_TRUE(list_get_at(list, 0) == 101, MSG("Expected that list provides the value"));
|
||||||
|
ASSERT_MEM_STATUS(2, 0);
|
||||||
|
ASSERT_FREE_VALID_LIST(&list);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(test_list_get_at__shall_return_first_value) {
|
||||||
|
IntList list = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
list_insert(list, 101);
|
||||||
|
list_insert(list, 102);
|
||||||
|
list_insert(list, 103);
|
||||||
|
ASSERT_TRUE(list_get_at(list, 0) == 101, MSG("Expected that list provides the value"));
|
||||||
|
ASSERT_MEM_STATUS(4, 0);
|
||||||
|
ASSERT_FREE_VALID_LIST(&list);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(test_list_get_at__shall_return_values_in_added_order) {
|
||||||
|
IntList list = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
list_insert(list, 101);
|
||||||
|
list_insert(list, 102);
|
||||||
|
list_insert(list, 103);
|
||||||
|
ASSERT_TRUE(list_get_at(list, 0) == 101, MSG("Expected that list provides the first value"));
|
||||||
|
ASSERT_TRUE(list_get_at(list, 1) == 102, MSG("Expected that list provides the second value"));
|
||||||
|
ASSERT_TRUE(list_get_at(list, 2) == 103, MSG("Expected that list provides the third value"));
|
||||||
|
list_insert_at(list, 1, 104);
|
||||||
|
ASSERT_TRUE(list_get_at(list, 0) == 101, MSG("Expected that list provides the first value"));
|
||||||
|
ASSERT_TRUE(list_get_at(list, 1) == 104, MSG("Expected that list provides the new second value"));
|
||||||
|
ASSERT_TRUE(list_get_at(list, 2) == 102, MSG("Expected that list provides the new third value"));
|
||||||
|
ASSERT_TRUE(list_get_at(list, 3) == 103, MSG("Expected that list provides the new forth value"));
|
||||||
|
ASSERT_MEM_STATUS(5, 0);
|
||||||
|
ASSERT_FREE_VALID_LIST(&list);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(test_list_get_at__shall_return_0_for_invalid_list) {
|
||||||
|
IntList tmp = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
ASSERT_TRUE(list_get_at(0, 0) == 0, MSG("Expected that invalid list provides always 0"));
|
||||||
|
ASSERT_MEM_STATUS(1, 0);
|
||||||
|
ASSERT_FREE_VALID_LIST(&tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
TEST(test_list_append__shall_append_empty_list_to_empty_list) {
|
||||||
|
IntList list1 = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
IntList list2 = ASSERT_NEW_VALID_LIST();
|
||||||
|
list_append(list1, list2);
|
||||||
|
ASSERT_TRUE(list_is_empty(list1), MSG("Expected that empty list "));
|
||||||
|
ASSERT_MEM_STATUS(2, 0);
|
||||||
|
ASSERT_FREE_VALID_LIST(&list1);
|
||||||
|
ASSERT_FREE_VALID_LIST(&list2);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(test_list_append__shall_append_filled_list_to_empty_list) {
|
||||||
|
IntList list1 = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
IntList list2 = ASSERT_NEW_VALID_LIST();
|
||||||
|
list_insert(list2, 111);
|
||||||
|
list_insert(list2, 112);
|
||||||
|
list_insert(list2, 113);
|
||||||
|
list_append(list1, list2);
|
||||||
|
ASSERT_TRUE(list_get_at(list1, 0) == 111, MSG("Expected that list provides the first value"));
|
||||||
|
ASSERT_TRUE(list_get_at(list1, 1) == 112, MSG("Expected that list provides the second value"));
|
||||||
|
ASSERT_TRUE(list_get_at(list1, 2) == 113, MSG("Expected that list provides the third value"));
|
||||||
|
ASSERT_TRUE(list_get_size(list1) == 3, MSG("Expected that size of appended list as the size of the resulting list"));
|
||||||
|
ASSERT_TRUE(list_get_size(list2) == 0, MSG("Expected that the appended list is empty"));
|
||||||
|
ASSERT_MEM_STATUS(5, 0);
|
||||||
|
ASSERT_FREE_VALID_LIST(&list1);
|
||||||
|
ASSERT_FREE_VALID_LIST(&list2);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(test_list_append__shall_append_empty_list_to_filled_list) {
|
||||||
|
IntList list1 = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
IntList list2 = ASSERT_NEW_VALID_LIST();
|
||||||
|
list_insert(list1, 121);
|
||||||
|
list_insert(list1, 122);
|
||||||
|
list_insert(list1, 123);
|
||||||
|
list_append(list1, list2);
|
||||||
|
ASSERT_TRUE(list_get_at(list1, 0) == 121, MSG("Expected that list provides the first value"));
|
||||||
|
ASSERT_TRUE(list_get_at(list1, 1) == 122, MSG("Expected that list provides the second value"));
|
||||||
|
ASSERT_TRUE(list_get_at(list1, 2) == 123, MSG("Expected that list provides the third value"));
|
||||||
|
ASSERT_TRUE(list_get_size(list1) == 3, MSG("Expected that size of original list as the size of the resulting list"));
|
||||||
|
ASSERT_TRUE(list_get_size(list2) == 0, MSG("Expected that the appended list is empty"));
|
||||||
|
ASSERT_MEM_STATUS(5, 0);
|
||||||
|
ASSERT_FREE_VALID_LIST(&list1);
|
||||||
|
ASSERT_FREE_VALID_LIST(&list2);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(test_list_append__shall_append_filled_list_to_filled_list) {
|
||||||
|
IntList list1 = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
IntList list2 = ASSERT_NEW_VALID_LIST();
|
||||||
|
list_insert(list1, 131);
|
||||||
|
list_insert(list1, 132);
|
||||||
|
list_insert(list1, 133);
|
||||||
|
list_insert(list2, 141);
|
||||||
|
list_insert(list2, 142);
|
||||||
|
list_insert(list2, 143);
|
||||||
|
list_append(list1, list2);
|
||||||
|
ASSERT_TRUE(list_get_at(list1, 0) == 131, MSG("Expected that list provides the first value"));
|
||||||
|
ASSERT_TRUE(list_get_at(list1, 1) == 132, MSG("Expected that list provides the second value"));
|
||||||
|
ASSERT_TRUE(list_get_at(list1, 2) == 133, MSG("Expected that list provides the third value"));
|
||||||
|
ASSERT_TRUE(list_get_at(list1, 3) == 141, MSG("Expected that list provides the first value of appended list"));
|
||||||
|
ASSERT_TRUE(list_get_at(list1, 4) == 142, MSG("Expected that list provides the second value of appended list"));
|
||||||
|
ASSERT_TRUE(list_get_at(list1, 5) == 143, MSG("Expected that list provides the third value of appended list"));
|
||||||
|
ASSERT_TRUE(list_get_size(list1) == 6, MSG("Expected that size of list is the size of both lists"));
|
||||||
|
ASSERT_TRUE(list_get_size(list2) == 0, MSG("Expected that the appended list is empty"));
|
||||||
|
ASSERT_MEM_STATUS(8, 0);
|
||||||
|
ASSERT_FREE_VALID_LIST(&list1);
|
||||||
|
ASSERT_FREE_VALID_LIST(&list2);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(test_list_append__shall_ignore_invalid_lists) {
|
||||||
|
IntList tmp = ASSERT_RESET_AND_NEW_VALID_LIST();
|
||||||
|
list_append(0, tmp);
|
||||||
|
ASSERT_MEM_STATUS(1, 0);
|
||||||
|
list_append(tmp, 0);
|
||||||
|
ASSERT_MEM_STATUS(1, 0);
|
||||||
|
list_append(0, 0);
|
||||||
|
ASSERT_MEM_STATUS(1, 0);
|
||||||
|
ASSERT_FREE_VALID_LIST(&tmp);
|
||||||
|
}
|
||||||
97
test_list.h
Normal file
|
|
@ -0,0 +1,97 @@
|
||||||
|
/*----------------------------------------------------------
|
||||||
|
* HTBLA-Leonding / Klasse: n/a
|
||||||
|
* ---------------------------------------------------------
|
||||||
|
* Title: Unit Tests for a List implementation
|
||||||
|
* Author: S. Schraml
|
||||||
|
* ----------------------------------------------------------
|
||||||
|
* Description:
|
||||||
|
* Tests functions of a list.
|
||||||
|
* ----------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#ifndef ___TEST_LIST_H
|
||||||
|
#define ___TEST_LIST_H
|
||||||
|
|
||||||
|
#include "shortcut.h"
|
||||||
|
|
||||||
|
TEST(test_list_obtain__shall_allocate_a_list);
|
||||||
|
TEST(test_list_obtain__shall_allocate_a_fresh_list);
|
||||||
|
TEST(test_list_obtain__shall_allocate_a_different_list);
|
||||||
|
TEST(test_list_obtain_failed__shall_not_allocate_a_list);
|
||||||
|
|
||||||
|
TEST(test_list_release__shall_release_a_valid_empty_list);
|
||||||
|
TEST(test_list_release__shall_release_a_valid_filled_list);
|
||||||
|
TEST(test_list_release__shall_ignore_release_of_an_invalid_list);
|
||||||
|
|
||||||
|
TEST(test_list_is_valid__shall_be_true_for_valid_list);
|
||||||
|
TEST(test_list_is_valid__shall_be_false_for_invalid_list);
|
||||||
|
|
||||||
|
TEST(test_list_insert__shall_add_one_value_to_empty_list);
|
||||||
|
TEST(test_list_insert__shall_add_multiple_values);
|
||||||
|
TEST(test_list_insert__shall_ignore_invalid_list);
|
||||||
|
|
||||||
|
TEST(test_list_remove__shall_not_remove_from_empty_list);
|
||||||
|
TEST(test_list_remove__shall_remove_only_value);
|
||||||
|
TEST(test_list_remove__shall_remove_one_value);
|
||||||
|
TEST(test_list_remove__shall_remove_first_value);
|
||||||
|
TEST(test_list_remove__shall_remove_value_in_the_middle);
|
||||||
|
TEST(test_list_remove__shall_remove_value_at_the_end);
|
||||||
|
TEST(test_list_remove__shall_not_remove_missing_value);
|
||||||
|
|
||||||
|
TEST(test_list_remove_all__shall_not_remove_from_empty_list);
|
||||||
|
TEST(test_list_remove_all__shall_remove_only_value);
|
||||||
|
TEST(test_list_remove_all__shall_remove_all_values);
|
||||||
|
TEST(test_list_remove_all__shall_remove_one_value);
|
||||||
|
TEST(test_list_remove_all__shall_remove_all_values_in_a_row);
|
||||||
|
TEST(test_list_remove_all__shall_remove_all_distributed_values);
|
||||||
|
TEST(test_list_remove_all__shall_not_remove_missing_value);
|
||||||
|
TEST(test_list_remove_all__shall_ignore_invalid_list);
|
||||||
|
|
||||||
|
TEST(test_list_insert_at__shall_insert_single_value_in_empty_list);
|
||||||
|
TEST(test_list_insert_at__shall_insert_value_at_the_beginning);
|
||||||
|
TEST(test_list_insert_at__shall_insert_value_in_the_middle);
|
||||||
|
TEST(test_list_insert_at__shall_insert_value_at_the_end);
|
||||||
|
TEST(test_list_insert_at__shall_insert_value_after_the_end);
|
||||||
|
TEST(test_list_insert_at__shall_ignore_invalid_list);
|
||||||
|
|
||||||
|
TEST(test_list_remove_at__shall_not_remove_from_empty_list);
|
||||||
|
TEST(test_list_remove_at__shall_remove_value_at_the_beginning);
|
||||||
|
TEST(test_list_remove_at__shall_remove_value_in_the_middle);
|
||||||
|
TEST(test_list_remove_at__shall_not_remove_from_empty_list);
|
||||||
|
TEST(test_list_remove_at__shall_remove_value_at_the_end);
|
||||||
|
TEST(test_list_remove_at__shall_not_remove_value_after_the_end);
|
||||||
|
TEST(test_list_remove_at__shall_ignore_invalid_list);
|
||||||
|
|
||||||
|
TEST(test_list_clear__shall_clear_empty_list);
|
||||||
|
TEST(test_list_clear__shall_clear_list_with_one_value);
|
||||||
|
TEST(test_list_clear__shall_clear_list_with_multiple_values);
|
||||||
|
TEST(test_list_clear__shall_ingore_invalid_list);
|
||||||
|
|
||||||
|
TEST(test_list_is_empty__shall_be_true__for_newly_obtained_list);
|
||||||
|
TEST(test_list_is_empty__shall_be_false__after_adding_values);
|
||||||
|
TEST(test_list_is_empty__shall_be_true_for_invalid_list);
|
||||||
|
|
||||||
|
TEST(test_list_get_size__shall_be_0_for_newly_obtained_list);
|
||||||
|
TEST(test_list_get_size__shall_reflect_number_of_values_after_adding_values);
|
||||||
|
TEST(test_list_get_size__shall_reflect_number_of_values_after_removing_values);
|
||||||
|
TEST(test_list_get_size__shall_be_0_after_clear);
|
||||||
|
TEST(test_list_get_size__shall_be_0_for_invalid_list);
|
||||||
|
|
||||||
|
TEST(test_list_contains__shall_be_false_for_empty_list);
|
||||||
|
TEST(test_list_contains__shall_be_true_for_one_value);
|
||||||
|
TEST(test_list_contains__shall_be_true_for_multiple_values);
|
||||||
|
TEST(test_list_contains__shall_be_false_form_missing_value);
|
||||||
|
TEST(test_list_contains__shall_be_false_for_invalid_list);
|
||||||
|
|
||||||
|
TEST(test_list_get_at__shall_return_0_for_empty_list);
|
||||||
|
TEST(test_list_get_at__shall_return_single_value);
|
||||||
|
TEST(test_list_get_at__shall_return_first_value);
|
||||||
|
TEST(test_list_get_at__shall_return_values_in_added_order);
|
||||||
|
TEST(test_list_get_at__shall_return_0_for_invalid_list);
|
||||||
|
|
||||||
|
TEST(test_list_append__shall_append_empty_list_to_empty_list);
|
||||||
|
TEST(test_list_append__shall_append_filled_list_to_empty_list);
|
||||||
|
TEST(test_list_append__shall_append_empty_list_to_filled_list);
|
||||||
|
TEST(test_list_append__shall_append_filled_list_to_filled_list);
|
||||||
|
TEST(test_list_append__shall_ignore_invalid_lists);
|
||||||
|
|
||||||
|
#endif
|
||||||