diff options
author | LAN-TW <lantw44@gmail.com> | 2013-11-05 02:06:48 +0800 |
---|---|---|
committer | LAN-TW <lantw44@gmail.com> | 2013-11-05 02:08:09 +0800 |
commit | d0c1a2cc702018a906468218bfeef97919ad7ed4 (patch) | |
tree | d4754d5d38907fc161387a0d17e0733e4d48977c | |
parent | f92962990ee4d98923f4a457c21e0c03d9c22722 (diff) | |
download | sp2013-d0c1a2cc702018a906468218bfeef97919ad7ed4.tar sp2013-d0c1a2cc702018a906468218bfeef97919ad7ed4.tar.gz sp2013-d0c1a2cc702018a906468218bfeef97919ad7ed4.tar.bz2 sp2013-d0c1a2cc702018a906468218bfeef97919ad7ed4.tar.lz sp2013-d0c1a2cc702018a906468218bfeef97919ad7ed4.tar.xz sp2013-d0c1a2cc702018a906468218bfeef97919ad7ed4.tar.zst sp2013-d0c1a2cc702018a906468218bfeef97919ad7ed4.zip |
HW2: 準備好程式基本架構,包含參數檢查以及記錄功能
-rw-r--r-- | hw2/Makefile.am | 2 | ||||
-rw-r--r-- | hw2/big_judge.c | 43 | ||||
-rw-r--r-- | hw2/logger.c | 113 | ||||
-rw-r--r-- | hw2/logger.h | 21 | ||||
-rw-r--r-- | hw2/xwrap.c | 131 | ||||
-rw-r--r-- | hw2/xwrap.h | 23 |
6 files changed, 332 insertions, 1 deletions
diff --git a/hw2/Makefile.am b/hw2/Makefile.am index 335e578..d4fd275 100644 --- a/hw2/Makefile.am +++ b/hw2/Makefile.am @@ -1,7 +1,7 @@ EXTRA_DIST = README.txt bin_PROGRAMS = big_judge judge player noinst_LIBRARIES = libsphw2.a -libsphw2_a_SOURCES = xwrap.c xwrap.h +libsphw2_a_SOURCES = xwrap.c xwrap.h logger.c logger.h big_judge_SOURCES = big_judge.c big_judge_LDADD = $(top_builddir)/libsphw2.a judge_SOURCES = judge.c diff --git a/hw2/big_judge.c b/hw2/big_judge.c new file mode 100644 index 0000000..1d39e81 --- /dev/null +++ b/hw2/big_judge.c @@ -0,0 +1,43 @@ +/* b01902062 藍挺瑋 */ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "logger.h" +#include "xwrap.h" + +int main (int argc, char* argv[]) { + if (argc < 2) { + fprintf (stderr, "Usage: %s judge_num player_num\n", argv[0]); + return 1; + } + + long judge_num, player_num; + + if (xatol (argv[1], &judge_num) < 0) { + fprintf (stderr, "%s: `%s\' is not a number\n", argv[0], argv[1]); + return 2; + } + if (judge_num < 0) { + fprintf (stderr, "%s: judge_num must be a positive number\n", argv[0]); + return 3; + } + + if (xatol (argv[2], &player_num) < 0) { + fprintf (stderr, "%s: `%s\' is not a number\n", argv[0], argv[2]); + return 2; + } + if (judge_num < 4) { + fprintf (stderr, "%s: player_num must be greater than 4\n", argv[0]); + return 3; + } + + Comp135 comp; + comp135_init (&comp, argv[0], false); + + + + comp135_destroy (&comp); + + return 0; +} diff --git a/hw2/logger.c b/hw2/logger.c new file mode 100644 index 0000000..bffe50b --- /dev/null +++ b/hw2/logger.c @@ -0,0 +1,113 @@ +/* b01902062 藍挺瑋 */ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "logger.h" +#include "xwrap.h" + +#include <fcntl.h> +#include <locale.h> +#include <stdarg.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <unistd.h> + +void comp135_init (Comp135* comp, const char* static_name, bool no_init) { + if (!no_init) { + setlocale (LC_ALL, ""); + tzset (); + } + + comp->name = (char*)static_name; + comp->pid = getpid (); + comp->debug = false; + + const char* comp135_debug = getenv ("COMP135_DEBUG"); + const char* comp135_logfile = getenv ("COMP135_LOGFILE"); + if (comp135_debug == NULL || + strcmp (comp135_debug, "0") == 0 || + strcmp (comp135_debug, "n") == 0 || + strcmp (comp135_debug, "no") == 0 || + strcmp (comp135_debug, "f") == 0 || + strcmp (comp135_debug, "false") == 0) { + + return; + } + + comp->debug = true; + comp->log = NULL; + comp->log_fd = STDERR_FILENO; + comp->log_file = stderr; + + if (comp135_logfile == NULL || *comp135_logfile == '\0') { + return; + } + + int fd = open ( + comp135_logfile, O_WRONLY | O_CREAT | O_APPEND, S_IWUSR | S_IRUSR); + if (fd < 0) { + return; + } + + FILE* fp = fdopen (fd, "wb"); + if (fp == NULL) { + close (fd); + return; + } + + setvbuf (fp, NULL, _IONBF, 0); + comp->log = xstrdup (comp135_logfile); + comp->log_fd = fd; + comp->log_file = fp; +} + +void comp135_destroy (Comp135* comp) { + if (!comp->debug) { + return; + } + + if (comp->log != NULL) { + free (comp->log); + fclose (comp->log_file); + } +} + +void comp135_log (Comp135* comp, const char* format, ...) { + if (!comp->debug) { + return; + } + + time_t t; + struct tm tmd; + + time (&t); + localtime_r (&t, &tmd); + + struct flock lock_info = { + .l_type = F_WRLCK, + .l_whence = SEEK_END, + .l_start = 0, + .l_len = 0 + }; + fcntl (comp->log_fd, F_SETLKW, &lock_info); + + fprintf (comp->log_file, + "%04d-%02d-%02d %02d:%02d:%02d %s [%d]: ", + tmd.tm_year + 1900, tmd.tm_mon + 1, tmd.tm_mday, + tmd.tm_hour, tmd.tm_min, tmd.tm_sec, + comp->name, comp->pid); + + va_list ap; + va_start (ap, format); + vfprintf (comp->log_file, format, ap); + va_end (ap); + + putc ('\n', comp->log_file); + + lock_info.l_type = F_UNLCK; + fcntl (comp->log_fd, F_SETLK, &lock_info); +} diff --git a/hw2/logger.h b/hw2/logger.h new file mode 100644 index 0000000..2e58930 --- /dev/null +++ b/hw2/logger.h @@ -0,0 +1,21 @@ +#ifndef COMP135_LOGGER_H +#define COMP135_LOGGER_H + +#include <stdbool.h> +#include <stdio.h> +#include <sys/types.h> + +typedef struct { + char* name; /* Constant: DO NOT free it! */ + pid_t pid; + char* log; + int log_fd; + FILE* log_file; + int debug : 1; +} Comp135; + +void comp135_init (Comp135* comp, const char* static_name, bool no_init); +void comp135_destroy (Comp135* comp); +void comp135_log (Comp135* comp, const char* format, ...); + +#endif /* COMP135_LOGGER_H */ diff --git a/hw2/xwrap.c b/hw2/xwrap.c new file mode 100644 index 0000000..3c3127d --- /dev/null +++ b/hw2/xwrap.c @@ -0,0 +1,131 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "xwrap.h" + +#include <errno.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <unistd.h> + +#define RETRY_SEC 0 +#define RETRY_NSEC 250000000 + +static const char fail_msg[] = "Fail to allocate memory. Retry ...\n"; +static const size_t fail_len = STATIC_STRLEN (fail_msg); + +int xatol (const char* str, long* result) { + int errno_save, rval; + long lres; + char* endptr; + + errno_save = errno; + errno = 0, rval = 0; + + lres = strtol (str, &endptr, 10); + if (str == endptr || errno != 0) { + rval = -1; + } else { + *result = lres; + } + + errno = errno_save; + + return rval; +} + +void* xmalloc (size_t size) { + void* memptr; + + while ((memptr = malloc (size)) == NULL) { + nanosleep (&(struct timespec) { RETRY_SEC, RETRY_NSEC }, NULL); + write (STDERR_FILENO, fail_msg, fail_len); + } + + return memptr; +} + +void* xrealloc (void* ptr, size_t size) { + void* newptr; + + while ((newptr = realloc (ptr, size)) == NULL) { + nanosleep (&(struct timespec) { RETRY_SEC, RETRY_NSEC }, NULL); + write (STDERR_FILENO, fail_msg, fail_len); + } + + return newptr; +} + +char* xstrcat (const char* str, ...) { + va_list ap; + char* strp; + char* strnow; + char* newstr; + int len = strlen (str); + + va_start (ap, str); + while ((strp = va_arg (ap, char*)) != NULL) { + len += strlen (strp); + } + va_end (ap); + + newstr = xmalloc (len + 1); + + va_start (ap, str); + strnow = stpcpy (newstr, str); + while ((strp = va_arg (ap, char*)) != NULL) { + strnow = stpcpy (strnow, strp); + } + newstr[len] = '\0'; + va_end (ap); + + return newstr; +} + +char* xstrdup (const char* str) { + char* newstr; + + while ((newstr = strdup (str)) == NULL) { + nanosleep (&(struct timespec) { RETRY_SEC, RETRY_NSEC }, NULL); + write (STDERR_FILENO, fail_msg, fail_len); + } + + return newstr; +} + +char* xsprintf (const char* format, ...) { + va_list ap; + char* newstr; + int len; + + va_start (ap, format); + len = vsnprintf (NULL, 0, format, ap) + 1; + va_end (ap); + + newstr = xmalloc (len); + + va_start (ap, format); + vsnprintf (newstr, len, format, ap); + va_end (ap); + + return newstr; +} + +char* xgetcwd (void) { + char *cwd, *result; + size_t size = pathconf (".", _PC_PATH_MAX); + + size = size > 0 ? size : 256; + cwd = xmalloc (sizeof (char) * size); + + while ((result = getcwd (cwd, size)) == NULL && errno == ERANGE) { + size *= 2; + cwd = xrealloc (cwd, size); + } + + return cwd; +} diff --git a/hw2/xwrap.h b/hw2/xwrap.h new file mode 100644 index 0000000..ca7fee4 --- /dev/null +++ b/hw2/xwrap.h @@ -0,0 +1,23 @@ +#ifndef X_GENERAL_WRAPPER +#define X_GENERAL_WRAPPER + +#include <stdlib.h> + +#define STATIC_STRLEN(x) (sizeof(x)/sizeof(char) - 1) + +int xatol (const char* str, long* result); +void* xmalloc (size_t size); +void* xrealloc (void* ptr, size_t size); +char* xstrcat (const char* str, ...); +char* xstrdup (const char* str); +char* xsprintf (const char* format, ...); +char* xgetcwd (void); + +static inline int xmax (int a, int b) { + return a > b ? a : b; +} +static inline int xmin (int a, int b) { + return a < b ? a : b; +} + +#endif /* X_GENERAL_WRAPPER */ |