summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLAN-TW <lantw44@gmail.com>2013-11-05 02:06:48 +0800
committerLAN-TW <lantw44@gmail.com>2013-11-05 02:08:09 +0800
commitd0c1a2cc702018a906468218bfeef97919ad7ed4 (patch)
treed4754d5d38907fc161387a0d17e0733e4d48977c
parentf92962990ee4d98923f4a457c21e0c03d9c22722 (diff)
downloadsp2013-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.am2
-rw-r--r--hw2/big_judge.c43
-rw-r--r--hw2/logger.c113
-rw-r--r--hw2/logger.h21
-rw-r--r--hw2/xwrap.c131
-rw-r--r--hw2/xwrap.h23
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 */