Added C99 Solution

This commit is contained in:
Clay Dowling 2017-03-13 21:30:37 -04:00
parent 45733a5129
commit a8561778e9
7 changed files with 299 additions and 0 deletions

90
c99/GildedRose.c Normal file
View File

@ -0,0 +1,90 @@
#include <string.h>
#include "GildedRose.h"
Item*
init_item(Item* item, const char *name, int sellIn, int quality)
{
item->sellIn = sellIn;
item->quality = quality;
item->name = strdup(name);
return item;
}
void update_quality(Item items[], int size)
{
int i;
for (i = 0; i < size; i++)
{
if (strcmp(items[i].name, "Aged Brie") && strcmp(items[i].name, "Backstage passes to a TAFKAL80ETC concert"))
{
if (items[i].quality > 0)
{
if (strcmp(items[i].name, "Sulfuras, Hand of Ragnaros"))
{
items[i].quality = items[i].quality - 1;
}
}
}
else
{
if (items[i].quality < 50)
{
items[i].quality = items[i].quality + 1;
if (!strcmp(items[i].name, "Backstage passes to a TAFKAL80ETC concert"))
{
if (items[i].sellIn < 11)
{
if (items[i].quality < 50)
{
items[i].quality = items[i].quality + 1;
}
}
if (items[i].sellIn < 6)
{
if (items[i].quality < 50)
{
items[i].quality = items[i].quality + 1;
}
}
}
}
}
if (strcmp(items[i].name, "Sulfuras, Hand of Ragnaros"))
{
items[i].sellIn = items[i].sellIn - 1;
}
if (items[i].sellIn < 0)
{
if (strcmp(items[i].name, "Aged Brie"))
{
if (strcmp(items[i].name, "Backstage passes to a TAFKAL80ETC concert"))
{
if (items[i].quality > 0)
{
if (strcmp(items[i].name, "Sulfuras, Hand of Ragnaros"))
{
items[i].quality = items[i].quality - 1;
}
}
}
else
{
items[i].quality = items[i].quality - items[i].quality;
}
}
else
{
if (items[i].quality < 50)
{
items[i].quality = items[i].quality + 1;
}
}
}
}
}

9
c99/GildedRose.h Normal file
View File

@ -0,0 +1,9 @@
typedef struct
{
char *name;
int sellIn;
int quality;
} Item;
extern Item* init_item(Item* item, const char *name, int sellIn, int quality);
extern void update_quality(Item items[], int size);

43
c99/GildedRoseTextTests.c Normal file
View File

@ -0,0 +1,43 @@
#include <stdio.h>
#include "GildedRose.h"
int
print_item(Item *item)
{
return printf("%s, %d, %d\n", item->name, item->sellIn, item->quality);
}
int main()
{
Item items[9];
int last = 0;
int day;
int index;
init_item(items + last++, "+5 Dexterity Vest", 10, 20);
init_item(items + last++, "Aged Brie", 2, 0);
init_item(items + last++, "Elixir of the Mongoose", 5, 7);
init_item(items + last++, "Sulfuras, Hand of Ragnaros", 0, 80);
init_item(items + last++, "Sulfuras, Hand of Ragnaros", -1, 80);
init_item(items + last++, "Backstage passes to a TAFKAL80ETC concert", 15, 20);
init_item(items + last++, "Backstage passes to a TAFKAL80ETC concert", 10, 49);
init_item(items + last++, "Backstage passes to a TAFKAL80ETC concert", 5, 49);
// this Conjured item doesn't yet work properly
init_item(items + last++, "Conjured Mana Cake", 3, 6);
puts("OMGHAI!");
for (day = 0; day <= 30; day++)
{
printf("-------- day %d --------\n", day);
printf("name, sellIn, quality\n");
for(index = 0; index < last; index++) {
print_item(items + index);
}
printf("\n");
update_quality(items, last);
}
return 0;
}

51
c99/Makefile Normal file
View File

