]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/C/BrotliCompress/tools/brotli.c
BaseTools: Make brotli a submodule
[mirror_edk2.git] / BaseTools / Source / C / BrotliCompress / tools / brotli.c
diff --git a/BaseTools/Source/C/BrotliCompress/tools/brotli.c b/BaseTools/Source/C/BrotliCompress/tools/brotli.c
deleted file mode 100644 (file)
index b0246e1..0000000
+++ /dev/null
@@ -1,1143 +0,0 @@
-/* Copyright 2014 Google Inc. All Rights Reserved.\r
-\r
-   Distributed under MIT license.\r
-   See file LICENSE for detail or copy at https://opensource.org/licenses/MIT\r
-*/\r
-\r
-/* Command line interface for Brotli library. */\r
-\r
-#include <errno.h>\r
-#include <fcntl.h>\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <string.h>\r
-#include <sys/stat.h>\r
-#include <sys/types.h>\r
-#include <time.h>\r
-\r
-#include "../common/constants.h"\r
-#include "../common/version.h"\r
-#include <brotli/decode.h>\r
-#include <brotli/encode.h>\r
-\r
-#if !defined(_WIN32)\r
-#include <unistd.h>\r
-#include <utime.h>\r
-#define MAKE_BINARY(FILENO) (FILENO)\r
-#else\r
-#include <io.h>\r
-#include <share.h>\r
-#include <sys/utime.h>\r
-\r
-#define MAKE_BINARY(FILENO) (_setmode((FILENO), _O_BINARY), (FILENO))\r
-\r
-#if !defined(__MINGW32__)\r
-#define STDIN_FILENO _fileno(stdin)\r
-#define STDOUT_FILENO _fileno(stdout)\r
-#define S_IRUSR S_IREAD\r
-#define S_IWUSR S_IWRITE\r
-#endif\r
-\r
-#define fdopen _fdopen\r
-#define isatty _isatty\r
-#define unlink _unlink\r
-#define utimbuf _utimbuf\r
-#define utime _utime\r
-\r
-#define fopen ms_fopen\r
-#define open ms_open\r
-\r
-#define chmod(F, P) (0)\r
-#define chown(F, O, G) (0)\r
-\r
-#if defined(_MSC_VER) && (_MSC_VER >= 1400)\r
-#define fseek _fseeki64\r
-#define ftell _ftelli64\r
-#endif\r
-\r
-static FILE* ms_fopen(const char* filename, const char* mode) {\r
-  FILE* result = 0;\r
-  fopen_s(&result, filename, mode);\r
-  return result;\r
-}\r
-\r
-static int ms_open(const char* filename, int oflag, int pmode) {\r
-  int result = -1;\r
-  _sopen_s(&result, filename, oflag | O_BINARY, _SH_DENYNO, pmode);\r
-  return result;\r
-}\r
-#endif  /* WIN32 */\r
-\r
-typedef enum {\r
-  COMMAND_COMPRESS,\r
-  COMMAND_DECOMPRESS,\r
-  COMMAND_HELP,\r
-  COMMAND_INVALID,\r
-  COMMAND_TEST_INTEGRITY,\r
-  COMMAND_NOOP,\r
-  COMMAND_VERSION\r
-} Command;\r
-\r
-#define DEFAULT_LGWIN 24\r
-#define DEFAULT_SUFFIX ".br"\r
-#define MAX_OPTIONS 20\r
-#define DECODE_HEADER_SIZE 0x10\r
-#define GAP_MEM_BLOCK 0x1000\r
-\r
-typedef struct {\r
-  /* Parameters */\r
-  int gmem;\r
-  int quality;\r
-  int lgwin;\r
-  BROTLI_BOOL force_overwrite;\r
-  BROTLI_BOOL junk_source;\r
-  BROTLI_BOOL copy_stat;\r
-  BROTLI_BOOL verbose;\r
-  BROTLI_BOOL write_to_stdout;\r
-  BROTLI_BOOL test_integrity;\r
-  BROTLI_BOOL decompress;\r
-  BROTLI_BOOL large_window;\r
-  const char* output_path;\r
-  const char* suffix;\r
-  int not_input_indices[MAX_OPTIONS];\r
-  size_t longest_path_len;\r
-  size_t input_count;\r
-\r
-  /* Inner state */\r
-  int argc;\r
-  char** argv;\r
-  char* modified_path;  /* Storage for path with appended / cut suffix */\r
-  int iterator;\r
-  int ignore;\r
-  BROTLI_BOOL iterator_error;\r
-  uint8_t* buffer;\r
-  uint8_t* input;\r
-  uint8_t* output;\r
-  const char* current_input_path;\r
-  const char* current_output_path;\r
-  int64_t input_file_length;  /* -1, if impossible to calculate */\r
-  FILE* fin;\r
-  FILE* fout;\r
-\r
-  /* I/O buffers */\r
-  size_t available_in;\r
-  const uint8_t* next_in;\r
-  size_t available_out;\r
-  uint8_t* next_out;\r
-} Context;\r
-\r
-/* Parse up to 5 decimal digits. */\r
-static BROTLI_BOOL ParseInt(const char* s, int low, int high, int* result) {\r
-  int value = 0;\r
-  int i;\r
-  for (i = 0; i < 5; ++i) {\r
-    char c = s[i];\r
-    if (c == 0) break;\r
-    if (s[i] < '0' || s[i] > '9') return BROTLI_FALSE;\r
-    value = (10 * value) + (c - '0');\r
-  }\r
-  if (i == 0) return BROTLI_FALSE;\r
-  if (i > 1 && s[0] == '0') return BROTLI_FALSE;\r
-  if (s[i] != 0) return BROTLI_FALSE;\r
-  if (value < low || value > high) return BROTLI_FALSE;\r
-  *result = value;\r
-  return BROTLI_TRUE;\r
-}\r
-\r
-/* Returns "base file name" or its tail, if it contains '/' or '\'. */\r
-static const char* FileName(const char* path) {\r
-  const char* separator_position = strrchr(path, '/');\r
-  if (separator_position) path = separator_position + 1;\r
-  separator_position = strrchr(path, '\\');\r
-  if (separator_position) path = separator_position + 1;\r
-  return path;\r
-}\r
-\r
-/* Detect if the program name is a special alias that infers a command type. */\r
-static Command ParseAlias(const char* name) {\r
-  /* TODO: cast name to lower case? */\r
-  const char* unbrotli = "unbrotli";\r
-  size_t unbrotli_len = strlen(unbrotli);\r
-  name = FileName(name);\r
-  /* Partial comparison. On Windows there could be ".exe" suffix. */\r
-  if (strncmp(name, unbrotli, unbrotli_len) == 0) {\r
-    char terminator = name[unbrotli_len];\r
-    if (terminator == 0 || terminator == '.') return COMMAND_DECOMPRESS;\r
-  }\r
-  return COMMAND_COMPRESS;\r
-}\r
-\r
-static Command ParseParams(Context* params) {\r
-  int argc = params->argc;\r
-  char** argv = params->argv;\r
-  int i;\r
-  int next_option_index = 0;\r
-  size_t input_count = 0;\r
-  size_t longest_path_len = 1;\r
-  BROTLI_BOOL command_set = BROTLI_FALSE;\r
-  BROTLI_BOOL gmem_set = BROTLI_FALSE;\r
-  BROTLI_BOOL quality_set = BROTLI_FALSE;\r
-  BROTLI_BOOL output_set = BROTLI_FALSE;\r
-  BROTLI_BOOL keep_set = BROTLI_FALSE;\r
-  BROTLI_BOOL lgwin_set = BROTLI_FALSE;\r
-  BROTLI_BOOL suffix_set = BROTLI_FALSE;\r
-  BROTLI_BOOL after_dash_dash = BROTLI_FALSE;\r
-  Command command = ParseAlias(argv[0]);\r
-\r
-  for (i = 1; i < argc; ++i) {\r
-    const char* arg = argv[i];\r
-    /* C99 5.1.2.2.1: "members argv[0] through argv[argc-1] inclusive shall\r
-       contain pointers to strings"; NULL and 0-length are not forbidden. */\r
-    size_t arg_len = arg ? strlen(arg) : 0;\r
-\r
-    if (arg_len == 0) {\r
-      params->not_input_indices[next_option_index++] = i;\r
-      continue;\r
-    }\r
-\r
-    /* Too many options. The expected longest option list is:\r
-       "-q 0 -w 10 -o f -D d -S b -d -f -k -n -v --", i.e. 16 items in total.\r
-       This check is an additional guard that is never triggered, but provides\r
-       a guard for future changes. */\r
-    if (next_option_index > (MAX_OPTIONS - 2)) {\r
-      fprintf(stderr, "too many options passed\n");\r
-      return COMMAND_INVALID;\r
-    }\r
-\r
-    /* Input file entry. */\r
-    if (after_dash_dash || arg[0] != '-' || arg_len == 1) {\r
-      input_count++;\r
-      if (longest_path_len < arg_len) longest_path_len = arg_len;\r
-      continue;\r
-    }\r
-\r
-    /* Not a file entry. */\r
-    params->not_input_indices[next_option_index++] = i;\r
-\r
-    /* '--' entry stop parsing arguments. */\r
-    if (arg_len == 2 && arg[1] == '-') {\r
-      after_dash_dash = BROTLI_TRUE;\r
-      continue;\r
-    }\r
-\r
-    /* Simple / coalesced options. */\r
-    if (arg[1] != '-') {\r
-      size_t j;\r
-      for (j = 1; j < arg_len; ++j) {\r
-        char c = arg[j];\r
-        if (c >= '0' && c <= '9') {\r
-          if (quality_set) {\r
-            fprintf(stderr, "quality already set\n");\r
-            return COMMAND_INVALID;\r
-          }\r
-          quality_set = BROTLI_TRUE;\r
-          params->quality = c - '0';\r
-          continue;\r
-        } else if (c == 'c') {\r
-          if (output_set) {\r
-            fprintf(stderr, "write to standard output already set\n");\r
-            return COMMAND_INVALID;\r
-          }\r
-          output_set = BROTLI_TRUE;\r
-          params->write_to_stdout = BROTLI_TRUE;\r
-          continue;\r
-        } else if (c == 'd') {\r
-          if (command_set) {\r
-            fprintf(stderr, "command already set when parsing -d\n");\r
-            return COMMAND_INVALID;\r
-          }\r
-          command_set = BROTLI_TRUE;\r
-          command = COMMAND_DECOMPRESS;\r
-          continue;\r
-        } else if (c == 'f') {\r
-          if (params->force_overwrite) {\r
-            fprintf(stderr, "force output overwrite already set\n");\r
-            return COMMAND_INVALID;\r
-          }\r
-          params->force_overwrite = BROTLI_TRUE;\r
-          continue;\r
-        } else if (c == 'h') {\r
-          /* Don't parse further. */\r
-          return COMMAND_HELP;\r
-        } else if (c == 'j' || c == 'k') {\r
-          if (keep_set) {\r
-            fprintf(stderr, "argument --rm / -j or --keep / -n already set\n");\r
-            return COMMAND_INVALID;\r
-          }\r
-          keep_set = BROTLI_TRUE;\r
-          params->junk_source = TO_BROTLI_BOOL(c == 'j');\r
-          continue;\r
-        } else if (c == 'n') {\r
-          if (!params->copy_stat) {\r
-            fprintf(stderr, "argument --no-copy-stat / -n already set\n");\r
-            return COMMAND_INVALID;\r
-          }\r
-          params->copy_stat = BROTLI_FALSE;\r
-          continue;\r
-        } else if (c == 't') {\r
-          if (command_set) {\r
-            fprintf(stderr, "command already set when parsing -t\n");\r
-            return COMMAND_INVALID;\r
-          }\r
-          command_set = BROTLI_TRUE;\r
-          command = COMMAND_TEST_INTEGRITY;\r
-          continue;\r
-        } else if (c == 'v') {\r
-          if (params->verbose) {\r
-            fprintf(stderr, "argument --verbose / -v already set\n");\r
-            return COMMAND_INVALID;\r
-          }\r
-          params->verbose = BROTLI_TRUE;\r
-          continue;\r
-        } else if (c == 'V') {\r
-          /* Don't parse further. */\r
-          return COMMAND_VERSION;\r
-        } else if (c == 'Z') {\r
-          if (quality_set) {\r
-            fprintf(stderr, "quality already set\n");\r
-            return COMMAND_INVALID;\r
-          }\r
-          quality_set = BROTLI_TRUE;\r
-          params->quality = 11;\r
-          continue;\r
-        }\r
-        /* o/q/w/D/S with parameter is expected */\r
-        if (c != 'o' && c != 'q' && c != 'w' && c != 'D' && c != 'S') {\r
-          fprintf(stderr, "invalid argument -%c\n", c);\r
-          return COMMAND_INVALID;\r
-        }\r
-        if (j + 1 != arg_len) {\r
-          fprintf(stderr, "expected parameter for argument -%c\n", c);\r
-          return COMMAND_INVALID;\r
-        }\r
-        i++;\r
-        if (i == argc || !argv[i] || argv[i][0] == 0) {\r
-          fprintf(stderr, "expected parameter for argument -%c\n", c);\r
-          return COMMAND_INVALID;\r
-        }\r
-        params->not_input_indices[next_option_index++] = i;\r
-        if (c == 'o') {\r
-          if (output_set) {\r
-            fprintf(stderr, "write to standard output already set (-o)\n");\r
-            return COMMAND_INVALID;\r
-          }\r
-          params->output_path = argv[i];\r
-        } else if (c == 'g') {\r
-          gmem_set = ParseInt(argv[i], 1, 0x10, &params->gmem);\r
-          if (!gmem_set) {\r
-            fprintf(stderr, "error parsing gmem value [%s]\n", argv[i]);\r
-            return COMMAND_INVALID;\r
-          }\r
-        } else if (c == 'q') {\r
-          if (quality_set) {\r
-            fprintf(stderr, "quality already set\n");\r
-            return COMMAND_INVALID;\r
-          }\r
-          quality_set = ParseInt(argv[i], BROTLI_MIN_QUALITY,\r
-                                 BROTLI_MAX_QUALITY, &params->quality);\r
-          if (!quality_set) {\r
-            fprintf(stderr, "error parsing quality value [%s]\n", argv[i]);\r
-            return COMMAND_INVALID;\r
-          }\r
-        } else if (c == 'w') {\r
-          if (lgwin_set) {\r
-            fprintf(stderr, "lgwin parameter already set\n");\r
-            return COMMAND_INVALID;\r
-          }\r
-          lgwin_set = ParseInt(argv[i], 0,\r
-                               BROTLI_MAX_WINDOW_BITS, &params->lgwin);\r
-          if (!lgwin_set) {\r
-            fprintf(stderr, "error parsing lgwin value [%s]\n", argv[i]);\r
-            return COMMAND_INVALID;\r
-          }\r
-          if (params->lgwin != 0 && params->lgwin < BROTLI_MIN_WINDOW_BITS) {\r
-            fprintf(stderr,\r
-                    "lgwin parameter (%d) smaller than the minimum (%d)\n",\r
-                    params->lgwin, BROTLI_MIN_WINDOW_BITS);\r
-            return COMMAND_INVALID;\r
-          }\r
-        } else if (c == 'S') {\r
-          if (suffix_set) {\r
-            fprintf(stderr, "suffix already set\n");\r
-            return COMMAND_INVALID;\r
-          }\r
-          suffix_set = BROTLI_TRUE;\r
-          params->suffix = argv[i];\r
-        }\r
-      }\r
-    } else {  /* Double-dash. */\r
-      arg = &arg[2];\r
-      if (strcmp("best", arg) == 0) {\r
-        if (quality_set) {\r
-          fprintf(stderr, "quality already set\n");\r
-          return COMMAND_INVALID;\r
-        }\r
-        quality_set = BROTLI_TRUE;\r
-        params->quality = 11;\r
-      } else if (strcmp("decompress", arg) == 0) {\r
-        if (command_set) {\r
-          fprintf(stderr, "command already set when parsing --decompress\n");\r
-          return COMMAND_INVALID;\r
-        }\r
-        command_set = BROTLI_TRUE;\r
-        command = COMMAND_DECOMPRESS;\r
-      } else if (strcmp("force", arg) == 0) {\r
-        if (params->force_overwrite) {\r
-          fprintf(stderr, "force output overwrite already set\n");\r
-          return COMMAND_INVALID;\r
-        }\r
-        params->force_overwrite = BROTLI_TRUE;\r
-      } else if (strcmp("help", arg) == 0) {\r
-        /* Don't parse further. */\r
-        return COMMAND_HELP;\r
-      } else if (strcmp("keep", arg) == 0) {\r
-        if (keep_set) {\r
-          fprintf(stderr, "argument --rm / -j or --keep / -n already set\n");\r
-          return COMMAND_INVALID;\r
-        }\r
-        keep_set = BROTLI_TRUE;\r
-        params->junk_source = BROTLI_FALSE;\r
-      } else if (strcmp("no-copy-stat", arg) == 0) {\r
-        if (!params->copy_stat) {\r
-          fprintf(stderr, "argument --no-copy-stat / -n already set\n");\r
-          return COMMAND_INVALID;\r
-        }\r
-        params->copy_stat = BROTLI_FALSE;\r
-      } else if (strcmp("rm", arg) == 0) {\r
-        if (keep_set) {\r
-          fprintf(stderr, "argument --rm / -j or --keep / -n already set\n");\r
-          return COMMAND_INVALID;\r
-        }\r
-        keep_set = BROTLI_TRUE;\r
-        params->junk_source = BROTLI_TRUE;\r
-      } else if (strcmp("stdout", arg) == 0) {\r
-        if (output_set) {\r
-          fprintf(stderr, "write to standard output already set\n");\r
-          return COMMAND_INVALID;\r
-        }\r
-        output_set = BROTLI_TRUE;\r
-        params->write_to_stdout = BROTLI_TRUE;\r
-      } else if (strcmp("test", arg) == 0) {\r
-        if (command_set) {\r
-          fprintf(stderr, "command already set when parsing --test\n");\r
-          return COMMAND_INVALID;\r
-        }\r
-        command_set = BROTLI_TRUE;\r
-        command = COMMAND_TEST_INTEGRITY;\r
-      } else if (strcmp("verbose", arg) == 0) {\r
-        if (params->verbose) {\r
-          fprintf(stderr, "argument --verbose / -v already set\n");\r
-          return COMMAND_INVALID;\r
-        }\r
-        params->verbose = BROTLI_TRUE;\r
-      } else if (strcmp("version", arg) == 0) {\r
-        /* Don't parse further. */\r
-        return COMMAND_VERSION;\r
-      } else {\r
-        /* key=value */\r
-        const char* value = strrchr(arg, '=');\r
-        size_t key_len;\r
-        if (!value || value[1] == 0) {\r
-          fprintf(stderr, "must pass the parameter as --%s=value\n", arg);\r
-          return COMMAND_INVALID;\r
-        }\r
-        key_len = (size_t)(value - arg);\r
-        value++;\r
-        if (strncmp("lgwin", arg, key_len) == 0) {\r
-          if (lgwin_set) {\r
-            fprintf(stderr, "lgwin parameter already set\n");\r
-            return COMMAND_INVALID;\r
-          }\r
-          lgwin_set = ParseInt(value, 0,\r
-                               BROTLI_MAX_WINDOW_BITS, &params->lgwin);\r
-          if (!lgwin_set) {\r
-            fprintf(stderr, "error parsing lgwin value [%s]\n", value);\r
-            return COMMAND_INVALID;\r
-          }\r
-          if (params->lgwin != 0 && params->lgwin < BROTLI_MIN_WINDOW_BITS) {\r
-            fprintf(stderr,\r
-                    "lgwin parameter (%d) smaller than the minimum (%d)\n",\r
-                    params->lgwin, BROTLI_MIN_WINDOW_BITS);\r
-            return COMMAND_INVALID;\r
-          }\r
-        } else if (strncmp("large_window", arg, key_len) == 0) {\r
-          /* This option is intentionally not mentioned in help. */\r
-          if (lgwin_set) {\r
-            fprintf(stderr, "lgwin parameter already set\n");\r
-            return COMMAND_INVALID;\r
-          }\r
-          lgwin_set = ParseInt(value, 0,\r
-                               BROTLI_LARGE_MAX_WINDOW_BITS, &params->lgwin);\r
-          if (!lgwin_set) {\r
-            fprintf(stderr, "error parsing lgwin value [%s]\n", value);\r
-            return COMMAND_INVALID;\r
-          }\r
-          if (params->lgwin != 0 && params->lgwin < BROTLI_MIN_WINDOW_BITS) {\r
-            fprintf(stderr,\r
-                    "lgwin parameter (%d) smaller than the minimum (%d)\n",\r
-                    params->lgwin, BROTLI_MIN_WINDOW_BITS);\r
-            return COMMAND_INVALID;\r
-          }\r
-        } else if (strncmp("output", arg, key_len) == 0) {\r
-          if (output_set) {\r
-            fprintf(stderr,\r
-                    "write to standard output already set (--output)\n");\r
-            return COMMAND_INVALID;\r
-          }\r
-          params->output_path = value;\r
-        } else if (strncmp("gap", arg, key_len) == 0) {\r
-          gmem_set = ParseInt(value, 1, 0x10, &params->gmem);\r
-          if (!gmem_set) {\r
-            fprintf(stderr, "error parsing gmem value [%s]\n", value);\r
-            return COMMAND_INVALID;\r
-          }\r
-        } else if (strncmp("quality", arg, key_len) == 0) {\r
-          if (quality_set) {\r
-            fprintf(stderr, "quality already set\n");\r
-            return COMMAND_INVALID;\r
-          }\r
-          quality_set = ParseInt(value, BROTLI_MIN_QUALITY,\r
-                                 BROTLI_MAX_QUALITY, &params->quality);\r
-          if (!quality_set) {\r
-            fprintf(stderr, "error parsing quality value [%s]\n", value);\r
-            return COMMAND_INVALID;\r
-          }\r
-        } else if (strncmp("suffix", arg, key_len) == 0) {\r
-          if (suffix_set) {\r
-            fprintf(stderr, "suffix already set\n");\r
-            return COMMAND_INVALID;\r
-          }\r
-          suffix_set = BROTLI_TRUE;\r
-          params->suffix = value;\r
-        } else {\r
-          fprintf(stderr, "invalid parameter: [%s]\n", arg);\r
-          return COMMAND_INVALID;\r
-        }\r
-      }\r
-    }\r
-  }\r
-\r
-  params->input_count = input_count;\r
-  params->longest_path_len = longest_path_len;\r
-  params->decompress = (command == COMMAND_DECOMPRESS);\r
-  params->test_integrity = (command == COMMAND_TEST_INTEGRITY);\r
-\r
-  if (input_count > 1 && output_set) return COMMAND_INVALID;\r
-  if (params->test_integrity) {\r
-    if (params->output_path) return COMMAND_INVALID;\r
-    if (params->write_to_stdout) return COMMAND_INVALID;\r
-  }\r
-  if (strchr(params->suffix, '/') || strchr(params->suffix, '\\')) {\r
-    return COMMAND_INVALID;\r
-  }\r
-\r
-  return command;\r
-}\r
-\r
-static void PrintVersion(void) {\r
-  int major = BROTLI_VERSION >> 24;\r
-  int minor = (BROTLI_VERSION >> 12) & 0xFFF;\r
-  int patch = BROTLI_VERSION & 0xFFF;\r
-  fprintf(stdout, "brotli %d.%d.%d\n", major, minor, patch);\r
-}\r
-\r
-static void PrintHelp(const char* name, BROTLI_BOOL error) {\r
-  FILE* media = error ? stderr : stdout;\r
-  /* String is cut to pieces with length less than 509, to conform C90 spec. */\r
-  fprintf(media,\r
-"Usage: %s [OPTION]... [FILE]...\n",\r
-          name);\r
-  fprintf(media,\r
-"Options:\n"\r
-"  -#                          compression level (0-9)\n"\r
-"  -c, --stdout                write on standard output\n"\r
-"  -d, --decompress            decompress\n"\r
-"  -f, --force                 force output file overwrite\n"\r
-"  -h, --help                  display this help and exit\n");\r
-  fprintf(media,\r
-"  -j, --rm                    remove source file(s)\n"\r
-"  -k, --keep                  keep source file(s) (default)\n"\r
-"  -n, --no-copy-stat          do not copy source file(s) attributes\n"\r
-"  -o FILE, --output=FILE      output file (only if 1 input file)\n");\r
-  fprintf(media,\r
-"  -g NUM, --gap=NUM           scratch memory gap level (1-16)\n");\r
-  fprintf(media,\r
-"  -q NUM, --quality=NUM       compression level (%d-%d)\n",\r
-          BROTLI_MIN_QUALITY, BROTLI_MAX_QUALITY);\r
-  fprintf(media,\r
-"  -t, --test                  test compressed file integrity\n"\r
-"  -v, --verbose               verbose mode\n");\r
-  fprintf(media,\r
-"  -w NUM, --lgwin=NUM         set LZ77 window size (0, %d-%d)\n",\r
-          BROTLI_MIN_WINDOW_BITS, BROTLI_MAX_WINDOW_BITS);\r
-  fprintf(media,\r
-"                              window size = 2**NUM - 16\n"\r
-"                              0 lets compressor choose the optimal value\n");\r
-  fprintf(media,\r
-"  -S SUF, --suffix=SUF        output file suffix (default:'%s')\n",\r
-          DEFAULT_SUFFIX);\r
-  fprintf(media,\r
-"  -V, --version               display version and exit\n"\r
-"  -Z, --best                  use best compression level (11) (default)\n"\r
-"Simple options could be coalesced, i.e. '-9kf' is equivalent to '-9 -k -f'.\n"\r
-"With no FILE, or when FILE is -, read standard input.\n"\r
-"All arguments after '--' are treated as files.\n");\r
-}\r
-\r
-static const char* PrintablePath(const char* path) {\r
-  return path ? path : "con";\r
-}\r
-\r
-static BROTLI_BOOL OpenInputFile(const char* input_path, FILE** f) {\r
-  *f = NULL;\r
-  if (!input_path) {\r
-    *f = fdopen(MAKE_BINARY(STDIN_FILENO), "rb");\r
-    return BROTLI_TRUE;\r
-  }\r
-  *f = fopen(input_path, "rb");\r
-  if (!*f) {\r
-    fprintf(stderr, "failed to open input file [%s]: %s\n",\r
-            PrintablePath(input_path), strerror(errno));\r
-    return BROTLI_FALSE;\r
-  }\r
-  return BROTLI_TRUE;\r
-}\r
-\r
-static BROTLI_BOOL OpenOutputFile(const char* output_path, FILE** f,\r
-                                  BROTLI_BOOL force) {\r
-  int fd;\r
-  *f = NULL;\r
-  if (!output_path) {\r
-    *f = fdopen(MAKE_BINARY(STDOUT_FILENO), "wb");\r
-    return BROTLI_TRUE;\r
-  }\r
-  fd = open(output_path, O_CREAT | (force ? 0 : O_EXCL) | O_WRONLY | O_TRUNC,\r
-            S_IRUSR | S_IWUSR);\r
-  if (fd < 0) {\r
-    fd = open(output_path, (force ? 0 : O_EXCL) | O_WRONLY | O_TRUNC,\r
-              S_IRUSR | S_IWUSR);\r
-    if (fd < 0) {\r
-      fprintf(stderr, "failed to open output file [%s]: %s\n",\r
-              PrintablePath(output_path), strerror(errno));\r
-      return BROTLI_FALSE;\r
-    }\r
-  }\r
-\r
-  *f = fdopen(fd, "wb");\r
-  if (!*f) {\r
-    fprintf(stderr, "failed to open output file [%s]: %s\n",\r
-            PrintablePath(output_path), strerror(errno));\r
-    return BROTLI_FALSE;\r
-  }\r
-  return BROTLI_TRUE;\r
-}\r
-\r
-static int64_t FileSize(const char* path) {\r
-  FILE* f = fopen(path, "rb");\r
-  int64_t retval;\r
-  if (f == NULL) {\r
-    return -1;\r
-  }\r
-  if (fseek(f, 0L, SEEK_END) != 0) {\r
-    fclose(f);\r
-    return -1;\r
-  }\r
-  retval = ftell(f);\r
-  if (fclose(f) != 0) {\r
-    return -1;\r
-  }\r
-  return retval;\r
-}\r
-\r
-/* Copy file times and permissions.\r
-   TODO: this is a "best effort" implementation; honest cross-platform\r
-   fully featured implementation is way too hacky; add more hacks by request. */\r
-static void CopyStat(const char* input_path, const char* output_path) {\r
-  struct stat statbuf;\r
-  struct utimbuf times;\r
-  int res;\r
-  if (input_path == 0 || output_path == 0) {\r
-    return;\r
-  }\r
-  if (stat(input_path, &statbuf) != 0) {\r
-    return;\r
-  }\r
-  times.actime = statbuf.st_atime;\r
-  times.modtime = statbuf.st_mtime;\r
-  utime(output_path, &times);\r
-  res = chmod(output_path, statbuf.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO));\r
-  if (res != 0) {\r
-    fprintf(stderr, "setting access bits failed for [%s]: %s\n",\r
-            PrintablePath(output_path), strerror(errno));\r
-  }\r
-  res = chown(output_path, (uid_t)-1, statbuf.st_gid);\r
-  if (res != 0) {\r
-    fprintf(stderr, "setting group failed for [%s]: %s\n",\r
-            PrintablePath(output_path), strerror(errno));\r
-  }\r
-  res = chown(output_path, statbuf.st_uid, (gid_t)-1);\r
-  if (res != 0) {\r
-    fprintf(stderr, "setting user failed for [%s]: %s\n",\r
-            PrintablePath(output_path), strerror(errno));\r
-  }\r
-}\r
-\r
-int64_t input_file_length = 0;\r
-\r
-static BROTLI_BOOL NextFile(Context* context) {\r
-  const char* arg;\r
-  size_t arg_len;\r
-\r
-  /* Iterator points to last used arg; increment to search for the next one. */\r
-  context->iterator++;\r
-\r
-  context->input_file_length = -1;\r
-\r
-  /* No input path; read from console. */\r
-  if (context->input_count == 0) {\r
-    if (context->iterator > 1) return BROTLI_FALSE;\r
-    context->current_input_path = NULL;\r
-    /* Either write to the specified path, or to console. */\r
-    context->current_output_path = context->output_path;\r
-    return BROTLI_TRUE;\r
-  }\r
-\r
-  /* Skip option arguments. */\r
-  while (context->iterator == context->not_input_indices[context->ignore]) {\r
-    context->iterator++;\r
-    context->ignore++;\r
-  }\r
-\r
-  /* All args are scanned already. */\r
-  if (context->iterator >= context->argc) return BROTLI_FALSE;\r
-\r
-  /* Iterator now points to the input file name. */\r
-  arg = context->argv[context->iterator];\r
-  arg_len = strlen(arg);\r
-  /* Read from console. */\r
-  if (arg_len == 1 && arg[0] == '-') {\r
-    context->current_input_path = NULL;\r
-    context->current_output_path = context->output_path;\r
-    return BROTLI_TRUE;\r
-  }\r
-\r
-  if (context->current_input_path == NULL) {\r
-    context->current_input_path = arg;\r
-  }\r
-  context->input_file_length = FileSize(context->current_input_path);\r
-  context->current_output_path = context->output_path;\r
-  if (!context->decompress) {\r
-    input_file_length += context->input_file_length;\r
-  }\r
-\r
-  if (context->output_path) return BROTLI_TRUE;\r
-  if (context->write_to_stdout) return BROTLI_TRUE;\r
-\r
-  strcpy(context->modified_path, arg);\r
-  context->current_output_path = context->modified_path;\r
-  /* If output is not specified, input path suffix should match. */\r
-  if (context->decompress) {\r
-    size_t suffix_len = strlen(context->suffix);\r
-    char* name = (char*)FileName(context->modified_path);\r
-    char* name_suffix;\r
-    size_t name_len = strlen(name);\r
-    if (name_len < suffix_len + 1) {\r
-      fprintf(stderr, "empty output file name for [%s] input file\n",\r
-              PrintablePath(arg));\r
-      context->iterator_error = BROTLI_TRUE;\r
-      return BROTLI_FALSE;\r
-    }\r
-    name_suffix = name + name_len - suffix_len;\r
-    if (strcmp(context->suffix, name_suffix) != 0) {\r
-      fprintf(stderr, "input file [%s] suffix mismatch\n",\r
-              PrintablePath(arg));\r
-      context->iterator_error = BROTLI_TRUE;\r
-      return BROTLI_FALSE;\r
-    }\r
-    name_suffix[0] = 0;\r
-    return BROTLI_TRUE;\r
-  } else {\r
-    strcpy(context->modified_path + arg_len, context->suffix);\r
-    return BROTLI_TRUE;\r
-  }\r
-}\r
-\r
-static BROTLI_BOOL OpenFiles(Context* context) {\r
-  BROTLI_BOOL is_ok = OpenInputFile(context->current_input_path, &context->fin);\r
-  if (context->decompress) {\r
-    //\r
-    // skip the decoder data header\r
-    //\r
-    fseek(context->fin, DECODE_HEADER_SIZE, SEEK_SET);\r
-  }\r
-  if (!context->test_integrity && is_ok && context->fout == NULL) {\r
-    is_ok = OpenOutputFile(\r
-        context->current_output_path, &context->fout, context->force_overwrite);\r
-  }\r
-  if (!context->decompress) {\r
-    //\r
-    // append the decoder data header\r
-    //\r
-    fseek(context->fout, DECODE_HEADER_SIZE, SEEK_SET);\r
-  }\r
-  return is_ok;\r
-}\r
-\r
-static BROTLI_BOOL CloseFiles(Context* context, BROTLI_BOOL success) {\r
-  BROTLI_BOOL is_ok = BROTLI_TRUE;\r
-  if (!context->test_integrity && context->fout) {\r
-    if (!success && context->current_output_path) {\r
-      unlink(context->current_output_path);\r
-    }\r
-    if (fclose(context->fout) != 0) {\r
-      if (success) {\r
-        fprintf(stderr, "fclose failed [%s]: %s\n",\r
-                PrintablePath(context->current_output_path), strerror(errno));\r
-      }\r
-      is_ok = BROTLI_FALSE;\r
-    }\r
-\r
-    /* TOCTOU violation, but otherwise it is impossible to set file times. */\r
-    if (success && is_ok && context->copy_stat) {\r
-      CopyStat(context->current_input_path, context->current_output_path);\r
-    }\r
-  }\r
-\r
-  if (context->fin) {\r
-    if (fclose(context->fin) != 0) {\r
-      if (is_ok) {\r
-        fprintf(stderr, "fclose failed [%s]: %s\n",\r
-                PrintablePath(context->current_input_path), strerror(errno));\r
-      }\r
-      is_ok = BROTLI_FALSE;\r
-    }\r
-  }\r
-  if (success && context->junk_source && context->current_input_path) {\r
-    unlink(context->current_input_path);\r
-  }\r
-\r
-  context->fin = NULL;\r
-  context->fout = NULL;\r
-\r
-  return is_ok;\r
-}\r
-\r
-static const size_t kFileBufferSize = 1 << 16;\r
-\r
-static void InitializeBuffers(Context* context) {\r
-  context->available_in = 0;\r
-  context->next_in = NULL;\r
-  context->available_out = kFileBufferSize;\r
-  context->next_out = context->output;\r
-}\r
-\r
-static BROTLI_BOOL HasMoreInput(Context* context) {\r
-  return feof(context->fin) ? BROTLI_FALSE : BROTLI_TRUE;\r
-}\r
-\r
-static BROTLI_BOOL ProvideInput(Context* context) {\r
-  context->available_in =\r
-      fread(context->input, 1, kFileBufferSize, context->fin);\r
-  context->next_in = context->input;\r
-  if (ferror(context->fin)) {\r
-    fprintf(stderr, "failed to read input [%s]: %s\n",\r
-            PrintablePath(context->current_input_path), strerror(errno));\r
-    return BROTLI_FALSE;\r
-  }\r
-  return BROTLI_TRUE;\r
-}\r
-\r
-/* Internal: should be used only in Provide-/Flush-Output. */\r
-static BROTLI_BOOL WriteOutput(Context* context) {\r
-  size_t out_size = (size_t)(context->next_out - context->output);\r
-  if (out_size == 0) return BROTLI_TRUE;\r
-  if (context->test_integrity) return BROTLI_TRUE;\r
-\r
-  fwrite(context->output, 1, out_size, context->fout);\r
-  if (ferror(context->fout)) {\r
-    fprintf(stderr, "failed to write output [%s]: %s\n",\r
-            PrintablePath(context->current_output_path), strerror(errno));\r
-    return BROTLI_FALSE;\r
-  }\r
-  return BROTLI_TRUE;\r
-}\r
-\r
-static BROTLI_BOOL ProvideOutput(Context* context) {\r
-  if (!WriteOutput(context)) return BROTLI_FALSE;\r
-  context->available_out = kFileBufferSize;\r
-  context->next_out = context->output;\r
-  return BROTLI_TRUE;\r
-}\r
-\r
-static BROTLI_BOOL FlushOutput(Context* context) {\r
-  if (!WriteOutput(context)) return BROTLI_FALSE;\r
-  context->available_out = 0;\r
-  return BROTLI_TRUE;\r
-}\r
-\r
-static BROTLI_BOOL DecompressFile(Context* context, BrotliDecoderState* s) {\r
-  BrotliDecoderResult result = BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT;\r
-  InitializeBuffers(context);\r
-  for (;;) {\r
-    if (result == BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT) {\r
-      if (!HasMoreInput(context)) {\r
-        fprintf(stderr, "corrupt input [%s]\n",\r
-                PrintablePath(context->current_input_path));\r
-        return BROTLI_FALSE;\r
-      }\r
-      if (!ProvideInput(context)) return BROTLI_FALSE;\r
-    } else if (result == BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT) {\r
-      if (!ProvideOutput(context)) return BROTLI_FALSE;\r
-    } else if (result == BROTLI_DECODER_RESULT_SUCCESS) {\r
-      if (!FlushOutput(context)) return BROTLI_FALSE;\r
-      if (context->available_in != 0 || HasMoreInput(context)) {\r
-        fprintf(stderr, "corrupt input [%s]\n",\r
-                PrintablePath(context->current_input_path));\r
-        return BROTLI_FALSE;\r
-      }\r
-      return BROTLI_TRUE;\r
-    } else {\r
-      fprintf(stderr, "corrupt input [%s]\n",\r
-              PrintablePath(context->current_input_path));\r
-      return BROTLI_FALSE;\r
-    }\r
-\r
-    result = BrotliDecoderDecompressStream(s, &context->available_in,\r
-        &context->next_in, &context->available_out, &context->next_out, 0);\r
-  }\r
-}\r
-\r
-/* Default brotli_alloc_func */\r
-void* BrotliAllocFunc(void* opaque, size_t size) {\r
-  *(size_t *)opaque = *(size_t *) opaque + size; \r
-  return malloc(size);\r
-}\r
-\r
-/* Default brotli_free_func */\r
-void BrotliFreeFunc(void* opaque, void* address) {\r
-  free(address);\r
-}\r
-\r
-size_t scratch_buffer_size = 0;\r
-\r
-static BROTLI_BOOL DecompressFiles(Context* context) {\r
-  while (NextFile(context)) {\r
-    BROTLI_BOOL is_ok = BROTLI_TRUE;\r
-    BrotliDecoderState* s = BrotliDecoderCreateInstance(BrotliAllocFunc, BrotliFreeFunc, &scratch_buffer_size);\r
-    if (!s) {\r
-      fprintf(stderr, "out of memory\n");\r
-      return BROTLI_FALSE;\r
-    }\r
-    /* This allows decoding "large-window" streams. Though it creates\r
-       fragmentation (new builds decode streams that old builds don't),\r
-       it is better from used experience perspective. */\r
-    BrotliDecoderSetParameter(s, BROTLI_DECODER_PARAM_LARGE_WINDOW, 1u);\r
-    is_ok = OpenFiles(context);\r
-    if (is_ok && !context->current_input_path &&\r
-        !context->force_overwrite && isatty(STDIN_FILENO)) {\r
-      fprintf(stderr, "Use -h help. Use -f to force input from a terminal.\n");\r
-      is_ok = BROTLI_FALSE;\r
-    }\r
-    if (is_ok) is_ok = DecompressFile(context, s);\r
-    BrotliDecoderDestroyInstance(s);\r
-    if (!CloseFiles(context, is_ok)) is_ok = BROTLI_FALSE;\r
-    if (!is_ok) return BROTLI_FALSE;\r
-  }\r
-  return BROTLI_TRUE;\r
-}\r
-\r
-static BROTLI_BOOL CompressFile(Context* context, BrotliEncoderState* s) {\r
-  BROTLI_BOOL is_eof = BROTLI_FALSE;\r
-  InitializeBuffers(context);\r
-  for (;;) {\r
-    if (context->available_in == 0 && !is_eof) {\r
-      if (!ProvideInput(context)) return BROTLI_FALSE;\r
-      is_eof = !HasMoreInput(context);\r
-    }\r
-\r
-    if (!BrotliEncoderCompressStream(s,\r
-        is_eof ? BROTLI_OPERATION_FINISH : BROTLI_OPERATION_PROCESS,\r
-        &context->available_in, &context->next_in,\r
-        &context->available_out, &context->next_out, NULL)) {\r
-      /* Should detect OOM? */\r
-      fprintf(stderr, "failed to compress data [%s]\n",\r
-              PrintablePath(context->current_input_path));\r
-      return BROTLI_FALSE;\r
-    }\r
-\r
-    if (context->available_out == 0) {\r
-      if (!ProvideOutput(context)) return BROTLI_FALSE;\r
-    }\r
-\r
-    if (BrotliEncoderIsFinished(s)) {\r
-      return FlushOutput(context);\r
-    }\r
-  }\r
-}\r
-\r
-static BROTLI_BOOL CompressFiles(Context* context) {\r
-  while (NextFile(context)) {\r
-    BROTLI_BOOL is_ok = BROTLI_TRUE;\r
-    BrotliEncoderState* s = BrotliEncoderCreateInstance(NULL, NULL, NULL);\r
-    if (!s) {\r
-      fprintf(stderr, "out of memory\n");\r
-      return BROTLI_FALSE;\r
-    }\r
-    BrotliEncoderSetParameter(s,\r
-        BROTLI_PARAM_QUALITY, (uint32_t)context->quality);\r
-    if (context->lgwin > 0) {\r
-      /* Specified by user. */\r
-      /* Do not enable "large-window" extension, if not required. */\r
-      if (context->lgwin > BROTLI_MAX_WINDOW_BITS) {\r
-        BrotliEncoderSetParameter(s, BROTLI_PARAM_LARGE_WINDOW, 1u);\r
-      }\r
-      BrotliEncoderSetParameter(s,\r
-          BROTLI_PARAM_LGWIN, (uint32_t)context->lgwin);\r
-    } else {\r
-      /* 0, or not specified by user; could be chosen by compressor. */\r
-      uint32_t lgwin = DEFAULT_LGWIN;\r
-      /* Use file size to limit lgwin. */\r
-      if (context->input_file_length >= 0) {\r
-        int32_t size = 1 << BROTLI_MIN_WINDOW_BITS;\r
-        lgwin = BROTLI_MIN_WINDOW_BITS;\r
-        while (size < context->input_file_length) {\r
-          size <<= 1;\r
-          lgwin++;\r
-          if (lgwin == BROTLI_MAX_WINDOW_BITS) break;\r
-        }\r
-      }\r
-      BrotliEncoderSetParameter(s, BROTLI_PARAM_LGWIN, lgwin);\r
-    }\r
-    if (context->input_file_length > 0) {\r
-      uint32_t size_hint = context->input_file_length < (1 << 30) ?\r
-          (uint32_t)context->input_file_length : (1u << 30);\r
-      BrotliEncoderSetParameter(s, BROTLI_PARAM_SIZE_HINT, size_hint);\r
-    }\r
-    is_ok = OpenFiles(context);\r
-    if (is_ok && !context->current_output_path &&\r
-        !context->force_overwrite && isatty(STDOUT_FILENO)) {\r
-      fprintf(stderr, "Use -h help. Use -f to force output to a terminal.\n");\r
-      is_ok = BROTLI_FALSE;\r
-    }\r
-    if (is_ok) is_ok = CompressFile(context, s);\r
-    BrotliEncoderDestroyInstance(s);\r
-    if (!CloseFiles(context, is_ok)) is_ok = BROTLI_FALSE;\r
-    if (!is_ok) return BROTLI_FALSE;\r
-  }\r
-  return BROTLI_TRUE;\r
-}\r
-\r
-int main(int argc, char** argv) {\r
-  Command command;\r
-  Context context;\r
-  Context context_dec;\r
-  BROTLI_BOOL is_ok = BROTLI_TRUE;\r
-  int i;\r
-\r
-  context.quality = 11;\r
-  context.lgwin = -1;\r
-  context.gmem = 1;\r
-  context.force_overwrite = BROTLI_FALSE;\r
-  context.junk_source = BROTLI_FALSE;\r
-  context.copy_stat = BROTLI_TRUE;\r
-  context.test_integrity = BROTLI_FALSE;\r
-  context.verbose = BROTLI_FALSE;\r
-  context.write_to_stdout = BROTLI_FALSE;\r
-  context.decompress = BROTLI_FALSE;\r
-  context.large_window = BROTLI_FALSE;\r
-  context.output_path = NULL;\r
-  context.suffix = DEFAULT_SUFFIX;\r
-  for (i = 0; i < MAX_OPTIONS; ++i) context.not_input_indices[i] = 0;\r
-  context.longest_path_len = 1;\r
-  context.input_count = 0;\r
-\r
-  context.argc = argc;\r
-  context.argv = argv;\r
-  context.modified_path = NULL;\r
-  context.iterator = 0;\r
-  context.ignore = 0;\r
-  context.iterator_error = BROTLI_FALSE;\r
-  context.buffer = NULL;\r
-  context.current_input_path = NULL;\r
-  context.current_output_path = NULL;\r
-  context.fin = NULL;\r
-  context.fout = NULL;\r
-\r
-  command = ParseParams(&context);\r
-\r
-  if (command == COMMAND_COMPRESS || command == COMMAND_DECOMPRESS ||\r
-      command == COMMAND_TEST_INTEGRITY) {\r
-    if (is_ok) {\r
-      size_t modified_path_len =\r
-          context.longest_path_len + strlen(context.suffix) + 1;\r
-      context.modified_path = (char*)malloc(modified_path_len);\r
-      context.buffer = (uint8_t*)malloc(kFileBufferSize * 2);\r
-      if (!context.modified_path || !context.buffer) {\r
-        fprintf(stderr, "out of memory\n");\r
-        is_ok = BROTLI_FALSE;\r
-      } else {\r
-        context.input = context.buffer;\r
-        context.output = context.buffer + kFileBufferSize;\r
-      }\r
-    }\r
-  }\r
-\r
-  if (!is_ok) command = COMMAND_NOOP;\r
-\r
-  switch (command) {\r
-    case COMMAND_NOOP:\r
-      break;\r
-\r
-    case COMMAND_VERSION:\r
-      PrintVersion();\r
-      break;\r
-\r
-    case COMMAND_COMPRESS:\r
-      memcpy (&context_dec, &context, sizeof (context));\r
-      is_ok = CompressFiles(&context);\r
-      if (!is_ok) {\r
-        break;\r
-      }\r
-      context_dec.decompress  = BROTLI_TRUE;\r
-      context_dec.input_count = 1;\r
-      context_dec.current_input_path = context_dec.output_path;\r
-      context_dec.fout = tmpfile ();\r
-      is_ok = DecompressFiles(&context_dec);\r
-      if (!is_ok) {\r
-        break;\r
-      }\r
-      //\r
-      // fill decoder header\r
-      //\r
-      context_dec.fout = fopen(context_dec.output_path, "rb+");  /* open output_path file and add in head info */\r
-      fwrite(&input_file_length, 1, sizeof(int64_t), context_dec.fout);\r
-      scratch_buffer_size += context.gmem * GAP_MEM_BLOCK;  /* there is a memory gap between IA32 and X64 environment*/\r
-      scratch_buffer_size += kFileBufferSize * 2;\r
-      fwrite(&scratch_buffer_size, 1, sizeof(int64_t), context_dec.fout);\r
-      if (fclose(context_dec.fout) != 0) {\r
-        fprintf(stderr, "failed to update ouptut file: %s\n", context_dec.output_path);\r
-        is_ok = 0;\r
-      }\r
-      break;\r
-\r
-    case COMMAND_DECOMPRESS:\r
-    case COMMAND_TEST_INTEGRITY:\r
-      is_ok = DecompressFiles(&context);\r
-      break;\r
-\r
-    case COMMAND_HELP:\r
-    case COMMAND_INVALID:\r
-    default:\r
-      is_ok = (command == COMMAND_HELP);\r
-      PrintHelp(FileName(argv[0]), is_ok);\r
-      break;\r
-  }\r
-\r
-  if (context.iterator_error) is_ok = BROTLI_FALSE;\r
-\r
-  free(context.modified_path);\r
-  free(context.buffer);\r
-\r
-  if (!is_ok) exit(1);\r
-  return 0;\r
-}\r