Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adds support for optional args, with backwards compatibility #64

Merged
merged 12 commits into from
May 15, 2017
Prev Previous commit
Next Next commit
experimenting with optional args
dmalan committed Apr 9, 2017

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
commit 5932357b09bdd26a9047b5128f02a5377d016fcd
9 changes: 4 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
@@ -34,7 +34,7 @@ bash:
.PHONY: build
build: clean Makefile $(SRC) $(HDR)
mkdir -p "$(INCLUDE_DIR)" "$(LIB_DIR)" "$(MAN_DIR)" "$(BUILD_SRC)"
gcc -c -fPIC -std=c99 -Wall -Werror -o "$(OBJ)" "$(SRC)"
gcc -c -fPIC -std=gnu99 -Wall -o "$(OBJ)" "$(SRC)"
gcc -o "$(LIB_DIR)/libcs50.so" -shared "$(OBJ)"
rm -f "$(OBJ)"
cp "$(HDR)" "$(INCLUDE_DIR)"
@@ -111,7 +111,6 @@ rpm: build
# TODO: improve test suite
.PHONY: test
test: build hackerrank
clang -ggdb3 -I "$(INCLUDE_DIR)" -O0 -std=c99 -Wall -Werror -Wno-deprecated-declarations "$(TESTS_DIR)/eprintf.c" -L "$(LIB_DIR)" -lcs50 -o "$(EPRINTF_EXE)"
clang -I "$(BUILD_DIR)" -std=c99 -Wall -Werror -Wno-deprecated-declarations "$(TESTS_DIR)/hackerrank.c" -o "$(HR_EXE)"
LD_LIBRARY_PATH="$(LIB_DIR)" "$(EPRINTF_EXE)"
"$(HR_EXE)"
#clang -ggdb3 -I "$(INCLUDE_DIR)" -O0 -std=c99 -Wall -Werror -Wno-deprecated-declarations "$(TESTS_DIR)/eprintf.c" -L "$(LIB_DIR)" -lcs50 -o "$(EPRINTF_EXE)"
#clang -I "$(BUILD_DIR)" -std=c99 -Wall -Werror -Wno-deprecated-declarations "$(TESTS_DIR)/hackerrank.c" -o "$(HR_EXE)"
clang -ggdb3 -I "$(INCLUDE_DIR)" -O0 -std=gnu99 -Wall -Werror -Wno-deprecated-declarations "$(TESTS_DIR)/get_int.c" -L "$(LIB_DIR)" -lcs50 -o "$(BUILD_DIR)"/get_int
2,947 changes: 2,947 additions & 0 deletions src/OUT

Large diffs are not rendered by default.

64 changes: 31 additions & 33 deletions src/cs50.c
Original file line number Diff line number Diff line change
@@ -51,23 +51,6 @@

#include "cs50.h"

/**
*
* https://gustedt.wordpress.com/2010/06/03/default-arguments-for-c99/
*/
#define _ARGS(_0, _1, _2, ...) _2
#define ARGS(...) _ARGS(, ##__VA_ARGS__, 1, 0)
#define ARG_0(NAME) retry()
#define ARG_1(NAME, a) a
#define __ZERO_OR_ONE_ARG(NAME, N, ...) ARG_ ## N (NAME, ##__VA_ARGS__)
#define _ZERO_OR_ONE_ARG(NAME, N, ...) __ZERO_OR_ONE_ARG(NAME, N, ##__VA_ARGS__)
#define ZERO_OR_ONE_ARG(NAME, ...) NAME(_ZERO_OR_ONE_ARG(NAME, ARGS(__VA_ARGS__), ##__VA_ARGS__))
#define get_int(...) ZERO_OR_ONE_ARG(get_int, ##__VA_ARGS__)
static inline string retry(void)
{
return "Retry: ";
}

/**
* Prints an error message, formatted like printf, to standard error, prefixing it with program's
* name as well as the file and line number from which function was called, which a macro is
@@ -105,7 +88,7 @@ void eprintf(const char *file, int line, const char *format, ...)
* Leading and trailing whitespace is ignored. If line can't be read,
* returns CHAR_MAX.
*/
char get_char(void)
char get_char(string prompt)
{
// try to get a char from user
while (true)
@@ -123,18 +106,21 @@ char get_char(void)
{
return c;
}
printf("Retry: ");
printf("%s", prompt);
}
}
char (*GetChar)(void) = get_char;
char GetChar(void)
{
return get_char();
}

/**
* Reads a line of text from standard input and returns the equivalent
* double as precisely as possible; if text does not represent a
* double or if value would cause underflow or overflow, user is
* prompted to retry. If line can't be read, returns DBL_MAX.
*/
double get_double(void)
double get_double(string prompt)
{
// try to get a double from user
while (true)
@@ -161,18 +147,21 @@ double get_double(void)
}
}
}
printf("Retry: ");
printf("%s", prompt);
}
}
double (*GetDouble)(void) = get_double;
double GetDouble(void)
{
return get_double();
}

/**
* Reads a line of text from standard input and returns the equivalent
* float as precisely as possible; if text does not represent a float
* or if value would cause underflow or overflow, user is prompted to
* retry. If line can't be read, returns FLT_MAX.
*/
float get_float(void)
float get_float(string prompt)
{
// try to get a float from user
while (true)
@@ -199,18 +188,21 @@ float get_float(void)
}
}
}
printf("Retry: ");
printf("%s", prompt);
}
}
float (*GetFloat)(void) = get_float;
float GetFloat(void)
{
return get_float();
}