@ -0,0 +1,51 @@
# Makefile for building the kata file with the Google Testing Framework
#
# SYNOPSIS:
#
# make [all] - makes everything, runs tests
# make TARGET - makes the given target.
# make clean - removes all files generated by make.
# make memtest - run memory leak analysis
# The _POSIX_C_SOURCE definition prevents the compiler from throwing warnings
CFLAGS = `pkg-config --cflags check` -g --std=c99 -D_POSIX_C_SOURCE=200809L
LIBS = `pkg-config --libs check`
# All files that should be part of your test should start with 'test_'
TEST_SRC = $(wildcard test_*.c)
TEST_BASE = $(basename ${TEST_SRC})
TEST_OBJECTS = $(addsuffix .o, ${TEST_BASE})
# All files that should be part of your main program should start with 'gilded_'
PROG_SRC = $(wildcard gilded_*.c)
PROG_BASE = $(basename ${PROG_SRC})
PROG_OBJECTS = $(addsuffix .o, ${PROG_BASE})
OBJECT_UNDER_TEST = GildedRose.o ${PROG_OBJECTS}
# This is the test application. You can run this program to see your test output
TEST_APP = test_gildedrose
# This will generate output for several products over a course of several days.
# You can run this application to build golden rule tests
GOLDEN_APP = golden_rose
all: ${TEST_APP} ${GOLDEN_APP}
./${TEST_APP}
${TEST_APP}: ${TEST_OBJECTS} ${OBJECT_UNDER_TEST}
$(CC) $(CFLAGS) -o $@ $^ $(LIBS)
${GOLDEN_APP}: GildedRoseTextTests.o ${OBJECT_UNDER_TEST}
$(CC) $(CFLAGS) -o $@ $^
# If you're not on a mac, you should run memtest (in fact, consider adding it to the 'all' target).
# If you're on a mac, complain to apple for breaking an important development tool.
memtest: ${TEST_APP}
valgrind --leak-check=full --error-exitcode=1 ./${TEST_APP} --nofork
clean:
rm -f *.o
rm -f ${TEST_APP}
rm -f ${GOLDEN_APP}

41
c99/README.md Normal file
View File

@ -0,0 +1,41 @@
# Gilded Rose, C99 Edition
The command "make" will build and run your tests, as well as build the program
golden_rose, which can serve as the basis for a golden-rule test.
## Assumptions
- gnu make and a C compiler (like gcc) is installed on your system and is in the PATH
- The check unit testing library is installed on your system (https://libcheck.github.io/check/)
- pkg-config is installed on your system
## Usage
- Run `make` to build the program and run all tests
- Files which contain tests should be named `test_*.c` They will automatically
be included in your test suite.
- `GildedRose.h` should not be modified. The Goblin threat is real.
- New program logic may be included in files named `gilded_*.c` which will
automatically be included in both your tests and the final program.
## Golden Rule tests
- The program `golden_rose` will generate text output. If you capture this
output after your first `make` you can use this as a reference for a golden
rule test.
- You can test your work against this reference by directing the output of your
current golden_rose to a file and using the `diff` utility to compare that
to the reference file you created above.
- To avoid the Goblin threat you can use `git diff GildedRose.h`, which should
have no output if you have left the precious Item structure unchanged.
## Notes
- This project is tweaked to run on Linux systems, and will mostly work on Macs.
With some changes to the Makefile it can be made to run on BSD systems with
BSD make. An adventurous person could also get it to run on Windows.
- If you are working on a Macintosh computer you cannot run the memtest target,
because valgrind and OS X don't play nice any more. If you want to use the
memory checker OS X does run docker as a first class citizen.
- If you don't have pkg-config on your system, the only changes you'll need to
make are for the requirements of the check library. Mostly you need to
set the appropriate flags for threaded binaries, which may include some
special linker flags. The libcheck documentation will cover what you need
if you want to undertake this change.

31
c99/test_main.c Normal file
View File

@ -0,0 +1,31 @@
#include <stdio.h>
#include <stdlib.h>
#include <check.h>
Suite *suite_rose(void);
int main(int argc, char **argv)
{
Suite *s;
SRunner *runner;
int number_fails;
int forkme = 1;
if (argc > 1 && strcmp(argv[1], "--nofork") == 0) {
forkme = 0;
}
s = suite_rose();
runner = srunner_create(s);
if (0 == forkme) {
srunner_set_fork_status(runner, CK_NOFORK);
}
srunner_run_all(runner, CK_NORMAL);
number_fails = srunner_ntests_failed(runner);
srunner_free(runner);
return number_fails;
}

34
c99/test_rose.c Normal file
View File

@ -0,0 +1,34 @@
#include <check.h>
#include "GildedRose.h"
START_TEST(roseFoo)
{
Item items[1];
init_item(items, "foo", 0, 0);
update_quality(items, 1);
ck_assert_str_eq("fixme", items[0].name);
}
END_TEST
TCase *tcase_rose(void)
{
TCase *tc;
tc = tcase_create("gilded-rose");
tcase_add_test(tc, roseFoo);
return tc;
}
Suite *suite_rose(void)
{
Suite *s;
s = suite_create("characterization-tests");
suite_add_tcase(s, tcase_rose());
return s;
}