Lab5 Ex2

You cannot submit for this problem because the homework's deadline is due.

We provide lab5_dlist.h and main.c in JOJ. You only need to submit the files that implement all the functions appeared in lab5_dlist.h.

For input files, the length of a line is no longer than 2048.

main.c tests your code with the following procedure:

int run(char *fileName, char *order) {
  FILE *fp = fopen(fileName, "r");
  if (fp == NULL) exit(EXIT_FAILURE);
  dlistValueType type = getValueType(fileName);
  dlistSortMethod method = getSortMethod(order);
  if (type == DLIST_UNKOWN || method == Dsort_list_UNKOWN) exit(EXIT_FAILURE);
  dlist listDst = createDlist(type), list = createDlist(type);
  char line[2048], key[2048];
  dlistValue value;
  while (fgets(line, sizeof(line), fp)) {
    getKeyFromLine(&key, line);
    getValueFromLine(&value, line, type);
    dlistAppend(list, key, value);
  }
  fclose(fp);
  dlistSort(list, listDst, method);
  dlistSort(list, listDst, method);
  dlistPrint(listDst);
  dlistFree(list);
  dlistFree(listDst);
  return 0;
}

int main(int argc, char *argv[]) {
  if (argc < 3) return -1;
  run(argv[1], argv[2]);
  return 0;
}

stdout of your program will be redirected to the corresponding file used in h3ex2 in JOJ.

Makefile used:

CC = clang
CFLAGS = -std=gnu11 -O2 -Wall -Wextra -Werror -pedantic -Wno-unused-result -Wconversion -Wvla
L5_SRC = *.c
L5 = l5
L5MC = l5_memory_check
L5MC_FLAGS = -fsanitize=address -fno-omit-frame-pointer -fsanitize=undefined -fsanitize=integer
.PHONY: clean

all: $(L5) $(L5MC)
    @echo l5 successfully constructed

$(L5): $(L5_SRC)
    $(CC) $(CFLAGS) -o $(L5) $(L5_SRC)

$(L5MC) : $(L5_SRC)
    $(CC) $(CFLAGS) $(L5MC_FLAGS) -o $(L5MC) $(L5_SRC)

.c.o:
    $(CC) $(CFLAGS) -c $< -o $@

clean:
    $(RM) *.o *.a *~ $(L5) $(L5MC)

Wrapper to run your program on JOJ:

#!/usr/bin/env python3

# Example usage: ./l5.py int rand inc

import sys
import subprocess
from enum import Enum
import tempfile


class SortingType(str, Enum):
    rand = "rand"
    inc = "inc"
    dec = "dec"


class DataType(str, Enum):
    char = "char*"
    int = "int"
    double = "double"


def generate_text_filename(sorting_type: SortingType, data_type: DataType) -> str:
    return f"{sorting_type.value}_{data_type.value}.txt"


def main(data_type: DataType, orig_sort: SortingType, dest_sort: SortingType) -> int:
    fn = {DataType.char: str, DataType.int: int, DataType.double: float}
    input_fn = generate_text_filename(orig_sort, data_type)
    input_lines = open(input_fn).read().rstrip().split("\n")
    input_dict = {}
    for line in input_lines:
        k, v = line.split("=")
        input_dict[k] = fn[data_type](v)
    output_fn = generate_text_filename(dest_sort, data_type)
    try:
        print(
            "$",
            " ".join(["./l5", input_fn, dest_sort.value]),
            file=sys.stderr,
            flush=True,
        )
        tf = tempfile.SpooledTemporaryFile()
        subprocess.run(
            ["./l5", input_fn, dest_sort.value],
            check=True,
            stdout=tf,
            stderr=sys.stderr,
        )
        tf.seek(0)
        open(output_fn, "wb").write(tf.read())
    except subprocess.CalledProcessError as e:
        print(f"Program exit with non zero value {e.returncode}!")
        return e.returncode
    except FileNotFoundError:
        print(f"Binary file ./l5 not found!")
        return -1
    try:
        output_lines = open(output_fn).read().rstrip().split("\n")
    except FileNotFoundError:
        print(f"Output file {output_fn} not found!")
        return -1
    if len(input_lines) != len(output_lines):
        print(f"Line number {len(input_lines)} vs {len(output_lines)} not match!")
        return 0
    output_dict = {}
    for line in output_lines:
        try:
            k, v = line.split("=")
            output_dict[k] = fn[data_type](v)
        except:
            print(f"Line '{line}' wrong format")
            return 0
    if dest_sort == SortingType.rand:
        for k, v in input_dict.items():
            if output_dict.get(k) != v:
                print(f"{k}={v} not match!")
                return 0
        shuffled = False
        for k1, k2 in zip(input_dict, output_dict):
            if k1 != k2:
                shuffled = True
                break
        if not shuffled:
            print(f"File content not change!")
            return 0
    else:
        input_dict = {
            k: v
            for k, v in sorted(
                input_dict.items(),
                key=lambda item: item[1],
                reverse=dest_sort == SortingType.dec,
            )
        }
        for k1, k2 in zip(input_dict, output_dict):
            if k1 != k2 or input_dict[k1] != output_dict.get(k2):
                print(f"{k1}={input_dict[k1]} not match!")
                return 0
    print("Correct!")
    return 0

if __name__ == "__main__":
    if len(sys.argv) == 1:
        print("Free 10 points to make the total score 100.", file=sys.stderr)
        print("Correct!")
        exit(0)
    data_type = DataType(sys.argv[1])
    orig_sort = SortingType(sys.argv[2])
    dest_sort = SortingType(sys.argv[3])
    exit_code = main(data_type, orig_sort, dest_sort)
    exit(exit_code)

Lab5 Ex2

Not Claimed
Status
Finished
Problems
2
Open Since
2022-10-21 00:00
DDL
2022-11-01 23:59
Extension
24.0 hour(s)