/**
* Reads a line of text from standard input and returns it as an
* int in [-2^31, 2^31 - 1), if possible; if text does not represent
* such an int or if value would cause underflow or overflow, user is
* prompted to retry. If line can't be read, returns INT_MAX.
*/
int get_int(string s)
int get_int(string prompt)
{
// try to get an int from user
while (true)
@@ -233,18 +225,21 @@ int get_int(string s)
return n;
}
}
printf("Retry: ");
printf("%s", prompt);
}
}
int (*GetInt)(void) = get_int;
int GetInt(void)
{
return get_int();
}

/**
* Reads a line of text from standard input and returns an equivalent
* long long in [-2^63, 2^63 - 1), if possible; if text does not
* represent such a long long or if value would cause underflow or overflow,
* user is prompted to retry. If line can't be read, returns LLONG_MAX.
*/
long long get_long_long(void)
long long get_long_long(string prompt)
{
// try to get a long long from user
while (true)
@@ -267,10 +262,13 @@ long long get_long_long(void)
return n;
}
}
printf("Retry: ");
printf("%s", prompt);
}
}
long long (*GetLongLong)(void) = get_long_long;
long long GetLongLong(void)
{
return get_long_long();
}

/**
* Number of strings allocated by get_string.
@@ -290,7 +288,7 @@ static string *strings = NULL;
* error or no input whatsoever (i.e., just EOF). Stores string
* on heap, but library's destructor frees memory on program's exit.
*/
string get_string(void)
string get_string(string prompt)
{
// check whether we have room for another string
if (allocations == SIZE_MAX)
43 changes: 31 additions & 12 deletions src/cs50.h
Original file line number Diff line number Diff line change
@@ -46,6 +46,19 @@
#include <stdbool.h>
#include <stdlib.h>

/**
* TODO
*
* https://gustedt.wordpress.com/2010/06/03/default-arguments-for-c99/
*/
#define _ARGS(_0, _1, _2, ...) _2
#define ARGS(...) _ARGS(, ##__VA_ARGS__, 1, 0)
#define ARG_0(NAME) "Retry: "
#define ARG_1(NAME, a) a
#define __ZERO_OR_ONE_ARG(NAME, N, ...) ARG_ ## N (NAME, ##__VA_ARGS__)
#define _ZERO_OR_ONE_ARG(NAME, N, ...) __ZERO_OR_ONE_ARG(NAME, N, ##__VA_ARGS__)
#define ZERO_OR_ONE_ARG(NAME, ...) NAME(_ZERO_OR_ONE_ARG(NAME, ARGS(__VA_ARGS__), ##__VA_ARGS__))

/**
* Our own data type for string variables.
*/
@@ -77,44 +90,49 @@ void eprintf(const char *file, int line, const char *format, ...) __attribute__(
* Leading and trailing whitespace is ignored. If line can't be read,
* returns CHAR_MAX.
*/
char get_char(void);
extern char (*GetChar)(void);
char get_char(string prompt);
char GetChar(void) __attribute__((deprecated));
#define get_char(...) ZERO_OR_ONE_ARG(get_char, ##__VA_ARGS__)

/**
* Reads a line of text from standard input and returns the equivalent
* double as precisely as possible; if text does not represent a
* double or if value would cause underflow or overflow, user is
* prompted to retry. If line can't be read, returns DBL_MAX.
*/
double get_double(void);
extern double (*GetDouble)(void);
double get_double(string prompt);
double GetDouble(void) __attribute__((deprecated));
#define get_double(...) ZERO_OR_ONE_ARG(get_double, ##__VA_ARGS__)

/**
* Reads a line of text from standard input and returns the equivalent
* float as precisely as possible; if text does not represent a float
* or if value would cause underflow or overflow, user is prompted to
* retry. If line can't be read, returns FLT_MAX.
*/
float get_float(void);
extern float (*GetFloat)(void);
float get_float(string prompt);
float GetFloat(void) __attribute__((deprecated));
#define get_float(...) ZERO_OR_ONE_ARG(get_float, ##__VA_ARGS__)

/**
* Reads a line of text from standard input and returns it as an
* int in [-2^31, 2^31 - 1), if possible; if text does not represent
* such an int or if value would cause underflow or overflow, user is
* prompted to retry. If line can't be read, returns INT_MAX.
*/
int get_int(string s);
extern int (*GetInt)(void);
int get_int(string prompt);
int GetInt(void) __attribute__((deprecated));
#define get_int(...) ZERO_OR_ONE_ARG(get_int, ##__VA_ARGS__)

/**
* Reads a line of text from standard input and returns an equivalent
* long long in [-2^63, 2^63 - 1), if possible; if text does not
* represent such a long long or if value would cause underflow or overflow,
* user is prompted to retry. If line can't be read, returns LLONG_MAX.
*/
long long get_long_long(void);
extern long long (*GetLongLong)(void);
long long get_long_long(string prompt);
long long GetLongLong(void) __attribute__((deprecated));
#define get_long_long(...) ZERO_OR_ONE_ARG(get_long_long, ##__VA_ARGS__)

/**
* Reads a line of text from standard input and returns it as
@@ -124,7 +142,8 @@ extern long long (*GetLongLong)(void);
* error or no input whatsoever (i.e., just EOF). Stores string
* on heap, but library's destructor frees memory on program's exit.
*/
string get_string(void);
string GetString(void);
string get_string(string prompt);
string GetString(void) __attribute__((deprecated));
#define get_string(...) ZERO_OR_ONE_ARG(get_string, ##__VA_ARGS__)

#endif
2 changes: 1 addition & 1 deletion tests/eprintf.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#include <stdio.h>
#include "cs50.h"
#include "stdio.h"

int main(void)
{