From 595cae98a1d953fb9ad77f5734cbc22d2b05f102 Mon Sep 17 00:00:00 2001 From: Gene Stark Date: Sat, 15 Jan 2022 16:47:59 -0500 Subject: [PATCH 01/10] Bring in basecode from development repo. --- .gitlab-ci.yml | 29 + hw1/.gitignore | 6 + hw1/Makefile | 61 + hw1/hw1.sublime-project | 50 + hw1/include/argo.h | 242 ++++ hw1/include/debug.h | 88 ++ hw1/include/global.h | 87 ++ hw1/lib/argo.a | Bin 0 -> 19100 bytes hw1/rsrc/numbers.json | 17 + hw1/rsrc/package-lock.json | 2419 ++++++++++++++++++++++++++++++++ hw1/rsrc/strings.json | 11 + hw1/src/argo.c | 148 ++ hw1/src/const.c | 47 + hw1/src/main.c | 33 + hw1/src/validargs.c | 26 + hw1/tests/basecode_tests.c | 95 ++ hw1/tests/rsrc/strings_-c.json | 1 + 17 files changed, 3360 insertions(+) create mode 100644 .gitlab-ci.yml create mode 100644 hw1/.gitignore create mode 100644 hw1/Makefile create mode 100644 hw1/hw1.sublime-project create mode 100644 hw1/include/argo.h create mode 100644 hw1/include/debug.h create mode 100644 hw1/include/global.h create mode 100644 hw1/lib/argo.a create mode 100644 hw1/rsrc/numbers.json create mode 100644 hw1/rsrc/package-lock.json create mode 100644 hw1/rsrc/strings.json create mode 100644 hw1/src/argo.c create mode 100644 hw1/src/const.c create mode 100644 hw1/src/main.c create mode 100644 hw1/src/validargs.c create mode 100644 hw1/tests/basecode_tests.c create mode 100644 hw1/tests/rsrc/strings_-c.json diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..d3bb8f3 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,29 @@ +image: hwrunner:latest +variables: + GIT_SSL_NO_VERIFY: "true" + EXEC: argo + HW_DIR: hw1 + CPU_LIMIT: 60 + FILE_LIMIT: 1000000 +before_script: + - make clean all -C ${HW_DIR} +stages: + - build + - run + - test +build: + stage: build + script: + - echo "Build done" +run: + stage: run + script: + - ulimit -t ${CPU_LIMIT} + - ulimit -f ${FILE_LIMIT} + - cd ${HW_DIR} && bin/${EXEC} -h +test: + stage: test + script: + - ulimit -t ${CPU_LIMIT} + - ulimit -f ${FILE_LIMIT} + - cd ${HW_DIR} && bin/${EXEC}_tests -S --verbose=0 --timeout 30 diff --git a/hw1/.gitignore b/hw1/.gitignore new file mode 100644 index 0000000..665cbf9 --- /dev/null +++ b/hw1/.gitignore @@ -0,0 +1,6 @@ +bin/ +build/ +test_output/ +*~ +*.out +*.bak diff --git a/hw1/Makefile b/hw1/Makefile new file mode 100644 index 0000000..e3efe98 --- /dev/null +++ b/hw1/Makefile @@ -0,0 +1,61 @@ +CC := gcc +SRCD := src +TSTD := tests +BLDD := build +BIND := bin +INCD := include +LIBD := lib + +EXEC := argo +TEST_EXEC := $(EXEC)_tests + +MAIN := $(BLDD)/main.o +LIB := $(LIBD)/$(EXEC).a + +ALL_SRCF := $(shell find $(SRCD) -type f -name *.c) +ALL_OBJF := $(patsubst $(SRCD)/%,$(BLDD)/%,$(ALL_SRCF:.c=.o)) +ALL_FUNCF := $(filter-out $(MAIN) $(AUX), $(ALL_OBJF)) + +TEST_ALL_SRCF := $(shell find $(TSTD) -type f -name *.c) +TEST_SRCF := $(filter-out $(TEST_REF_SRCF), $(TEST_ALL_SRCF)) + +INC := -I $(INCD) + +CFLAGS := -Wall -Werror -Wno-unused-variable -Wno-unused-function -MMD -fcommon +COLORF := -DCOLOR +DFLAGS := -g -DDEBUG -DCOLOR +PRINT_STAMENTS := -DERROR -DSUCCESS -DWARN -DINFO + +STD := -std=gnu11 +TEST_LIB := -lcriterion +LIBS := $(LIB) + +CFLAGS += $(STD) + +.PHONY: clean all setup debug + +all: setup $(BIND)/$(EXEC) $(BIND)/$(TEST_EXEC) + +debug: CFLAGS += $(DFLAGS) $(PRINT_STAMENTS) $(COLORF) +debug: all + +setup: $(BIND) $(BLDD) +$(BIND): + mkdir -p $(BIND) +$(BLDD): + mkdir -p $(BLDD) + +$(BIND)/$(EXEC): $(ALL_OBJF) + $(CC) $^ -o $@ $(LIBS) + +$(BIND)/$(TEST_EXEC): $(ALL_FUNCF) $(TEST_SRCF) + $(CC) $(CFLAGS) $(INC) $(ALL_FUNCF) $(TEST_SRCF) $(TEST_LIB) $(LIBS) -o $@ + +$(BLDD)/%.o: $(SRCD)/%.c + $(CC) $(CFLAGS) $(INC) -c -o $@ $< + +clean: + rm -rf $(BLDD) $(BIND) + +.PRECIOUS: $(BLDD)/*.d +-include $(BLDD)/*.d diff --git a/hw1/hw1.sublime-project b/hw1/hw1.sublime-project new file mode 100644 index 0000000..5465569 --- /dev/null +++ b/hw1/hw1.sublime-project @@ -0,0 +1,50 @@ +{ + "folders": + [ + { + "path":".", + "name":"Project Base" + }, + { + "path": "src", + "name": "C Source", + "follow_symlinks": false, + "file_include_patterns":["*.c"], + }, + { + "path": "include", + "name": "C Headers", + "follow_symlinks": false, + "file_include_patterns":["*.h"], + }, + { + "path": "tests", + "name": "Tests", + } + { + "path": "rsrc", + "name": "Resource Files", + } + ], + "settings": + { + }, + "build_systems": + [ + { + "name": "Release (full build)", + "working_dir":"$project_path", + "shell_cmd": "make clean all", + }, + { + "name": "Debug (full build)", + "working_dir":"$project_path", + "shell_cmd": "make clean debug", + }, + { + "name": "Test", + "working_dir":"$project_path", + "shell_cmd": "bin/${project_base_name}_tests}", + } + ] +} diff --git a/hw1/include/argo.h b/hw1/include/argo.h new file mode 100644 index 0000000..005f6b6 --- /dev/null +++ b/hw1/include/argo.h @@ -0,0 +1,242 @@ +/* + * DO NOT MODIFY THE CONTENTS OF THIS FILE. + * IT WILL BE REPLACED DURING GRADING + */ +#ifndef ARGO_H +#define ARGO_H + +/* + * Definitions for "Argo" (aka JSON). + */ + +/* + * USAGE macro to be called from main() to print a help message and exit + * with a specified exit status. + */ +#define USAGE(program_name, retcode) do { \ +fprintf(stderr, "USAGE: %s %s\n", program_name, \ +"[-h] [-c|-v] [-p INDENT]\n" \ +" -h Help: displays this help menu.\n" \ +" -v Validate: the program reads from standard input and checks whether\n" \ +" it is syntactically correct JSON. If there is any error, then a message\n" \ +" describing the error is printed to standard error before termination.\n" \ +" No other output is produced.\n" \ +" -c Canonicalize: once the input has been read and validated, it is\n" \ +" re-emitted to standard output in 'canonical form'. Unless -p has been\n" \ +" specified, the canonicalized output contains no whitespace (except within\n" \ +" strings that contain whitespace characters).\n" \ +" -p Pretty-print: This option is only permissible if -c has also been specified.\n" \ +" In that case, newlines and spaces are used to format the canonical output\n" \ +" in a more human-friendly way. For the precise requirements on where this\n" \ +" whitespace must appear, see the assignment handout.\n" \ +" The INDENT is an optional nonnegative integer argument that specifies the\n" \ +" number of additional spaces to be output at the beginning of a line for each\n" \ +" for each increase in indentation level. If no value is specified, then a\n" \ +" default value of 4 is used.\n" \ +); \ +exit(retcode); \ +} while(0) + +/* + * Type used to represent an input character. It is intended to + * represent a Unicode code point (4 bytes max), so the C type + * "char" is not used. It is signed, so that we can represent + * the out-of-band value EOF (-1) as a value of this type. + */ +typedef int ARGO_CHAR; + +/* + * Type codes for Argo values. + */ +typedef enum { + ARGO_NO_TYPE = 0, + ARGO_BASIC_TYPE = 1, + ARGO_NUMBER_TYPE = 2, + ARGO_STRING_TYPE = 3, + ARGO_OBJECT_TYPE = 4, + ARGO_ARRAY_TYPE = 5 +} ARGO_VALUE_TYPE; + +/* + * Basic Argo values, represented by the (unquoted) tokens + * "true", "false", or "null" in Argo code. + */ +typedef enum { + ARGO_NULL, ARGO_TRUE, ARGO_FALSE +} ARGO_BASIC; + +/* + * Structure used to hold a string value. + * The content field is maintained as an array of char, which is not null-terminated + * and which might contain '\0' characters. This data is interpreted as Unicode text, + * represented as an array of ARGO_CHAR values, each of which represents a single + * Unicode code point. The length field gives the length in bytes of the data. + * The capacity field records the actual size of the data area. This is included so + * that the size can be dynamically increased while the string is being read. + */ +typedef struct argo_string { + size_t capacity; // Current total size of space in the content. + size_t length; // Current length of the content. + ARGO_CHAR *content; // Unicode code points (not null terminated). +} ARGO_STRING; + +/* + * Structure used to hold a number. + * The "text_value" field holds a printable/parseable representation of the number + * as Unicode text, conforming to the Argo standard. + * The "int_value" field holds the value of the number in integer format, if the + * number can be exactly represented as such. + * The "float_value" field holds the value of the number in floating-point format. + * The "valid_text" field is nonzero if the "text_valid" field contains a valid + * representation of the value. + * The "valid_int" field is nonzero if the "int_value" field contains a valid + * representation of the value. + * The "valid_float" field is nonzero if the "float_value" field contains a valid + * representation of the value. + * + * If multiple representations of the value of the number are present, they should + * agree with each other. + * It is up to an application to determine which representation is the appropriate + * one to use, based on the semantics of the data being represented. + */ +typedef struct argo_number { + struct argo_string string_value; // Value represented in textual format. + long int_value; // Value represented in integer format. + double float_value; // Value represented in floating-point format. + char valid_string; // Nonzero if string representation is valid. + char valid_int; // Nonzero if integer representation is valid. + char valid_float; // Nonzero if floating point representation is valid. +} ARGO_NUMBER; + +/* + * An "object" has a list of members, each of which has a name and a value. + * To store the members, we use a circular, doubly linked list, with the next and + * previous pointers stored in the "next" and "prev" fields of the ARGO_VALUE structure + * and the member name stored in the "name" field of the ARGO_VALUE structure. + * The "member_list" field of the ARGO_OBJECT structure serves as the sentinel at + * the head of the list. This element does not represent one of the members; + * rather, its "next" field points to the first member and its "prev" field points + * to the last member. An empty list of members is represented by the situation in + * which both the "next" and "prev" fields point back to the sentinel object itself. + * + * Note that the collection of members of an object is supposed to be regarded as unordered, + * which would permit it to be represented using a hash map or similar data structure, + * which we are not doing here. + */ +typedef struct argo_object { + struct argo_value *member_list; +} ARGO_OBJECT; + +/* + * An "array" has an ordered sequence of elements, each of which is just a value. + * Here we represent the elements as a circular, doubly linked list, in the same + * way as for the members of an object. The "element_list" field in the ARGO_ARRAY + * structure serves as the sentinel at the head of the list. + * + * Note that elements of an array do not have any name, so the "name" field in each + * of the elements will be NULL. Arrays could be represented as actual arrays, + * but we are not doing that here. + */ +typedef struct argo_array { + struct argo_value *element_list; +} ARGO_ARRAY; + +/* + * The ARGO_VALUE structure is used to represent all kinds of Argo values. + * The "type" field tells what type of value it represents. + * It has "next" and "prev" fields so that it can be linked into "members" + * or "elements" lists. It has a "name" field which will hold the name in case + * it is a member of an object. The "content" field is the union of the structures + * that represent the various Argo types. Depending on the value of the "type" field, + * one of the "object", "array", or "string", "number", or "basic" variants of this union + * will be valid. + */ +typedef struct argo_value { + ARGO_VALUE_TYPE type; + struct argo_value *next; // Next value in list of members or elements. + struct argo_value *prev; // Previous value in list of members or element. + struct argo_string name; // NULL unless value is an object member. + union { + struct argo_object object; + struct argo_array array; + struct argo_string string; + struct argo_number number; + ARGO_BASIC basic; + } content; +} ARGO_VALUE; + +/* + * The following value is the maximum number of digits that will be printed + * for a floating point value. + */ +#define ARGO_PRECISION 15 + +/* + * Macros that define particular character values mentioned in the Argo standard. + * You should use these macros where reference to these character values is required, + * rather than "hard-coding" the values as C character constants. + */ +#define ARGO_COLON ':' +#define ARGO_LBRACE '{' +#define ARGO_RBRACE '}' +#define ARGO_LBRACK '[' +#define ARGO_RBRACK ']' +#define ARGO_QUOTE '"' +#define ARGO_BSLASH '\\' +#define ARGO_FSLASH '/' +#define ARGO_COMMA ',' +#define ARGO_PERIOD '.' +#define ARGO_PLUS '+' +#define ARGO_MINUS '-' +#define ARGO_DIGIT0 '0' +#define ARGO_B 'b' +#define ARGO_E 'e' +#define ARGO_F 'f' +#define ARGO_N 'n' +#define ARGO_R 'r' +#define ARGO_T 't' +#define ARGO_U 'u' +#define ARGO_BS '\b' +#define ARGO_FF '\f' +#define ARGO_LF '\n' +#define ARGO_CR '\r' +#define ARGO_HT '\t' +#define ARGO_SPACE ' ' + +/* + * Macros that define particular classes of characters mentioned in the Argo standard. + * You should use these macros when it is necessary to test whether a character belongs + * to a particular class, rather than "hard-coding" expressions involving C character + * constants. + */ +#define argo_is_whitespace(c) ((c) == ' ' || (c) == '\n' || (c) == '\r' || c == '\t') +#define argo_is_exponent(c) ((c) == 'e' || (c) == 'E') +#define argo_is_digit(c) ((c) >= '0' && (c) <= '9') +#define argo_is_hex(c) (argo_is_digit(c) || ((c) >= 'A' && (c) <= 'F') || ((c) >= 'a' && (c) <= 'f')) +#define argo_is_control(c) ((c) >= 0 && (c) < ' ') + +/* + * Macros that define the tokens used to represent the basic values + * "true", "false", and "null", defined by the Argo standard. + * You should use these macros rather than "hard-coding" C string literals + * into your program. + */ +#define ARGO_TRUE_TOKEN "true" +#define ARGO_FALSE_TOKEN "false" +#define ARGO_NULL_TOKEN "null" + +/* + * Variable that is reset to zero at the beginning of each line and is + * incremented each time a character is read by function argo_read_char(). + * It is intended to be used for error messages and debugging. It can be + * assigned to if it is necessary to reset the value for some reason, + * such as if reading from multiple sources is done. + */ + +/* + * The following function is used to append a character to a string. + * An implementation has been provided for you. + */ +int argo_append_char(ARGO_STRING *, ARGO_CHAR); + +#endif diff --git a/hw1/include/debug.h b/hw1/include/debug.h new file mode 100644 index 0000000..e8fc8b6 --- /dev/null +++ b/hw1/include/debug.h @@ -0,0 +1,88 @@ +#ifndef DEBUG_H +#define DEBUG_H + +#include + +#define NL "\n" + +#ifdef COLOR +#define KNRM "\033[0m" +#define KRED "\033[1;31m" +#define KGRN "\033[1;32m" +#define KYEL "\033[1;33m" +#define KBLU "\033[1;34m" +#define KMAG "\033[1;35m" +#define KCYN "\033[1;36m" +#define KWHT "\033[1;37m" +#define KBWN "\033[0;33m" +#else +#define KNRM "" +#define KRED "" +#define KGRN "" +#define KYEL "" +#define KBLU "" +#define KMAG "" +#define KCYN "" +#define KWHT "" +#define KBWN "" +#endif + +#ifdef VERBOSE +#define DEBUG +#define INFO +#define WARN +#define ERROR +#define SUCCESS +#endif + +#ifdef DEBUG +#define debug(S, ...) \ + do { \ + fprintf(stderr, KMAG "DEBUG: %s:%s:%d " KNRM S NL, __FILE__, \ + __extension__ __FUNCTION__, __LINE__, ##__VA_ARGS__); \ + } while (0) +#else +#define debug(S, ...) +#endif + +#ifdef INFO +#define info(S, ...) \ + do { \ + fprintf(stderr, KBLU "INFO: %s:%s:%d " KNRM S NL, __FILE__, \ + __extension__ __FUNCTION__, __LINE__, ##__VA_ARGS__); \ + } while (0) +#else +#define info(S, ...) +#endif + +#ifdef WARN +#define warn(S, ...) \ + do { \ + fprintf(stderr, KYEL "WARN: %s:%s:%d " KNRM S NL, __FILE__, \ + __extension__ __FUNCTION__, __LINE__, ##__VA_ARGS__); \ + } while (0) +#else +#define warn(S, ...) +#endif + +#ifdef SUCCESS +#define success(S, ...) \ + do { \ + fprintf(stderr, KGRN "SUCCESS: %s:%s:%d " KNRM S NL, __FILE__, \ + __extension__ __FUNCTION__, __LINE__, ##__VA_ARGS__); \ + } while (0) +#else +#define success(S, ...) +#endif + +#ifdef ERROR +#define error(S, ...) \ + do { \ + fprintf(stderr, KRED "ERROR: %s:%s:%d " KNRM S NL, __FILE__, \ + __extension__ __FUNCTION__, __LINE__, ##__VA_ARGS__); \ + } while (0) +#else +#define error(S, ...) +#endif + +#endif /* DEBUG_H */ diff --git a/hw1/include/global.h b/hw1/include/global.h new file mode 100644 index 0000000..6cac919 --- /dev/null +++ b/hw1/include/global.h @@ -0,0 +1,87 @@ +/* + * DO NOT MODIFY THE CONTENTS OF THIS FILE. + * IT WILL BE REPLACED DURING GRADING + */ +#ifndef GLOBAL_H +#define GLOBAL_H + +#include + +/* + * Options info, set by validargs. + * If -h is specified, then the HELP_OPTION bit is set. + * If -v is specified, then the VALIDATE_OPTION bit is set. + * If -c is specified, then the CANONICALIZE_OPTION bit is set. + * If -p is specified, then the PRETTY_PRINT_OPTION bit is set. + * If PRETTY_PRINT_OPTION is set, then CANONICALIZE_OPTION must also be set. + * The least-significant byte contains the number of additional spaces + * to add at the beginning of each output line, for each increase + * in the indentation level of the value being output. + */ +int global_options; + +#define HELP_OPTION (0x80000000) +#define VALIDATE_OPTION (0x40000000) +#define CANONICALIZE_OPTION (0x20000000) +#define PRETTY_PRINT_OPTION (0x10000000) + +/* + * Variables that keep track of the current amount of input data that has been + * read. Variable "argo_lines_read" starts at zero and is incremented each time + * a newline character is read by function argo_read_char(). Variable + * "argo_chars_read" starts at zero, is reset to zero at the beginning of each + * line, and is incremented each time a character is read by function argo_read_char(). + * These variables are intended to be used for error messages and debugging. + * They can be assigned to if it is necessary to reset their values for some reason, + * such as if reading from multiple sources is done. + */ +int argo_lines_read; +int argo_chars_read; + +/* + * Variable that keeps track of the current indent level while pretty printing. + * See the assignment handout for a description of how the indent level is to + * be maintained and used. + */ +int indent_level; + +/* + * The following array contains statically allocated space for Argo values. + * You *must* use the elements of this array to store your values. + * The "argo_next_value" variable contains the index of the next unused slot + * in the array. As you use the elements of the array, you should increment + * this value. Pay attention to when all elements are used, so that you don't + * use a "value" beyond the end of the array and corrupt something else in memory! + */ +#define NUM_ARGO_VALUES 100000 +ARGO_VALUE argo_value_storage[NUM_ARGO_VALUES]; +int argo_next_value; + +/* + * The following array contains storage to hold digits of an integer during + * output conversion (the digits are naturally generated in the reverse order + * from which they will be output). You *must* use this array to hold the + * digits; you may not declare your own arrays! + */ + +#define ARGO_MAX_DIGITS 10 +ARGO_CHAR argo_digits[ARGO_MAX_DIGITS]; + +/* + * Prototypes for functions that you must implement. + * For detailed specifications of these functions, refer to the + * stubs in the file "argo.c", as well as to the assignment handout. + * Note that you will almost certainly want to implement additional + * functions besides those specified here. + */ +ARGO_VALUE *argo_read_value(FILE *); +int argo_read_string(ARGO_STRING *s, FILE *); +int argo_read_number(ARGO_NUMBER *n, FILE *); + +int argo_write_value(ARGO_VALUE *, FILE *); +int argo_write_string(ARGO_STRING *, FILE *); +int argo_write_number(ARGO_NUMBER *, FILE *); + +int validargs(int argc, char **argv); + +#endif diff --git a/hw1/lib/argo.a b/hw1/lib/argo.a new file mode 100644 index 0000000000000000000000000000000000000000..dfc9ca1d88b501c538ce6c38c68fec63dbce669a GIT binary patch literal 19100 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 +#include + +#include "argo.h" +#include "global.h" +#include "debug.h" + +/** + * @brief Read JSON input from a specified input stream, parse it, + * and return a data structure representing the corresponding value. + * @details This function reads a sequence of 8-bit bytes from + * a specified input stream and attempts to parse it as a JSON value, + * according to the JSON syntax standard. If the input can be + * successfully parsed, then a pointer to a data structure representing + * the corresponding value is returned. See the assignment handout for + * information on the JSON syntax standard and how parsing can be + * accomplished. As discussed in the assignment handout, the returned + * pointer must be to one of the elements of the argo_value_storage + * array that is defined in the const.h header file. + * In case of an error (these include failure of the input to conform + * to the JSON standard, premature EOF on the input stream, as well as + * other I/O errors), a one-line error message is output to standard error + * and a NULL pointer value is returned. + * + * @param f Input stream from which JSON is to be read. + * @return Zero if the operation is completely successful, + * nonzero if there is any error. + */ +ARGO_VALUE *argo_read_value(FILE *f) { + // TO BE IMPLEMENTED. + abort(); +} + +/** + * @brief Read JSON input from a specified input stream, attempt to + * parse it as a JSON string literal, and return a data structure + * representing the corresponding string. + * @details This function reads a sequence of 8-bit bytes from + * a specified input stream and attempts to parse it as a JSON string + * literal, according to the JSON syntax standard. If the input can be + * successfully parsed, then a pointer to a data structure representing + * the corresponding value is returned. + * In case of an error (these include failure of the input to conform + * to the JSON standard, premature EOF on the input stream, as well as + * other I/O errors), a one-line error message is output to standard error + * and a NULL pointer value is returned. + * + * @param f Input stream from which JSON is to be read. + * @return Zero if the operation is completely successful, + * nonzero if there is any error. + */ +int argo_read_string(ARGO_STRING *s, FILE *f) { + // TO BE IMPLEMENTED. + abort(); +} + +/** + * @brief Read JSON input from a specified input stream, attempt to + * parse it as a JSON number, and return a data structure representing + * the corresponding number. + * @details This function reads a sequence of 8-bit bytes from + * a specified input stream and attempts to parse it as a JSON numeric + * literal, according to the JSON syntax standard. If the input can be + * successfully parsed, then a pointer to a data structure representing + * the corresponding value is returned. The returned value must contain + * (1) a string consisting of the actual sequence of characters read from + * the input stream; (2) a floating point representation of the corresponding + * value; and (3) an integer representation of the corresponding value, + * in case the input literal did not contain any fraction or exponent parts. + * In case of an error (these include failure of the input to conform + * to the JSON standard, premature EOF on the input stream, as well as + * other I/O errors), a one-line error message is output to standard error + * and a NULL pointer value is returned. + * + * @param f Input stream from which JSON is to be read. + * @return Zero if the operation is completely successful, + * nonzero if there is any error. + */ +int argo_read_number(ARGO_NUMBER *n, FILE *f) { + // TO BE IMPLEMENTED. + abort(); +} + +/** + * @brief Write canonical JSON representing a specified value to + * a specified output stream. + * @details Write canonical JSON representing a specified value + * to specified output stream. See the assignment document for a + * detailed discussion of the data structure and what is meant by + * canonical JSON. + * + * @param v Data structure representing a value. + * @param f Output stream to which JSON is to be written. + * @return Zero if the operation is completely successful, + * nonzero if there is any error. + */ +int argo_write_value(ARGO_VALUE *v, FILE *f) { + // TO BE IMPLEMENTED. + abort(); +} + +/** + * @brief Write canonical JSON representing a specified string + * to a specified output stream. + * @details Write canonical JSON representing a specified string + * to specified output stream. See the assignment document for a + * detailed discussion of the data structure and what is meant by + * canonical JSON. The argument string may contain any sequence of + * Unicode code points and the output is a JSON string literal, + * represented using only 8-bit bytes. Therefore, any Unicode code + * with a value greater than or equal to U+00FF cannot appear directly + * in the output and must be represented by an escape sequence. + * There are other requirements on the use of escape sequences; + * see the assignment handout for details. + * + * @param v Data structure representing a string (a sequence of + * Unicode code points). + * @param f Output stream to which JSON is to be written. + * @return Zero if the operation is completely successful, + * nonzero if there is any error. + */ +int argo_write_string(ARGO_STRING *s, FILE *f) { + // TO BE IMPLEMENTED. + abort(); +} + +/** + * @brief Write canonical JSON representing a specified number + * to a specified output stream. + * @details Write canonical JSON representing a specified number + * to specified output stream. See the assignment document for a + * detailed discussion of the data structure and what is meant by + * canonical JSON. The argument number may contain representations + * of the number as any or all of: string conforming to the + * specification for a JSON number (but not necessarily canonical), + * integer value, or floating point value. This function should + * be able to work properly regardless of which subset of these + * representations is present. + * + * @param v Data structure representing a number. + * @param f Output stream to which JSON is to be written. + * @return Zero if the operation is completely successful, + * nonzero if there is any error. + */ +int argo_write_number(ARGO_NUMBER *n, FILE *f) { + // TO BE IMPLEMENTED. + abort(); +} diff --git a/hw1/src/const.c b/hw1/src/const.c new file mode 100644 index 0000000..72d31c7 --- /dev/null +++ b/hw1/src/const.c @@ -0,0 +1,47 @@ +/* + * DO NOT MODIFY THE CONTENTS OF THIS FILE. + * IT WILL BE REPLACED DURING GRADING + */ + +#include + +#include "argo.h" +#include "global.h" +#include "debug.h" + +/** + * @brief Append a specified character to a specified string. + * @details This function takes a pointer to an ARGO_STRING structure, + * which is assumed previously to have been initialized (an ARGO_STRING + * is initialized to empty by zeroing its fields) and an ARGO_CHAR + * value, representing an arbitrary Unicode code point, and it appends + * the character to the string, taking care of reallocating the string + * content into a new memory area if its length has grown to exceed + * the area already allocated for it. + * + * @return Zero if the operation completes without error, nonzero if + * there was a failure to allocate additional memory required to + * accomodate the string. + */ +int argo_append_char(ARGO_STRING *s, ARGO_CHAR c) { + if(s->capacity == 0) { + s->capacity = 10; + s->content = malloc(s->capacity * sizeof(ARGO_CHAR)); + if(!s->content) { + fprintf(stderr, "[%d] Failed to allocate space for string text", + argo_lines_read); + return 1; + } + } + if(s->length == s->capacity) { + s->capacity *= 2; + s->content = realloc(s->content, s->capacity * sizeof(ARGO_CHAR)); + if(!s->content) { + fprintf(stderr, "[%d] Failed to allocate space for string text", + argo_lines_read); + return 1; + } + } + s->content[s->length++] = c; + return 0; +} diff --git a/hw1/src/main.c b/hw1/src/main.c new file mode 100644 index 0000000..62631ad --- /dev/null +++ b/hw1/src/main.c @@ -0,0 +1,33 @@ +#include +#include + +#include "argo.h" +#include "global.h" +#include "debug.h" + +#ifdef _STRING_H +#error "Do not #include . You will get a ZERO." +#endif + +#ifdef _STRINGS_H +#error "Do not #include . You will get a ZERO." +#endif + +#ifdef _CTYPE_H +#error "Do not #include . You will get a ZERO." +#endif + +int main(int argc, char **argv) +{ + if(validargs(argc, argv)) + USAGE(*argv, EXIT_FAILURE); + if(global_options == HELP_OPTION) + USAGE(*argv, EXIT_SUCCESS); + // TO BE IMPLEMENTED + return EXIT_FAILURE; +} + +/* + * Just a reminder: All non-main functions should + * be in another file not named main.c + */ diff --git a/hw1/src/validargs.c b/hw1/src/validargs.c new file mode 100644 index 0000000..c218d35 --- /dev/null +++ b/hw1/src/validargs.c @@ -0,0 +1,26 @@ +#include + +#include "argo.h" +#include "global.h" +#include "debug.h" + +/** + * @brief Validates command line arguments passed to the program. + * @details This function will validate all the arguments passed to the + * program, returning 0 if validation succeeds and -1 if validation fails. + * Upon successful return, the various options that were specified will be + * encoded in the global variable 'global_options', where it will be + * accessible elsewhere in the program. For details of the required + * encoding, see the assignment handout. + * + * @param argc The number of arguments passed to the program from the CLI. + * @param argv The argument strings passed to the program from the CLI. + * @return 0 if validation succeeds and -1 if validation fails. + * @modifies global variable "global_options" to contain an encoded representation + * of the selected program options. + */ + +int validargs(int argc, char **argv) { + // TO BE IMPLEMENTED + abort(); +} diff --git a/hw1/tests/basecode_tests.c b/hw1/tests/basecode_tests.c new file mode 100644 index 0000000..d8cf83b --- /dev/null +++ b/hw1/tests/basecode_tests.c @@ -0,0 +1,95 @@ +#include +#include + +#include "argo.h" +#include "global.h" + +static char *progname = "bin/argo"; + +Test(basecode_suite, validargs_help_test) { + char *argv[] = {progname, "-h", NULL}; + int argc = (sizeof(argv) / sizeof(char *)) - 1; + int ret = validargs(argc, argv); + int exp_ret = 0; + int opt = global_options; + int flag = HELP_OPTION; + cr_assert_eq(ret, exp_ret, "Invalid return for validargs. Got: %d | Expected: %d", + ret, exp_ret); + cr_assert_eq(opt & flag, flag, "Correct bit (0x%x) not set for -h. Got: %x", + flag, opt); +} + +Test(basecode_suite, validargs_validate_test) { + char *argv[] = {progname, "-v", NULL}; + int argc = (sizeof(argv) / sizeof(char *)) - 1; + int ret = validargs(argc, argv); + int exp_ret = 0; + int opt = global_options; + int exp_opt = VALIDATE_OPTION; + cr_assert_eq(ret, exp_ret, "Invalid return for validargs. Got: %d | Expected: %d", + ret, exp_ret); + cr_assert_eq(opt, exp_opt, "Invalid options settings. Got: 0x%x | Expected: 0x%x", + opt, exp_opt); +} + +Test(basecode_suite, validargs_canonicalize_test) { + char *argv[] = {progname, "-c", NULL}; + int argc = (sizeof(argv) / sizeof(char *)) - 1; + int ret = validargs(argc, argv); + int exp_ret = 0; + int opt = global_options; + int exp_opt = CANONICALIZE_OPTION | 0x4; + cr_assert_eq(ret, exp_ret, "Invalid return for validargs. Got: %d | Expected: %d", + ret, exp_ret); + cr_assert_eq(opt, exp_opt, "Invalid options settings. Got: 0x%x | Expected: 0x%x", + opt, exp_opt); +} + +Test(basecode_suite, validargs_pretty_print_test) { + char *argv[] = {progname, "-c", "-p", "13", NULL}; + int argc = (sizeof(argv) / sizeof(char *)) - 1; + int ret = validargs(argc, argv); + int exp_ret = 0; + int opt = global_options; + int exp_opt = CANONICALIZE_OPTION | PRETTY_PRINT_OPTION | 13; + cr_assert_eq(ret, exp_ret, "Invalid return for validargs. Got: %d | Expected: %d", + ret, exp_ret); + cr_assert_eq(opt, exp_opt, "Invalid options settings. Got: 0x%x | Expected: 0x%x", + opt, exp_opt); +} + +Test(basecode_suite, validargs_error_test) { + char *argv[] = {progname, "-v", "-p", NULL}; + int argc = (sizeof(argv) / sizeof(char *)) - 1; + int exp_ret = -1; + int ret = validargs(argc, argv); + cr_assert_eq(ret, exp_ret, "Invalid return for validargs. Got: %d | Expected: %d", + ret, exp_ret); +} + +Test(basecode_suite, help_system_test) { + char *cmd = "bin/argo -h > /dev/null 2>&1"; + + // system is a syscall defined in stdlib.h + // it takes a shell command as a string and runs it + // we use WEXITSTATUS to get the return code from the run + // use 'man 3 system' to find out more + int return_code = WEXITSTATUS(system(cmd)); + + cr_assert_eq(return_code, EXIT_SUCCESS, + "Program exited with 0x%x instead of EXIT_SUCCESS", + return_code); +} + +Test(basecode_suite, argo_basic_test) { + char *cmd = "bin/argo -c < rsrc/strings.json > test_output/strings_-c.json"; + char *cmp = "cmp test_output/strings_-c.json tests/rsrc/strings_-c.json"; + + int return_code = WEXITSTATUS(system(cmd)); + cr_assert_eq(return_code, EXIT_SUCCESS, + "Program exited with 0x%x instead of EXIT_SUCCESS", + return_code); + return_code = WEXITSTATUS(system(cmp)); + cr_assert_eq(return_code, EXIT_SUCCESS, + "Program output did not match reference output."); +} diff --git a/hw1/tests/rsrc/strings_-c.json b/hw1/tests/rsrc/strings_-c.json new file mode 100644 index 0000000..1e650e4 --- /dev/null +++ b/hw1/tests/rsrc/strings_-c.json @@ -0,0 +1 @@ +["","a"," ","\\","\"","\\"," ","\b\f\n\t\r","\b\f\n\t\u000b"] \ No newline at end of file From 6dfda0e777b6d77f63fb2236caa7f98defe4d981 Mon Sep 17 00:00:00 2001 From: Gene Stark Date: Wed, 26 Jan 2022 17:54:28 -0500 Subject: [PATCH 02/10] Change test to be consistent with the behavior specified in the assignment handout. --- hw1/tests/basecode_tests.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw1/tests/basecode_tests.c b/hw1/tests/basecode_tests.c index d8cf83b..99deac6 100644 --- a/hw1/tests/basecode_tests.c +++ b/hw1/tests/basecode_tests.c @@ -38,7 +38,7 @@ Test(basecode_suite, validargs_canonicalize_test) { int ret = validargs(argc, argv); int exp_ret = 0; int opt = global_options; - int exp_opt = CANONICALIZE_OPTION | 0x4; + int exp_opt = CANONICALIZE_OPTION; cr_assert_eq(ret, exp_ret, "Invalid return for validargs. Got: %d | Expected: %d", ret, exp_ret); cr_assert_eq(opt, exp_opt, "Invalid options settings. Got: 0x%x | Expected: 0x%x", From 775d42de2b0fe37beed77d8886ec490abc9a02f5 Mon Sep 17 00:00:00 2001 From: Gene Stark Date: Thu, 27 Jan 2022 05:34:06 -0500 Subject: [PATCH 03/10] Add test_output directory, which got omitted. --- hw1/test_output/.git_keep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 hw1/test_output/.git_keep diff --git a/hw1/test_output/.git_keep b/hw1/test_output/.git_keep new file mode 100644 index 0000000..e69de29 From 8be8175f96499e75603059158b03003b111cb688 Mon Sep 17 00:00:00 2001 From: Gene Stark Date: Thu, 27 Jan 2022 15:16:22 -0500 Subject: [PATCH 04/10] Split the contents of lib/argo.a into a "read module" and a "write module", so they can be used separately. --- hw1/lib/argo.a | Bin 19100 -> 21174 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/hw1/lib/argo.a b/hw1/lib/argo.a index dfc9ca1d88b501c538ce6c38c68fec63dbce669a..526001fc3202db2048e2b416b3b5abbd8f43d16c 100644 GIT binary patch delta 2188 zcma)6ZActP7@nE)jJLg<*Ng0Z#LC4;{J7}edAfHRy_%xlok&Qa6bYiIQEO-*sZ~>h zQA6`1#nPU<6eNUDi&6<`lk}(*k%a#1pOlnBKOhZle-v7Z^;fYaN&C*utmqa?2X>yB z=lz&>ciw%jy-Qb?Xf}R48qtGdWE4V(n-KcNe?N6U5wiOOd#hiW`^L>-x^Lv=v%Tj> zPLB@uj`y7z8ze;2yg@?{F_U@<(X3IGd*;nyl(t~PXog0p%R9#xM}8=R=Q z2b;}KDAvkwcU1HGZTOu=@!{hU=Hr8d4PKSjDuW{=%Uy8@>w?yc8EE)C&J*ExaCSua z`cmWroGWYjdcm0eQNEswa-Rcre7;l1naX&OL6zm|QKw(vjCN z*5B0YlzNjE%9`dHQj zehD6cwVf^THtc|B(zleSQCMhl_jj3 zzy*X!0#^~P5m-f76Y!A0U$}crAW&7piYYWAG*LK-&`se2!X$;ORl^Vn`LHi}Pv%p< zhfuO6Pp+k6aS_3d)fMp{PT%&6h#zj~+}P+T;VHkkanTN>9{(-I5P|DWYG6iq{mcBO zVP>{dz7kNTaNG0^u8%m(S38=zlD!TzQV%CBtP$h zo*H#p?u?pvD}F5dQC{H|pD+0W8NgqfQ<~(R7QRdJQkAyyOi5ne@${BqQ5t-fM9s1Z ziY@$o$poHUpp(tNYkd}wd235-ks%#Juh=23uJRIUV15!NZ( zJ*v_eTztXHX7XUYRSno=y9ec)nTZeEp`=X>1m&m9Sj^w!J-4asbr-zU{xiGfGQ{}G zK5={&g%!nk!v!nJ1S5r8np~XnDWp(14P$92#y%;sK@?dOj6uY3F`h3p#Q0Mg kHZR0DE^h$CP>hx1&x)kCDLh4OCbEz>3^neON-fm*A3Yq9-v9sr delta 2253 zcmah~Z%ms-7{B-0I@aK<9TYm~+Okq$C2Ogr?F@D#2zDBwMa?iHX+e;XVIjy^vM`HT zG|Tn@;u9U2B=SKwVvJc*vKd9k2ck<{7EBh$4AFhU4{BzNQ9fYiJ$LtR?Iq1Fx#xNA z_xs)5bN}A=$|u_V``T^jiWT-s!Qbfh0Sv!UJ%K67e{IU=mrOc8FZmDiC!p^=NMKp= zk$gVGXgJo9gm_gTH(T|o=J=A)R-zH}ZqyONH;no3S+&5Ew|_Ms-?LHnHtkwdkp{IwS2lo#=PUW|w8{F(vI*Rk<) z|JLo$7<9iL>6wP-7;(D+MP2)^G5dti@4#i;Lc>bPB0Nu&g&T0x=QAO>0q10N3%>Hb z$@=;mQ(k0#mwnUh8DPP__zJi0i?U>emAGxs%_8(|PSan6`%{SjDIzxP#<7A=%M;Vn zT#zYr6v1s}*scGC3e1lk5UUvK8BP?zk5{5vtO)yjA*Xq}2tHs3%kwt+fpDwB-4iZZ z1!IiM2zN#}cQpscxyx?h<6%W#mAJm!wSA%$jGFE2PD2Jam)etSwE!Qg~m!l_G6hE?h$`- zWh`K2QNdr9H{mk{KPBrW?u9P-8zN2WY}EUCYlxs>#RA=|AU0|P^jz< U?_Bo@_6Io99ijE@Fx&0@AC*{H Date: Thu, 27 Jan 2022 15:26:07 -0500 Subject: [PATCH 05/10] Correct issue with @return specification for argo_read_value(). --- hw1/src/argo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw1/src/argo.c b/hw1/src/argo.c index 0809a8d..19ca524 100644 --- a/hw1/src/argo.c +++ b/hw1/src/argo.c @@ -23,8 +23,8 @@ * and a NULL pointer value is returned. * * @param f Input stream from which JSON is to be read. - * @return Zero if the operation is completely successful, - * nonzero if there is any error. + * @return A valid pointer if the operation is completely successful, + * NULL if there is any error. */ ARGO_VALUE *argo_read_value(FILE *f) { // TO BE IMPLEMENTED. From 9e6ea658444bbc6c99022d585754b46cc4fab406 Mon Sep 17 00:00:00 2001 From: Gene Stark Date: Sat, 29 Jan 2022 12:09:56 -0500 Subject: [PATCH 06/10] Fix matching of tokens "true", "false", "null". Fix character counting. --- hw1/lib/argo.a | Bin 21174 -> 21582 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/hw1/lib/argo.a b/hw1/lib/argo.a index 526001fc3202db2048e2b416b3b5abbd8f43d16c..2fb1235da038ad36dd5f44cd82a67cc50aaec751 100644 GIT binary patch delta 5289 zcmZ{o4Nz3q7036zT^4p-*e`s$Zb23z0!jo4;%Eul0F@vhkYcqBHGC#P1wSBStHoC0 zxI;UVIi?b8zY^1Cnl{oBQ>JAa(pb~UbW&}M>9nDeCK<6chBU;WV(B^W-51YXvuEbr zz56@o-2XZEy|?>zUwB%1?HQ%NZGOSmEtcp9q?B#@)pVR<&Ckn+z_J{5Fc->}r9z#0 zI(*;$y)(|Pd3`Y!wEd$>M4!B(kAxu2nrl1US2_ddiWhoB*n|k{hqF#UJZyC<>9E_H zY&$qRI}1mx4=6X`Lt7%aZK=w0u+;WBv2ZZNyUsBF=rF87_|Y{Esxot)WK6RZR)>ofZLw0M4-feRDJOVjN1dgY4;13 z-qFt5vc6K9x_>_jZ@c{dlD^WZvcA0&W&1D3tuKwdbZ=xDw%Zc}W&2NghEc+D=@1T> zG+q{YWugRb+V|Sl+`z6*xbATM==$tzq;v*%>>Hhs>($`p*j!iTr*O6le&SdHcg8u@ zrfaYwu0DG)`u@{su6FF2nZCEnU)EPQj=NeGIgdJ4j02DBYf2bW9lupuriaEHK1Hd4 zNoS2~_Ntl21m<2vfns=dPAGc}{kKG_K8>!IL{6fIMAW~24BK4S)$>!ZC4Nl(efkk!&|IoPD0pQ4$Z!LwdVtP z*;lJ92F+irUc937r~L(L%M}>&-(!373hLdFxC>7&3?wd6oKRU30AC>2{z$`?t`;YF z=SJ38zM9^=GQGJz{KbZcx3n~eJ3GQ#8#x^!a7OyhjBw`8hFv&o z%E-Rurngy67?`^X1w4Vg*p9|FOvKf-Y$Qcm4vy_w7LEg229BfpIH6_Y+#4vs(W7NR zM<51gcWY^IB#?l!p9aYPm%s`f9YM;zE0~YtL&2qSPP%N-;ECXJL}!C{*$BazU=l2t z7esXTyq8vdi$Y2hJO|X`c)Qx|ip5Jh3DNz;(F$lV{aban?%xA}P)h1C@}jMzYtoFe zE>$RwRvCdWhfA-vG*^=p7!J)>3gJye_YZv%x~M1~++%<8L5%lV6iYp=g;s4f zUI*|+kASq~C$z5i2U|LuEDbvz?AWxUrJ;F~ewK#LCf}=+UosLbcq%P(@R-K?oa`fs z&lq@iCJGNJ;3?O7)`&uE80N>rOsf>!lrj1GDEuA9si#gM`#}_br_uOgy$_l%6bT2! zj*u`-7YlyD3X^NK#*I`cnq1c=#_0+$>uqJ+!}xB-Nv04FvI8~hx_YK*jhRl*!62$_sH zy_*W==H1jX&Sf?-&ShE|Cz&lmW~VOG6A^B@yAts*FX*Ezjm!U-aW4Ne#<~1+jFbFf zA^$srLwbd`C&z&fG^$}P9%c;>2rln*E91O|t&H;;_AyR1jEEY(YjCQe@z*Sd_dCou z*Lsn0u63Gm(wY)luRHX!x`)<4lUw>W<6I`fIG6bz<0P|y2DGP~y37UU=H0xkfBjabeP}b&5U#THpaR9cE-8TOU5xX6>}8yk6RCN$#|*CT<8cuq@5^bH%g=GA+gL-6e_U|6 z=I=AkYktz;#v>Fj`Xo!BqANtve{k!2_KtAN`dPFFn#|jy@I!*j^*+uxulJb2Z?E?R zOQ3ptMZF^)z24U(_mpstOMFJ~fLCwhwm#|vr+P`ojNcq3{;af_YCUPfeOz*PiUyyN_#zSi3yCigd{E+ffVb_ii8mPkQUA)rC)IuBf37gP)VP?%TbTur~h(ZVsXp}IizWWz|_ zDkTVKs*BXVpq{a?CR6PXLUm1%V=!n$cf*mI<&Ml8<6RuQS+iWt3_)Rjky@Pud+;SU P7y4@#4*e_tT=M?`@a!&M delta 5286 zcmZ{o3vg8B702)WcC$$~VUz48`$!;ZESZFWCP>^!p$rnJL1Xh^e2fYtYQV=DG$i;c zz1G)|p<`E%PSIu{PE!Y_Fv7$tlQIaXg&9zSrc_6wQR@(jV-`h-VRieRd(TY{AMQ7^ zH~0R|>wnJu?oBrDZ`I%Un;yNlu<8paU($A9r_V!8}K$bH~OdaX7Zv2fH0vdIubGOmk{-!6`?xsQU@7N%6r7XR+Q0k2?$W zaafp=3p<^~({6BS+SB{8o^lFJ+l>LIJoeehR?|zQ6i-{1W_kTXx4rh*XCpUBuUo{A zakIpZl*OXgI(4~j5_7H72VKSbECAQb!V`yz)PQTaw(Hf z(2u}->HQ+-hrTYiSJ!`p?ud+9I+4oJ?5*>oW7RE>1fRTQWnI5}88${v1r5 zGA^F@9)g}B@z=9(-t(#ccHi-=>AKkbEyS~X^)YxQXNLYh9L{MIE6>0@?_v=;1Ap+= zh`|^f$+-@)eapqn7_9L%>HmQPz8V3eCU49Qi=0vD%3WmDJDU3tT$fko*E-reTeVd! zk+rQ_TW2JK0%b=7{wtm9S|XjW>&m4tkXHlG`+uz?z8V$=OQ9m*g8PG)!Oa1Wq^klm z?n)0`Y?nb)All_dSnc@;FGgIYO znJUrkP+d?|{5vy7(}phc8l3RzhKCA@^gZxrc|3vVBCf$l1%>)lI4{xszQELzdY)I) zHQAuK8XVTo=U~gyfW8Tju&D4Qe@px7H7na&Tkcwk^J>*P+g7)B+}U@gaH%eI9rj)C zH|i(_PCi$D;t6ZLKwM5k!|WaMgR3VA{}dhNvi(b}ORbuu*}R;1)Z({I1XPm2ZSDap zQHEr;plrt7j0YIcX1v@9kJtH)YBJ-G9A-Yv!g!f8jPo*MjPo)X)()6xBQ9&;3R>LI z)WVe%fSeC}6-&egMHuIT)-uioJ;S&|Gc;{J-7z48Drh$g;Dz@x&I`ZGI4^vJadXFD zU0GlIm<(#+I{BK#rB0$F34ek(ZY3^s1LIuipCrfn=Dp!cyIBA#?WGBABd!Yliuv=x zry1vkzn$cU#tSDV4dz2NNQE;~QKmHszDaK-u6EqaI4``KajULjJz<>7+*8JB{LiGcmgzy%F5j)FQ!(C5TeL9TS^Bp15z z!kLUuPD0*)A2aa6`HW-X?NqpwxLWvS#`%luKoUNH9G^c`>2V4`KB+X37-F0Y{U75f z^aKe#Ph1r`2b0Q$ZU!IGTxQ^f7c$NZ-@rH)&cuUUw-Q$iZ(y7@ul4-B#1e5qTNuYv zdvm?YI2W{oanxdO-hSe$po$Fh{degtxC&LsrQU-1jPt_vjAP*{n#AqI)xr_m-@gB2 z)_W+i+cwA~cxrdNmvKIccNyn`K42WRL`cwQ#BD)_U7#dWddY$znk0OA68=aM z{^HMbBeCn}4T;PtDCg2!<7J#rBE&eK#4N^f2;DS^xh5~V^q0yT6ktvQ>dONqI5T@5 z@33^d{9#yIUMjyx{H46e7~>gOY`#Zc$c4KKKlV*OL|mQyDdx{Lj55wOoU^!LCg(Fq zH@~}BMX~)j&A?CG-VJt>)r|Aaus#Vta1ob#+D`N(8L(U4!70Xh2QkKZ0}i~93-h4% zDpV|2Ht~xZz<0`JNASXB%E~KxMt(=%c;&l;t%M_a^ZT3jZhZKPvn!;!%aaP5cFgAGElkZBh(} zDWF^7M~U|+{6pfs3NInPRpFly-){2A-6 zW;>$r0`mXbr13xjhOxT9XnX}}4w#;`kDZe0fD!`BoR%>lT(X@S@nFhln?m5FEoMw%9+ z?+jRew?M_RYWLR5t*e*@4=fA2(?Zr|nSh)(eU83 F{{#K&Sl|Ev From 5be82bd40655b0c26746ee2ac49452f07ab03ec3 Mon Sep 17 00:00:00 2001 From: Gene Stark Date: Sun, 30 Jan 2022 10:38:06 -0500 Subject: [PATCH 07/10] Remove incorrect white space when printing an object member. --- hw1/lib/argo.a | Bin 21582 -> 21686 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/hw1/lib/argo.a b/hw1/lib/argo.a index 2fb1235da038ad36dd5f44cd82a67cc50aaec751..f525c6077d26dadb9f6604de888a34c824a38b3e 100644 GIT binary patch delta 785 zcmZ8fUr1A76u;+FH>XpV)~LsX$hzMdqf%+cR_uadocHsQZ`Ofcm&Ud-zd$T}K9?|lm zr^4gyz>=qfbvy9c(?f&Up|;XKgw#B}N43{Q8|d`5(gz&#W?9CHsNaqj-#uEvbKel1 zLbKmPyAbh@GL3N2r((n3MB}Im43UCl;GkdPHd)A+pAt{Lp9oF&u7{>xCw!Y z;Y*qH==qd%_QH7Pbk5&zCC7ZFXp|%oHgW&?+pu?)=;E6zS?W|V7nbYhORV@2jd&Se zBn@K&vhvYn$ebm$_$;xgS4(on6ycgO{8>_O``-FY|uiL*xh8)8c~9=Nt-mOMW`Sm7CkkUDk2D# zqEvE-_+EMvz4?cU1WFMhdhzFAD+uaAt9ViLkb0AX=>7#X;J~~y?>zH;@4zhGrj=V% zy(?J;WC{1Bo$Q^6Ptrb0p+^o;4^ncSo})b)rq9?F4bclsL@Vrs6FEh|me_Tw;8ARn z3h*fs1&~!vu_3}tOvVqTlcr#ePm%-2;)6RbavXQ*@od{NshjWVR4KWhy7IKHsP5|n z``@g;_BOs|uPr6-k$YanT$1-(X8T<>cD^=q;1I*w!3%9u#WS}jeRnhgerYz(@F(Zg~99l5PF?Cwh zIj9+Ryut5`*WYNN;|Aoc9oI$#achTRo3%~akE0`A|H6N0$*Bc1yGvh&^+n|Qe_QpL zLEUJmt->u-Ht8adxwHUj^oBTOGtL4g(%z(fz)Lhnz5bF(LoM{D4Z*A+7ERntZ5BU7 zHd`kP+&Qn0Apvhw0oGR^btdNREY0 Date: Mon, 31 Jan 2022 13:40:43 -0500 Subject: [PATCH 08/10] Correct escaping of characters with Unicode code points greater than \u00ff. --- hw1/lib/argo.a | Bin 21686 -> 21702 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/hw1/lib/argo.a b/hw1/lib/argo.a index f525c6077d26dadb9f6604de888a34c824a38b3e..01b5763285c67aecb2d2be5cc18b905b1d3bbd4b 100644 GIT binary patch delta 739 zcmZ{hT}V@57{}k|m}_lrXI-@8(aEfaiBuSqv(Gqz3n>SJ_xSIkI!rt?-3k46nzxR2c|MNV5-uJv-q|b{~ zex?X91<#dU(os|T=^9Q)LX>m`HZ%HK(E638agu zogzyYN7m9at25Q#RWmO>hzpEaT?HOlRa47%-BxseCpdZB3NP;Q(c)}nGZ_--MnzPg zI+}TgvC7NTHi`duH%oba4~2e@qv=oO#lX2Eq@p$`(V)rm5Hk|LwZU1FZ%wvijAx=I zb0)V83P~5nGk*D#%QRue_$I!R){$*vFC(=bb?;a6w%Xx-ob}7fA?g6GW~H_#ho}oJ zhOuzcV{X^YP44pUH#%z@g;CE+@}&c6#8%4)4!w~_9M&;lXN{{E|7jidAxU1a)zAUe zhoC0O)3)01YxI7Hrq%hYsk$Wp^;oUJhFhrRj}FDO-s-&tMn5k&N5aw$06obZmx0ix%o5y E0TGa{LjV8( delta 726 zcmX@Ml5yKg#tm!Cm@Et?uQM}XbeMeK%$YHKva-1fqtRp!^Zkt1Cv#Y6Fn*kDXmN$9 zglBSqmDpri%Xy6ZChxI~W=xtaVP(dsJ=x!CD`V+oR_ka+$;pY<5sU{W@3PinoI3fb zbuPa;Cj&$4ffBAAj0_A6FZWMQw2@|PoLp<8=6;O>BvUHm(e3)9o57}U+L)Yq*_dB%KIpE?!e}=6y|*}{6PQ$;Ebk)@^d^XG1(O@Vq|oGgpol)0^aPWS zKqQkf*W?BtG0B}=Ky!frWIQtv+kiMg@N_c2uej7dG}#b{B!dX|WC33>NnLITAEp^5 zZ8td|sChaL*;zawo0%kd!Bixel9c5`HA)9+lh)+_zT%SRXtL%|+2xb<{kBW`utB&o zP*IR`KrwS?@_#>Z$yrcY6*O7)$@>1{lJ!ton0+w4Cnv}IzXt}Je}K5;8(xUk29TjZ z08`UGxjx`I(>}h*GR9`W^f5oso{?el{XqN4_X0U49~TvvtYs`P`IoT-n4cD8!Pqc) zevmz5#pL@z_DqZUCm$3QoBYZ|gK@>=_+Wd+6O-oy$pw?|1IdKR@*(z&8k6IJB+%dx FbpStNtmFUy From 3fc2cc85f3a0134445f0d234f0c95db30ddd2475 Mon Sep 17 00:00:00 2001 From: Gene Stark Date: Wed, 2 Feb 2022 02:33:20 -0500 Subject: [PATCH 09/10] Correct regression where lib/argo_write_value was calling argo_write_string, instead of the internal version. --- hw1/lib/argo.a | Bin 21702 -> 21638 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/hw1/lib/argo.a b/hw1/lib/argo.a index 01b5763285c67aecb2d2be5cc18b905b1d3bbd4b..49751b1329fd95fb98c41ac804427e239b9d800d 100644 GIT binary patch delta 120 zcmX@MlCfwvUC8Ve>p|3qHpF$@@L0h$j}M=f{^9WtODI z7nc-e=A|>F6_l1FZ;tZfVPsm)GWmnA*yc3vDNKw)n}7QzGjm-KW&nc&%#&k`%_h$a qJis_%b9|6JBjbk2^Ml=)PB2csV`|1}0aZ42vb32w Date: Sat, 5 Feb 2022 12:17:44 -0500 Subject: [PATCH 10/10] Correct printing of exact 0.1. --- hw1/lib/argo.a | Bin 21638 -> 21638 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/hw1/lib/argo.a b/hw1/lib/argo.a index 49751b1329fd95fb98c41ac804427e239b9d800d..4359b8df0d140b539c935efe2bb6e1276865c5a9 100644 GIT binary patch delta 55 zcmZo$$=J4%al;!&#-hpZ9rc;DUrTM4cRJ1`$;!V!Z