Bring in basecode from development repo.
This commit is contained in:
		
						commit
						595cae98a1
					
				
							
								
								
									
										29
									
								
								.gitlab-ci.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								.gitlab-ci.yml
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -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
 | 
				
			||||||
							
								
								
									
										6
									
								
								hw1/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								hw1/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,6 @@
 | 
				
			||||||
 | 
					bin/
 | 
				
			||||||
 | 
					build/
 | 
				
			||||||
 | 
					test_output/
 | 
				
			||||||
 | 
					*~
 | 
				
			||||||
 | 
					*.out
 | 
				
			||||||
 | 
					*.bak
 | 
				
			||||||
							
								
								
									
										61
									
								
								hw1/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								hw1/Makefile
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -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
 | 
				
			||||||
							
								
								
									
										50
									
								
								hw1/hw1.sublime-project
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								hw1/hw1.sublime-project
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -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}",
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										242
									
								
								hw1/include/argo.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										242
									
								
								hw1/include/argo.h
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -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
 | 
				
			||||||
							
								
								
									
										88
									
								
								hw1/include/debug.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								hw1/include/debug.h
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,88 @@
 | 
				
			||||||
 | 
					#ifndef DEBUG_H
 | 
				
			||||||
 | 
					#define DEBUG_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#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 */
 | 
				
			||||||
							
								
								
									
										87
									
								
								hw1/include/global.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								hw1/include/global.h
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -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 <stdio.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								hw1/lib/argo.a
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								hw1/lib/argo.a
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										17
									
								
								hw1/rsrc/numbers.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								hw1/rsrc/numbers.json
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,17 @@
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    "0": 0,
 | 
				
			||||||
 | 
					    "2147483648": 2147483648,
 | 
				
			||||||
 | 
					    "-2147483649": 2147483649,
 | 
				
			||||||
 | 
					    "0.0": 0.0,
 | 
				
			||||||
 | 
					    "1": 1,
 | 
				
			||||||
 | 
					    "789": 789,
 | 
				
			||||||
 | 
					    "1.0": 1.0,
 | 
				
			||||||
 | 
					    "-1.0": -1.0,
 | 
				
			||||||
 | 
					    "1e3": 1e3,
 | 
				
			||||||
 | 
					    "1E3": 1E3,
 | 
				
			||||||
 | 
					    "1e-3": 1e-3,
 | 
				
			||||||
 | 
					    "1.234": 1.234,
 | 
				
			||||||
 | 
					    "-1.234": -1.234,
 | 
				
			||||||
 | 
					    "1.234e3": 1.234e3,
 | 
				
			||||||
 | 
					    "1.234e-3": 1.234e-3
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										2419
									
								
								hw1/rsrc/package-lock.json
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										2419
									
								
								hw1/rsrc/package-lock.json
									
									
									
										generated
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										11
									
								
								hw1/rsrc/strings.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								hw1/rsrc/strings.json
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,11 @@
 | 
				
			||||||
 | 
					[
 | 
				
			||||||
 | 
					    "",
 | 
				
			||||||
 | 
					    "a",
 | 
				
			||||||
 | 
					    " ",
 | 
				
			||||||
 | 
					    "\\",
 | 
				
			||||||
 | 
					    "\"",
 | 
				
			||||||
 | 
					    "\u005c",
 | 
				
			||||||
 | 
					    "\u0020",
 | 
				
			||||||
 | 
					    "\b\f\n\t\r",
 | 
				
			||||||
 | 
					    "\u0008\u000c\u000a\u0009\u000b"
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
							
								
								
									
										148
									
								
								hw1/src/argo.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										148
									
								
								hw1/src/argo.c
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,148 @@
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#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();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										47
									
								
								hw1/src/const.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								hw1/src/const.c
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,47 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * DO NOT MODIFY THE CONTENTS OF THIS FILE.
 | 
				
			||||||
 | 
					 * IT WILL BE REPLACED DURING GRADING
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#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;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										33
									
								
								hw1/src/main.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								hw1/src/main.c
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,33 @@
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "argo.h"
 | 
				
			||||||
 | 
					#include "global.h"
 | 
				
			||||||
 | 
					#include "debug.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef _STRING_H
 | 
				
			||||||
 | 
					#error "Do not #include <string.h>. You will get a ZERO."
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef _STRINGS_H
 | 
				
			||||||
 | 
					#error "Do not #include <strings.h>. You will get a ZERO."
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef _CTYPE_H
 | 
				
			||||||
 | 
					#error "Do not #include <ctype.h>. 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
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
							
								
								
									
										26
									
								
								hw1/src/validargs.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								hw1/src/validargs.c
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,26 @@
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#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();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										95
									
								
								hw1/tests/basecode_tests.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								hw1/tests/basecode_tests.c
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,95 @@
 | 
				
			||||||
 | 
					#include <criterion/criterion.h>
 | 
				
			||||||
 | 
					#include <criterion/logging.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#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.");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										1
									
								
								hw1/tests/rsrc/strings_-c.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								hw1/tests/rsrc/strings_-c.json
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1 @@
 | 
				
			||||||
 | 
					["","a"," ","\\","\"","\\"," ","\b\f\n\t\r","\b\f\n\t\u000b"]
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user