Removed submodules

This commit is contained in:
2026-05-31 14:34:00 -04:00
commit 46c36b11da
352 changed files with 14792 additions and 0 deletions
+22
View File
@@ -0,0 +1,22 @@
# Ignore all compiled files regardless of location
*.o
tests/public.o
tests/testsuite.o
# But not the private.o
!tests/private.o
# Ignore executables for this project
ptrs
testsuite
# Ignore test outputs
tests/ckstyle
tests/itests.txt
tests/outputs
tests/style.txt
tests/valgrind
tests/utests.txt
**/.nfs*
**/.vscode
+51
View File
@@ -0,0 +1,51 @@
#
# Simple Makefile
# Mike Lam, James Madison University, August 2016
#
# This makefile builds a simple application that contains a main module
# (specified by the EXE variable) and a predefined list of additional modules
# (specified by the MODS variable). If there are any external library
# dependencies (e.g., the math library, "-lm"), list them in the LIBS variable.
# If there are any precompiled object files, list them in the OBJS variable.
#
# By default, this makefile will build the project with debugging symbols and
# without optimization. To change this, edit or remove the "-g" and "-O0"
# options in CFLAGS and LDFLAGS accordingly.
#
# By default, this makefile build the application using the GNU C compiler,
# adhering to the C99 standard with all warnings enabled.
# application-specific settings and run target
EXE=ptrs
MODS=movies.o
OBJS=
LIBS=
default: $(EXE)
test: $(EXE)
make -C tests test
# compiler/linker settings
CC=gcc
CFLAGS=-g -O0 -Wall -Werror --std=c99
LDFLAGS=-g -O0
# build targets
$(EXE): main.o $(MODS) $(OBJS)
$(CC) $(LDFLAGS) -o $(EXE) $^ $(LIBS)
%.o: %.c
$(CC) -c $(CFLAGS) $<
clean:
rm -f $(EXE) main.o $(MODS)
make -C tests clean
.PHONY: default clean
+80
View File
@@ -0,0 +1,80 @@
#include <getopt.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include "movies.h"
int cmdline (int, char **, bool *);
void
usage (void)
{
printf ("Usage: ptrs [-hm]\n");
printf (" Options are:\n");
printf (" -m Parse the CSV data as a movie\n");
printf (" -h Print this help message\n");
printf ("Only one option is allowable\n");
}
int
main (int argc, char **argv)
{
bool run_movie = false;
if (cmdline (argc, argv, &run_movie) != 0)
return EXIT_FAILURE;
if (!run_movie)
{
usage ();
return EXIT_FAILURE;
}
// Split the following comma-separated value (CSV) data into fields
char *data = "The Shawshank Redemption,1994,Drama";
movie_t movie = split_data (data);
printf ("Title: %s\n", movie.title);
printf ("Year: %d\n", movie.year);
printf ("Genre: %s\n", movie.genre);
char *rebuilt = merge_data (movie);
printf ("%s\n", rebuilt);
free (rebuilt);
free (movie.title);
free (movie.genre);
return EXIT_SUCCESS;
}
/* DO NOT MODIFY THIS FUNCTION. Parses the command line arguments to get
the signal numbers to override, the number of overridden signals, and
the order of signals to raise in the full implementation. */
int
cmdline (int argc, char **argv, bool *movies)
{
int option;
if ((option = getopt (argc, argv, "mh")) == -1)
{
usage ();
return -1;
}
switch (option)
{
case 'h':
*movies = false;
return -1;
case 'm':
*movies = true;
break;
default:
printf ("Invalid command-line option: %c\n", optopt);
usage ();
return -1;
}
return 0;
}
+97
View File
@@ -0,0 +1,97 @@
#define _POSIX_C_SOURCE 200809L // needed for strdup extension
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "movies.h"
/* Given a string (possibly read-only) of IMDB movie data
(formatted as "Title,Year,Genre"), create a movie_t object
based on the appropriate fields. */
movie_t
split_data (char *csv)
{
movie_t movie;
char *temp = strdup (csv);
char *token = strtok (temp, ",");
movie.title = strdup (token); // make a copy the first token as the title
char *year_str = strtok (NULL, ",");
char *endptr;
movie.year = strtol (year_str, &endptr, 10);
char *genre = strtok (NULL, ",");
movie.genre = strdup (genre);
free (temp);
return movie;
}
/* Build a dynamically allocated string from a movie_t object as follows:
"Title [Year] - Genre"
*/
char *
merge_data (movie_t movie)
{
// There are a few ways to merge strings in C. One approach is to start with
// a base string on the heap and repeatedly grow and append the string. In
// pseudocode, it might look like this:
//
// str = strdup ("Hello");
// str = realloc (str, ...length...); // grow
// strncat (str, " World", ...length...); // concatenate
// str = realloc (str, ...length...); // grow
// strncat (str, " Again", ...length...); // concatenate
//
// This is the C equivalent of something like this in Java:
//
// str = "Hello";
// str += " World";
// str += " Again";
//
// Another (generally more efficient) way to do this is to use snprintf(),
// for formatting a string. If you are not familiar with snprintf(), you
// should be familiar with its cousin, printf(). Consider the following
// line of code, which prints three string variables to the screen:
//
// printf ("%s %s %s\n", str1, str2, str3);
//
// You do the exact same thing with snprintf(), but add two variables at
// the beginning: the destination buffer (i.e., where do you want the
// final string in memory) and the length:
//
// snprintf (buffer, length, "%s %s %s\n", str1, str2, str3);
//
// The original strings str1, str2, and str3 are unmodified, because their
// contents are copied into the buffer. snprintf() also has a great built-in
// feature that strncat() doesn't: it works with more than just strings!
//
// int num = 42;
// char *str = "My favorite number is ";
// snprintf (message, length, "%s%d\n", str, num);
//
// Just remember that the message/buffer variable must be a pointer to a
// writable portion of memory where you have allocated enough space to store
// the combined string.
// HINT: When doing string manipulation, you should use a variable to keep
// explicit track of the string length. C string lengths are not inherently
// stored anywhere.
size_t len = 1; // always keep track of the null byte
// +10 byte space for yeaar, spaces, brackets, and dash
len += strlen (movie.title) + 10 + strlen (movie.genre);
// Use one of the two techniques above to allocated enough space for the
// merged string. You should NOT rely on any length unless its exact value
// is known. For instance, you can assume that " [Year] - " adds 10 bytes,
// but you cannot assume anything about the length of the genre or title.
// As such, you need to compute those lengths using strlen(). Do not forget
// to account for the null byte.
char *result = calloc (len, sizeof (char));
snprintf (result, len, "%s [%d] - %s", movie.title, movie.year, movie.genre);
return result;
}
+16
View File
@@ -0,0 +1,16 @@
#ifndef __CS361_MOVIES_H__
#define __CS361_MOVIES_H__
#include <stdbool.h>
typedef struct movie
{
char *title;
int year;
char *genre;
} movie_t;
movie_t split_data (char *);
char *merge_data (movie_t);
#endif
+89
View File
@@ -0,0 +1,89 @@
#
# Simple Test Makefile
# Mike Lam, James Madison University, August 2016
#
# This version of the Makefile includes support for building a test suite. The
# recommended framework is Check (http://check.sourceforge.net/). To build and
# run the test suite, execute the "test" target. The test suite must be located
# in a module called "testsuite". The MODS, LIBS, and OBJS variables work as
# they do in the main Makefile.
#
# To change the default build target (which executes when you just type
# "make"), change the right-hand side of the definition of the "default"
# target.
#
# By default, this makefile will build the project with debugging symbols and
# without optimization. To change this, edit or remove the "-g" and "-O0"
# options in CFLAGS and LDFLAGS accordingly.
#
# By default, this makefile build the application using the GNU C compiler,
# adhering to the C99 standard with all warnings enabled.
# application-specific settings and run target
EXE=../ptrs
TEST=testsuite
MODS=public.o
OBJS=../movies.o
LIBS=
UTESTOUT=utests.txt
ITESTOUT=itests.txt
SCHECKOUT=style.txt
default: $(TEST)
$(EXE):
make -C ../
test: utest itest style
@echo "========================================"
utest: $(EXE) $(TEST)
@echo "========================================"
@echo " UNIT TESTS"
@./$(TEST) 2>/dev/null >$(UTESTOUT)
@cat $(UTESTOUT) | sed -n -e '/Checks/,$$p' | sed -e 's/^private.*:[EF]://g'
itest: $(EXE)
@echo "========================================"
@echo " INTEGRATION TESTS"
@./integration.sh | tee $(ITESTOUT)
style: $(EXE)
@echo "========================================"
@echo " CODING STYLE CHECK"
@./style.sh 2>/dev/null >$(SCHECKOUT)
@cat $(SCHECKOUT)
# compiler/linker settings
CC=gcc
CFLAGS=-g -O0 -Wall --std=c99 -pedantic
LDFLAGS=-g -O0
#CFLAGS+=-I/opt/local/include -Wno-gnu-zero-variadic-macro-arguments
CFLAGS+=-Wno-gnu-zero-variadic-macro-arguments
#LDFLAGS+=-L/opt/local/lib
LDFLAGS=
LIBS+=-lcheck -lm -lpthread
ifeq ($(shell uname -s),Linux)
LIBS+=-lrt -lsubunit
endif
# build targets
$(TEST): $(TEST).o $(MODS) $(OBJS)
$(CC) $(LDFLAGS) -o $(TEST) $^ $(LIBS)
%.o: %.c
$(CC) -c $(CFLAGS) $<
clean:
rm -rf $(TEST) $(TEST).o $(MODS) $(UTESTOUT) $(ITESTOUT) $(SCHECKOUT) outputs valgrind ckstyle
.PHONY: default clean test unittest inttest
@@ -0,0 +1 @@
514af63cc957d92dab366709ad95b76ad030e9d9
@@ -0,0 +1 @@
514af63cc957d92dab366709ad95b76ad030e9d9
@@ -0,0 +1,4 @@
Title: The Shawshank Redemption
Year: 1994
Genre: Drama
The Shawshank Redemption [1994] - Drama
@@ -0,0 +1,4 @@
Title: The Shawshank Redemption
Year: 1994
Genre: Drama
The Shawshank Redemption [1994] - Drama
+75
View File
@@ -0,0 +1,75 @@
#!/bin/bash
EXE="../ptrs"
function run_test {
# parameters
TAG=$1
ARGS=$2
# file paths
OUTPUT=outputs/$TAG.txt
DIFF=outputs/$TAG.diff
EXPECT=expected/$TAG.txt
VALGRND=valgrind/$TAG.txt
# print tag format
PTAG=$(printf '%-30s' "$TAG")
# check for expected text that needs to be fixed
if [ ! -z "$(egrep "<<<<.*>>>>" "$EXPECT")" ] ; then
echo "$PTAG FAIL ($EXPECT not correct)"
return
fi
# compare the file
SHAOUT=$(shasum "$EXPECT" | awk '{print $1}')
SHAEXP=$(cat "expected/.$TAG.sha")
if [ "$SHAOUT" != "$SHAEXP" ] ; then
echo "$PTAG FAIL ($EXPECT not correct)"
return
fi
# run test and compare output to the expected version
$EXE "$ARGS" 2>/dev/null >"$OUTPUT"
diff -u "$OUTPUT" "$EXPECT" >"$DIFF"
if [ -s "$DIFF" ]; then
# try alternative solution (if it exists)
EXPECT=expected/$TAG-2.txt
if [ -e "$EXPECT" ]; then
diff -u "$OUTPUT" "$EXPECT" >"$DIFF"
if [ -s "$DIFF" ]; then
echo "$PTAG FAIL (see $DIFF for details)"
else
echo "$PTAG pass"
fi
else
echo "$PTAG FAIL (see $DIFF for details)"
fi
else
echo "$PTAG pass"
fi
# run valgrind
valgrind $EXE $ARGS &>$VALGRND
}
# initialize output folders
mkdir -p outputs
mkdir -p valgrind
rm -f outputs/* valgrind/*
# run individual tests
source itests.include
# check for memory leaks
LEAK=`cat valgrind/*.txt | grep 'definitely lost' | grep -v ' 0 bytes in 0 blocks'`
if [ -z "$LEAK" ]; then
echo "No memory leak found."
else
echo "Memory leak(s) found. See files listed below for details."
grep 'definitely lost' valgrind/*.txt | grep -v ' 0 bytes in 0 blocks' | sed -e 's/:.*$//g' | sed -e 's/^/ - /g'
fi
+7
View File
@@ -0,0 +1,7 @@
# list of integration tests
# format: run_test <TAG> <ARGS>
# <TAG> used as the root for all filenames (i.e., "expected/$TAG.txt")
# <ARGS> command-line arguments to test
run_test INTEG_movies "-m"
run_test INTEG_movies_inc "-m"
+95
View File
@@ -0,0 +1,95 @@
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <check.h>
#include "../movies.h"
// Test that split_data gets the title copy
START_TEST (UNIT_split_title)
{
char *csv = "Casablanca,1942,Romance";
movie_t movie = split_data (csv);
ck_assert_str_eq (csv, "Casablanca,1942,Romance");
ck_assert_str_eq (movie.title, "Casablanca");
}
END_TEST
// Test that split_data parses numeric values
START_TEST (UNIT_split_nums)
{
char *csv = "Casablanca,1942,Romance";
movie_t movie = split_data (csv);
ck_assert_str_eq (csv, "Casablanca,1942,Romance");
ck_assert_int_eq (movie.year, 1942);
}
END_TEST
// Test that split_data gets the genre copy
START_TEST (UNIT_split_genre)
{
char *csv = "Casablanca,1942,Romance";
movie_t movie = split_data (csv);
ck_assert_str_eq (csv, "Casablanca,1942,Romance");
ck_assert_str_eq (movie.genre, "Romance");
}
END_TEST
// Test that split_data operates correctly on stack-based strings
START_TEST (UNIT_split_stack)
{
char csv[] = "Casablanca,1942,Romance";
movie_t movie = split_data (csv);
ck_assert_str_eq (movie.title, "Casablanca");
ck_assert_int_eq (movie.year, 1942);
ck_assert_str_eq (movie.genre, "Romance");
ck_assert_str_eq (csv, "Casablanca,1942,Romance");
}
END_TEST
// Test that merge_data combines the fields into a string
START_TEST (UNIT_merge_movie)
{
movie_t movie;
movie.title = "The Lord of the Rings: The Fellowship of the Ring";
movie.year = 2001;
movie.genre = "Fantasy";
char *result = merge_data (movie);
ck_assert_str_eq (result, "The Lord of the Rings: The Fellowship of the Ring [2001] - Fantasy");
free (result);
}
END_TEST
// Test that merge_data combines the fields from the heap into a string
START_TEST (UNIT_merge_heap)
{
movie_t *movie = calloc (1, sizeof (movie_t));
movie->title = "The Lord of the Rings: The Fellowship of the Ring";
movie->year = 2001;
movie->genre = "Fantasy";
char *result = merge_data (*movie);
ck_assert_str_eq (result, "The Lord of the Rings: The Fellowship of the Ring [2001] - Fantasy");
free (result);
result = NULL;
ck_assert_str_eq (movie->title, "The Lord of the Rings: The Fellowship of the Ring");
ck_assert_int_eq (movie->year, 2001);
ck_assert_str_eq (movie->genre, "Fantasy");
free (movie);
}
END_TEST
void public_tests (Suite *s)
{
TCase *tc_public = tcase_create ("Public");
tcase_add_test (tc_public, UNIT_split_title);
tcase_add_test (tc_public, UNIT_split_nums);
tcase_add_test (tc_public, UNIT_split_genre);
tcase_add_test (tc_public, UNIT_split_stack);
tcase_add_test (tc_public, UNIT_merge_movie);
tcase_add_test (tc_public, UNIT_merge_heap);
suite_add_tcase (s, tc_public);
}
+53
View File
@@ -0,0 +1,53 @@
#!/bin/bash
STYLE="gnu"
IGNORE=()
FAIL=0
function comp_file {
SRC=$1
SRC_NAME=$2
# file paths
FORMAT=ckstyle/${SRC_NAME}.$STYLE
DIFF=ckstyle/${SRC_NAME}.diff
# run clang-format and compare results
clang-format --style=$STYLE $source > $FORMAT
diff -u $SRC $FORMAT >$DIFF
PTAG=$(printf '%-30s' "$SRC_NAME")
if [ -s $DIFF ]; then
echo "$PTAG FAIL (see $DIFF for details)"
FAIL=1
else
echo "$PTAG pass"
rm $DIFF
fi
rm $FORMAT
}
mkdir -p ckstyle
rm -f ckstyle/*
for source in $(ls ../*.c ../*.h) ; do
SKIP=0
src=$(basename $source)
for ignore in ${IGNORE[*]} ; do
if [ "$src" = "$ignore" ] ; then
SKIP=1
fi
done
if [ $SKIP = 0 ] ; then
comp_file $source $src
fi
done
if [ $FAIL != 0 ] ; then
echo "Code that does not adhere to GNU standards will not be accepted."
echo "You must fix these files before submission."
else
echo "Code correctly adheres to required style."
fi
+36
View File
@@ -0,0 +1,36 @@
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <assert.h>
#include <time.h>
#include <check.h>
extern void public_tests (Suite *s);
void run_testsuite (void);
Suite *
test_suite (void)
{
Suite *s = suite_create ("Default");
public_tests (s);
return s;
}
void
run_testsuite (void)
{
Suite *s = test_suite ();
SRunner *sr = srunner_create (s);
srunner_run_all (sr, CK_NORMAL);
srunner_free (sr);
}
int
main (void)
{
srand((unsigned)time(NULL));
run_testsuite ();
return EXIT_SUCCESS;
}