diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index a7c40df..d337b64 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -11,15 +11,26 @@ jobs:
strategy:
matrix:
- include:
- - os: ubuntu-18.04
- - os: ubuntu-20.04
- - os: macos-10.15
- - os: macos-11
+ os:
+ - ubuntu-18.04
+ - ubuntu-20.04
+ - macos-10.15
+ - macos-11
+ cc:
+ - gcc
+ - clang
+ arch:
+ - amd64
+ - arm64
+ - arm
+ - ppc64le
+ - s390x
continue-on-error: true
steps:
+ - run: git config --global core.autocrlf false
+
- uses: actions/checkout@v2
- name: Resolve dependencies (Ubuntu)
@@ -30,7 +41,7 @@ jobs:
imagemagick \
libqrencode-dev \
zbar-tools
- if: matrix.os == 'ubuntu-18.04' || matrix.os == 'ubuntu-20.04'
+ if: contains(matrix.os, 'ubuntu')
- name: Resolve dependencies (macOS)
run: |
@@ -41,12 +52,19 @@ jobs:
brew tap homebrew/cask-fonts
brew install --cask font-freefont
convert -font FreeMono label:"Unable to revert mtime: /Library/Fonts fix" png:- > /dev/null
- if: matrix.os == 'macos-10.15' || matrix.os == 'macos-11'
+ if: contains(matrix.os, 'macos')
- name: Build
run: make
- - name: Test
+ - name: Test (Ubuntu)
+ shell: 'script --return --quiet --command "bash {0}"'
+ if: contains(matrix.os, 'ubuntu')
+ run: make test
+
+ - name: Test (macOS)
+ shell: bash -l {0}
+ if: contains(matrix.os, 'macos')
run: make test
- name: Print test logs
@@ -56,7 +74,14 @@ jobs:
- name: Install
run: PREFIX=/usr/local sudo make install
- - name: Run
+ - name: Run (Ubuntu)
+ shell: 'script --return --quiet --command "bash {0}"'
+ if: contains(matrix.os, 'ubuntu')
+ run: /usr/local/bin/qr Success
+
+ - name: Run (macOS)
+ shell: bash -l {0}
+ if: contains(matrix.os, 'macos')
run: /usr/local/bin/qr Success
- name: Uninstall
diff --git a/Dockerfile b/Dockerfile
index 46a83ac..1b72e59 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -8,7 +8,7 @@ RUN apk update && \
COPY Makefile qr.c .
RUN make clean && \
- make -j 16 && \
+ make -j && \
make install
CMD ["qr"]
diff --git a/Makefile b/Makefile
index 0e1dfc0..b747d54 100644
--- a/Makefile
+++ b/Makefile
@@ -4,7 +4,7 @@
include config.mk
$(PROG):
- $(CC) $(PROG).c $(CFLAGS) $(LIBS) -DVERSION="\"$(VERSION)\"" -o $(PROG)
+ $(CC) $(PROG).c $(CFLAGS) $(LIBS) -DPROG="\"$(PROG)\"" -DVERSION="\"$(VERSION)\"" -o $(PROG)
all: $(PROG)
.PHONY: all
@@ -15,20 +15,20 @@ clean:
.PHONY: clean
install: all
- echo installing executable file to $(DESTDIR)$(PREFIX)/bin
- install -d $(DESTDIR)$(PREFIX)/bin
- install -m 755 $(PROG) $(DESTDIR)$(PREFIX)/bin/$(PROG)
+ @echo installing executable file into $(DESTDIR)$(PREFIX)/bin
+ @install -d $(DESTDIR)$(PREFIX)/bin
+ @install -m 755 $(PROG) $(DESTDIR)$(PREFIX)/bin/$(PROG)
.PHONY: install
uninstall:
- echo removing executable file from $(DESTDIR)$(PREFIX)/bin
- rm -f $(DESTDIR)$(PREFIX)/bin/$(PROG)
+ @echo removing executable file from $(DESTDIR)$(PREFIX)/bin
+ @rm -f $(DESTDIR)$(PREFIX)/bin/$(PROG)
.PHONY: uninstall
test: $(PROG)
- autom4te --no-cache -f -l autotest -o tests tests.at
- ./tests \
- FONT=$(FONT) \
- INPUT='Ünic0d3wörd 参 я' \
+ @autom4te --no-cache -f -l autotest -o tests tests.at
+ @./tests \
+ FONT="FreeMono" \
+ INPUT="Ünic0d3wörd 参 я" \
EXTRA_LONG_INPUT="参考文献に掲載されている文章等を抜粋し参考文献に掲載されている文章等を抜粋し参考文献に掲載されている文章等を抜粋し参考文献に掲載されている文章等を抜粋し参考文献に掲載されている文章等を抜粋し参考文献に掲載されている文章等を抜粋し参考文献に掲載されている文章等を抜粋し参考文献に掲載されている文章等を抜粋し参考文献に掲載されている文章等を抜粋し参考文献に掲載されている文章等を抜粋し参考文献に掲載されている文章等を抜粋し参考文献に掲載されている文章等を抜粋し参考文献に掲載されている文章等を抜粋し参考文献に掲載されている文章等を抜粋し参考文献に掲載されている文章等を抜粋し参考文献に掲載されている文章等を抜粋し参考文献に掲載されている文章等を抜粋し参考文献に掲載されている文章等を抜粋し参考文献に掲載されている文章等を抜粋し参考文献に掲載されている文章等を抜粋し参考文献に掲載されている文章等を抜粋し参考文献に掲載されている文章等を抜粋し参考文献に掲載されている文章等を抜粋し参考文献に掲載されている文章等を抜粋し参考文献に掲載されている文章等を抜粋し参考文献に掲載されている文章等を抜粋し参考文献に掲載されている文章等を抜粋し参考文献に掲載されている文章等を抜粋し参考文献に掲載されている文章等を抜粋し参考文献に掲載されている文章等を抜粋し参考文献に掲載されている文章等を抜粋し参考文献に掲載されている文章等を抜粋し参考文献に掲載されている文章等を抜粋し参考文献に掲載されている文章等を抜粋し参考文献に掲載されている文章等を抜粋し参考文献に掲載されている文章等を抜粋し参考文献に掲載されている文章等を抜粋し参考文献に掲載されている文章等を抜粋し参考文献に掲載されている文章等を抜粋し参考文献に掲載されている文章等を抜粋し参考文献に掲載されている文章等を抜粋し参考文献に掲載されている文章等を抜粋し参考文献に掲載されている文章等を抜粋し参考文献に掲載されている文章等を抜粋し参考文献に掲載されている文章等を抜粋し参考文献に掲載されている文章等を抜粋し参考文献に掲載されている文章等を抜粋し参考文献に掲載されている文章等を抜粋し参考文献に掲載されている文章等を抜粋し参考文献に掲載されている文章等を抜粋し参考文献に掲載されている文章等を抜粋し参考文献に掲載されている文章等を抜粋し参考文献に掲載されている文章等を抜粋し参考文献に掲載されている文章等を抜粋し"
.PHONY: test
diff --git a/README.md b/README.md
index da121ce..b0e0cd0 100644
--- a/README.md
+++ b/README.md
@@ -9,9 +9,7 @@ Print Unicode-friendly QR Codes® straight in your terminal!
$ make
-
- Build dependencies
-
+#### Build dependencies
- [libqrencode](https://github.com/fukuchi/libqrencode)
###### Resolve on Ubuntu or Debian
@@ -24,8 +22,6 @@ Print Unicode-friendly QR Codes® straight in your terminal!
$ make
# make install
-
-
## How to install
@@ -37,8 +33,8 @@ or
## How to build and install using containers
- $ docker build -t y2z/qr .
- $ sudo install -b utils/qr.sh /usr/local/bin/qr
+ $ docker build -t Y2Z/qr .
+ $ sudo install -b dist/run-in-container.sh /usr/local/bin/qr
## How to build and install on FreeBSD
@@ -56,13 +52,17 @@ or
or
$ echo -n "Hello" | qr
+or
+
+ $ cat file.png | qr -a
#### Options
- Usage: qr [OPTIONS] STRING
+ Usage: qr [OPTIONS] [STRING]
or: cat FILE | qr [OPTIONS]
Options:
+ -a produce animated QR code
-m QR mode [na8k] (n = number, a = alphabet, 8 = 8-bit, k = Kanji)
-v QR version [1-40]
-e QR EC level [lmqh] or [1-4]
@@ -71,6 +71,7 @@ or
-b border width [1-4] (the default is 1)
-i invert colors
-p force colorless output
+ -u ensure output has UTF-8 BOM
-h print help info and exit
-V print version info and exit
@@ -84,9 +85,7 @@ or
$ make test
-
- Test dependencies
-
+#### Test dependencies
- [autoconf](https://www.gnu.org/software/autoconf/autoconf.html)
###### Resolve on Ubuntu or Debian
@@ -110,8 +109,6 @@ or
$ brew tap homebrew/cask-fonts
$ brew install --cask font-freefont
-
-
## Acknowledgements
diff --git a/config.mk b/config.mk
index 77f58fa..97667aa 100644
--- a/config.mk
+++ b/config.mk
@@ -1,18 +1,17 @@
-# qr version
-VERSION = 1.0.0
-
# program name
PROG = qr
-# font used in tests
-FONT = FreeMono
+# program version
+VERSION = 2.0.0
+#
# Customize below to fit your system
+#
# paths
PREFIX = /usr/local
-# libs
+# libraries
LIBS = -lm -lqrencode
# flags
diff --git a/utils/qr.sh b/dist/run-in-container.sh
similarity index 73%
rename from utils/qr.sh
rename to dist/run-in-container.sh
index bf495e6..5ce8c76 100755
--- a/utils/qr.sh
+++ b/dist/run-in-container.sh
@@ -6,4 +6,4 @@ if which podman 2>&1 > /dev/null; then
DOCKER=podman
fi
-$DOCKER run --rm y2z/qr qr "$@"
+$DOCKER run --rm Y2Z/qr qr "$@"
diff --git a/qr.c b/qr.c
index 61c4dea..e65cc9a 100644
--- a/qr.c
+++ b/qr.c
@@ -13,9 +13,10 @@
#include
#include
#include
+#include
#include
-/* STDIN read buffer chunk size */
+/* STDIN read buffer chunk size in bytes */
#define STDIN_CHUNKSIZE 64
/* Single-module blocks (large size) */
@@ -61,8 +62,9 @@
#define BGBK_FGWH BG_BK FG_WH
#define BGDF_FGDF BG_DF FG_DF
-/* Newline character(s) */
+/* Characters used in terminal output */
#define EOL "\n"
+#define CLR "\033[A\33[2KT\r"
typedef unsigned char bool;
#define true 1
@@ -93,6 +95,7 @@ typedef unsigned char bool;
#define B_1111 15
typedef struct {
+ bool anim;
char encode_mode;
int version;
char ec_level;
@@ -101,6 +104,7 @@ typedef struct {
short border;
bool invert;
bool plain;
+ bool unicode;
} Options;
/* Unicode BOM */
@@ -108,19 +112,21 @@ const char *utf8_bom = "\xEF\xBB\xBF";
/* Help message */
const char *help_msg =
- "Usage: qr [OPTIONS] STRING" EOL
- " or: cat FILE | qr [OPTIONS]" EOL
+ "Usage: " PROG " [OPTIONS] [STRING]" EOL
+ " or: cat FILE | " PROG " [OPTIONS]" EOL
EOL
"Options:" EOL
+ " -a produce animated QR code" EOL
" -m QR mode [na8k] (n = number, a = alphabet, 8 = 8-bit, "
"k = Kanji)" EOL
" -v QR version [1-40]" EOL
" -e QR EC level [lmqh] or [1-4]" EOL
- " -l use two characters per block" EOL
+ " -l large mode" EOL
" -c compact mode" EOL
" -b border width [1-4] (the default is 1)" EOL
" -i invert colors" EOL
" -p force colorless output" EOL
+ " -u ensure output has UTF-8 BOM" EOL
" -h print help info and exit" EOL
" -V print version info and exit" EOL
;
@@ -132,7 +138,7 @@ void print_help_msg(void)
void print_version(void)
{
- printf("qr %s" EOL, VERSION);
+ printf(PROG " %s" EOL, VERSION);
}
void print_error(const char *message)
@@ -140,7 +146,15 @@ void print_error(const char *message)
fprintf(stderr, "Error: %s" EOL, message);
}
-static inline bool str_has_utf8_bom(const char *string)
+void msleep(const int ms)
+{
+ struct timeval tv;
+ tv.tv_sec = ms / 1000;
+ tv.tv_usec = (ms % 1000) * 1000;
+ select(0, NULL, NULL, NULL, &tv);
+}
+
+static inline bool is_utf8_string(const char *string)
{
return (strcmp(string, utf8_bom) == 0);
}
@@ -155,6 +169,7 @@ char *qr_data_to_text(const QRcode *code, const char border_width,
const unsigned char *data = code->data;
if (data == NULL) {
+ print_error("empty QR code data");
return NULL;
}
@@ -164,9 +179,11 @@ char *qr_data_to_text(const QRcode *code, const char border_width,
char *text;
if (large_size) {
- /*******************************************************************/
- /* One module per block (large size and large size + compact mode) */
- /*******************************************************************/
+ /*********************************************************************/
+ /* */
+ /* One module per block (large size and large size + compact mode) */
+ /* */
+ /*********************************************************************/
const char *blocks[2] = {
// 0
@@ -261,14 +278,18 @@ char *qr_data_to_text(const QRcode *code, const char border_width,
strcat(text, EOL);
}
} else {
- /****************************************************************/
- /* Two or four modules per block (normal mode and compact mode) */
- /****************************************************************/
+ /******************************************************************/
+ /* */
+ /* Two or four modules per block (normal mode and compact mode) */
+ /* */
+ /******************************************************************/
if (compact_mode) {
- /*****************************************/
- /* Four modules per block (compact mode) */
- /*****************************************/
+ /*******************************************/
+ /* */
+ /* Four modules per block (compact mode) */
+ /* */
+ /*******************************************/
const char *blocks[16] = {
(invert_colors) ? QUAD_BLOCK_0000 : QUAD_BLOCK_1111,
@@ -493,9 +514,11 @@ char *qr_data_to_text(const QRcode *code, const char border_width,
strcat(text, EOL);
}
} else {
- /***************************************/
- /* Two modules per block (normal mode) */
- /***************************************/
+ /*****************************************/
+ /* */
+ /* Two modules per block (normal mode) */
+ /* */
+ /*****************************************/
const char *blocks[4] = {
(invert_colors) ? DBL_BLOCK_00 : DBL_BLOCK_11,
@@ -688,9 +711,11 @@ QRecLevel get_qr_ec_level(const char ec_level)
int main(int argc, char *argv[])
{
- int ret = 0;
+ int ret = 0, c = 0;
char *str = NULL;
- int c = 0;
+ // bool str_is_dynmically_allocated = false;
+ const bool is_stdin_input = !isatty(STDIN_FILENO);
+ const bool is_term_output = isatty(STDOUT_FILENO);
// Enable wide-character support
char *p = setlocale(LC_ALL, "");
@@ -700,6 +725,7 @@ int main(int argc, char *argv[])
/* Default options */
Options options = {
+ .anim = false,
.encode_mode = '8',
.version = 0,
.ec_level = '1',
@@ -707,38 +733,18 @@ int main(int argc, char *argv[])
.compact = false,
.border = 1,
.invert = false,
- .plain = false
+ .plain = false,
+ .unicode = false,
};
- /* Process STDIN (if any) */
- if (!isatty(STDIN_FILENO)) {
- size_t bufsize = STDIN_CHUNKSIZE;
- str = malloc(bufsize);
- ssize_t stdin_read_size = 0;
- size_t total_bytes = 0;
-
- while ((stdin_read_size = read(STDIN_FILENO, str, STDIN_CHUNKSIZE)) > 0) {
- total_bytes += stdin_read_size;
- bufsize += STDIN_CHUNKSIZE;
- str = realloc(str, bufsize);
-
- if (str == NULL) {
- print_error("out of memory");
- ret = 1;
- goto exit;
- }
- }
- }
-
- /* Parse CLI arguments */
- while (optind < argc) {
- if ((c = getopt(argc, argv, "m:v:e:lcb:iphV")) == -1) {
- free(str);
- str = argv[optind++];
- continue;
- }
-
+ /* Parse CLI flags and options */
+ while ((c = getopt(argc, argv, "am:v:e:lcb:ipuhV")) != -1) {
switch (c) {
+ break;
+ case 'a':
+ options.anim = true;
+ break;
+
case 'm':
options.encode_mode = optarg[0];
break;
@@ -771,6 +777,10 @@ int main(int argc, char *argv[])
options.plain = true;
break;
+ case 'u':
+ options.unicode = true;
+ break;
+
case '?':
ret = 1;
goto exit;
@@ -785,7 +795,25 @@ int main(int argc, char *argv[])
}
}
- /* Validate options */
+ /* Validate and process CLI arguments */
+ while (optind < argc) {
+ if (argc - optind > 1) {
+ print_error("too many arguments");
+ fprintf(stderr, "%s" EOL, help_msg);
+ ret = 1;
+ goto exit;
+ }
+
+ // Ignore input provided via CLI when STDIN is available
+ if (!is_stdin_input) {
+ str = realloc(str, strlen(argv[optind]) + 1);
+ strcpy(str, argv[optind]);
+ }
+
+ optind++;
+ }
+
+ /* Validate given options */
if (
options.version < 0 || options.version > QRSPEC_VERSION_MAX ||
get_qr_ec_level(options.ec_level) < 0 ||
@@ -798,17 +826,28 @@ int main(int argc, char *argv[])
goto exit;
}
- /* Validate arguments */
- if (optind != argc) {
+ /* Process STDIN (if any) */
+ if (is_stdin_input) {
+ size_t buf_size = STDIN_CHUNKSIZE;
+ char buf[buf_size];
if (str != NULL) {
- print_error("too many arguments");
- fprintf(stderr, "%s" EOL, help_msg);
- ret = 1;
- goto exit;
+ free(str);
}
+ str = NULL;
+ ssize_t stdin_read_size = 0;
+ size_t total_bytes = 0;
- str = malloc(strlen(argv[optind])+1);
- memcpy(&str, &argv[optind], strlen(argv[optind])+1);
+ while ((stdin_read_size = read(STDIN_FILENO, buf, STDIN_CHUNKSIZE)) > 0) {
+ str = realloc(str, total_bytes + stdin_read_size + 1);
+ if (str == NULL) {
+ print_error("out of memory");
+ ret = 1;
+ goto exit;
+ }
+ memcpy(&str[total_bytes], buf, stdin_read_size);
+ total_bytes += stdin_read_size;
+ }
+ str[total_bytes] = '\0';
}
/* Check input */
@@ -819,58 +858,143 @@ int main(int argc, char *argv[])
goto exit;
}
- /*******************************/
- /* Generate and output QR code */
- /*******************************/
-
- QRcode *qr;
-
- /* Ensure QR Code contains UTF-8 BOM */
- if (str_has_utf8_bom(str)) {
- qr = QRcode_encodeString(str, options.version,
- get_qr_ec_level(options.ec_level),
- get_qr_encode_mode(options.encode_mode), true);
- } else {
- char str_utf8[strlen(utf8_bom) + strlen(str) + 1];
- memset(str_utf8, '\0', sizeof(str_utf8));
- strncpy(str_utf8, utf8_bom, sizeof(str_utf8));
- strncat(str_utf8, str, sizeof(str_utf8));
- str_utf8[strlen(utf8_bom) + strlen(str)] = '\0';
- qr = QRcode_encodeString(str_utf8, options.version,
- get_qr_ec_level(options.ec_level),
- get_qr_encode_mode(options.encode_mode), true);
- }
-
- /* Bail out if unable to successfully execute QRcode_encodeString() */
- if (qr == NULL) {
- print_error("failed to generate QR code");
- ret = 1;
- goto exit;
- }
-
/* Enforce colorless output mode for non-terminal environments */
- if (!isatty(STDOUT_FILENO)) {
+ if (!is_term_output) {
options.plain = true;
}
- /* Convert QR code data into text */
- char *qr_code_text = qr_data_to_text(qr, options.border, options.invert,
- !options.plain, options.large,
- options.compact);
+ /* Ensure that input string contains UTF-8 BOM */
+ if (options.unicode && !is_utf8_string(str)) {
+ /* Prepend UTF-8 BOM */
+ str = realloc(str, strlen(utf8_bom) + strlen(str) + 1);
+ memmove(str + strlen(utf8_bom), str, strlen(str) + 1);
+ memcpy(str, utf8_bom, strlen(utf8_bom));
+ }
+
+ /*********************************/
+ /* */
+ /* Generate and output QR code */
+ /* */
+ /*********************************/
+
+ if (options.anim) {
+ // Determine amount of chunks (frames)
+ const int data_chunk_size = 100; // Max chunk size in bytes
+ size_t data_chunk_count = strlen(str) / data_chunk_size;
+ // Account for leftover error (if any)
+ if (data_chunk_count * data_chunk_size < strlen(str)) {
+ data_chunk_count++;
+ }
+ unsigned char data_chunk[data_chunk_size + 1];
+
+ while (true) {
+ for (size_t str_chunk_i = 0; str_chunk_i < data_chunk_count; str_chunk_i++) {
+ strncpy((char*)data_chunk, str + data_chunk_size * str_chunk_i, data_chunk_size + 1);
+ if (str_chunk_i == data_chunk_count - 1) {
+ /* Since the whole chunk gets converted into our QR code, let's wipe its tail */
+ // TODO
+ }
+ QRcode *qr = QRcode_encodeData(data_chunk_size, data_chunk,
+ options.version,
+ get_qr_ec_level(options.ec_level));
+ // get_qr_encode_mode(options.encode_mode),
+ // true);
+
+ int line_num_to_clear = qr->width + options.border * 2;
+ if (!options.large) {
+ // Small (default) and compact (-c) modes both use 2 blocks per line
+ line_num_to_clear /= 2;
+ // Account for trailing half-block line
+ line_num_to_clear += 1;
+ }
+ const int clear_str_len = strlen(CLR) * line_num_to_clear + 1;
+ char clear_str[clear_str_len + 1];
+ clear_str[0] = clear_str[clear_str_len] = '\0';
+ for (int j = 0, jlen = line_num_to_clear; j < jlen; j++) {
+ strcat(clear_str, CLR);
+ }
+
+ /* Bail out if unable to successfully execute QRcode_encodeString() */
+ if (qr == NULL) {
+ print_error("failed to generate QR code");
+ ret = 1;
+ goto exit;
+ }
+
+ /* Convert QR code data into text */
+ char *qr_code_text = qr_data_to_text(qr,
+ options.border,
+ options.invert,
+ !options.plain,
+ options.large,
+ options.compact);
+
+ /* Output QR code as text */
+ if (qr_code_text) {
+ printf("%s", qr_code_text);
+ } else {
+ print_error("failed to convert QR code data into text");
+ ret = 1;
+ }
+
+ QRcode_free(qr);
+
+ /* Clean up */
+ free(qr_code_text);
+
+ // Delay between frames (in mc)
+ if (is_term_output) {
+ // Hang it here if it's just one frame
+ while(data_chunk_count == 1);
+
+ // Small delay before wiping the current and showing next frame
+ msleep(100);
+
+ // Wipe previously printed QR code
+ printf("%s", clear_str);
+ }
+ }
- /* Output QR code as text */
- if (qr_code_text) {
- printf("%s", qr_code_text);
+ // Only one iteration if outputting into a file
+ if (!is_term_output) {
+ break;
+ }
+ }
} else {
- print_error("failed to convert QR code data into text");
- ret = 1;
- }
+ QRcode *qr = QRcode_encodeString(str,
+ options.version,
+ get_qr_ec_level(options.ec_level),
+ get_qr_encode_mode(options.encode_mode),
+ true);
+
+ /* Bail out if unable to successfully execute QRcode_encodeString() */
+ if (qr == NULL) {
+ print_error("failed to generate QR code");
+ ret = 1;
+ goto exit;
+ }
+
+ /* Convert QR code data into text */
+ char *qr_code_text = qr_data_to_text(qr,
+ options.border,
+ options.invert,
+ !options.plain,
+ options.large,
+ options.compact);
+
+ /* Output QR code as text */
+ if (qr_code_text) {
+ printf("%s", qr_code_text);
+ } else {
+ print_error("failed to convert QR code data into text");
+ ret = 1;
+ }
- /* Clean up */
- if (qr != NULL) {
QRcode_free(qr);
+
+ /* Clean up */
+ free(qr_code_text);
}
- free(qr_code_text);
exit:
return ret;
diff --git a/tests.at b/tests.at
index 34f5767..2a83065 100644
--- a/tests.at
+++ b/tests.at
@@ -3,7 +3,7 @@ m4_define([AT_PACKAGE_STRING], [qr])
AT_INIT
AT_COLOR_TESTS
-AT_BANNER([QR-Code tests])
+AT_BANNER([Integration tests for qr])
## 1
AT_SETUP([generates proper QR Code])
@@ -15,76 +15,78 @@ AT_CLEANUP
## 2
AT_SETUP([generates proper QR Code using inverted colors])
AT_CHECK_UNQUOTED([
- convert -background white -fill black -font "${FONT}" -pointsize 9 -interline-spacing -1 label:"$(./../../qr -i "${INPUT}")" png:- | zbarimg -q png:- | grep -q "QR-Code:${INPUT}" || exit 1
+ convert -background white -fill black -font "$FONT" -pointsize 9 -interline-spacing -1 label:"$(./../../qr -i "$INPUT")" png:- | zbarimg -q png:- | grep -q "QR-Code:$INPUT" || exit 1
], [0], [], [])
AT_CLEANUP
## 3
AT_SETUP([generates proper QR Code using compact blocks])
AT_CHECK_UNQUOTED([
- convert -background black -fill white -font "${FONT}" -pointsize 9 -interline-spacing -1 label:"$(./../../qr -c "${INPUT}")" png:- | zbarimg -q png:- | grep -q "QR-Code:${INPUT}" || exit 1
+ convert -background black -fill white -font "$FONT" -pointsize 9 -interline-spacing -1 label:"$(./../../qr -c "$INPUT")" png:- | zbarimg -q png:- | grep -q "QR-Code:$INPUT" || exit 1
], [0], [], [])
AT_CLEANUP
## 4
AT_SETUP([generates proper QR Code using compact blocks and inverted colors])
AT_CHECK_UNQUOTED([
- convert -background white -fill black -font "${FONT}" -pointsize 9 -interline-spacing -1 label:"$(./../../qr -ci "${INPUT}")" png:- | zbarimg -q png:- | grep -q "QR-Code:${INPUT}" || exit 1
+ convert -background white -fill black -font "$FONT" -pointsize 9 -interline-spacing -1 label:"$(./../../qr -ci "$INPUT")" png:- | zbarimg -q png:- | grep -q "QR-Code:$INPUT" || exit 1
], [0], [], [])
AT_CLEANUP
## 5
AT_SETUP([generates proper QR Code using large blocks])
AT_CHECK_UNQUOTED([
- convert -background black -fill white -font "${FONT}" -pointsize 4 -interline-spacing -1 label:"$(./../../qr -l "${INPUT}")" png:- | zbarimg -q png:- | grep -q "QR-Code:${INPUT}" || exit 1
+ convert -background black -fill white -font "$FONT" -pointsize 4 -interline-spacing -1 label:"$(./../../qr -l "$INPUT")" png:- | zbarimg -q png:- | grep -q "QR-Code:$INPUT" || exit 1
], [0], [], [])
AT_CLEANUP
## 6
AT_SETUP([generates proper QR Code using large blocks and inverted colors])
AT_CHECK_UNQUOTED([
- convert -background white -fill black -font "${FONT}" -pointsize 4 -interline-spacing -1 label:"$(./../../qr -li "${INPUT}")" png:- | zbarimg -q png:- | grep -q "QR-Code:${INPUT}" || exit 1
+ convert -background white -fill black -font "$FONT" -pointsize 4 -interline-spacing -1 label:"$(./../../qr -li "$INPUT")" png:- | zbarimg -q png:- | grep -q "QR-Code:$INPUT" || exit 1
], [0], [], [])
AT_CLEANUP
## 7
AT_SETUP([generates proper QR Code using large compact blocks])
AT_CHECK_UNQUOTED([
- convert -background black -fill white -font "${FONT}" -pointsize 4 -interline-spacing -1 label:"$(./../../qr -lc "${INPUT}")" png:- | zbarimg -q png:- | grep -q "QR-Code:${INPUT}" || exit 1
+ convert -background black -fill white -font "$FONT" -pointsize 4 -interline-spacing -1 label:"$(./../../qr -lc "$INPUT")" png:- | zbarimg -q png:- | grep -q "QR-Code:$INPUT" || exit 1
], [0], [], [])
AT_CLEANUP
## 8
AT_SETUP([generates proper QR Code using large compact blocks and inverted colors])
AT_CHECK_UNQUOTED([
- convert -background white -fill black -font "${FONT}" -pointsize 9 -interline-spacing -1 label:"$(./../../qr -lci "${INPUT}")" png:- | zbarimg -q png:- | grep -q "QR-Code:${INPUT}" || exit 1
+ convert -background white -fill black -font "$FONT" -pointsize 9 -interline-spacing -1 label:"$(./../../qr -lci "$INPUT")" png:- | zbarimg -q png:- | grep -q "QR-Code:$INPUT" || exit 1
], [0], [], [])
AT_CLEANUP
## 9
AT_SETUP([generates proper QR Code with default settings using stdin])
AT_CHECK_UNQUOTED([
- convert -background black -fill white -font "${FONT}" -pointsize 9 -interline-spacing -1 label:"$(echo "${INPUT}" | ./../../qr)" png:- | zbarimg -q png:- | grep -q "QR-Code:${INPUT}" || exit 1
+ convert -background black -fill white -font "$FONT" -pointsize 9 -interline-spacing -1 label:"$(echo "$INPUT" | ./../../qr)" png:- | zbarimg -q png:- | grep -q "QR-Code:$INPUT" || exit 1
], [0], [], [])
AT_CLEANUP
## 10
AT_SETUP([fails to generate an empty QR Code])
-AT_CHECK_UNQUOTED([./../../qr ""], [1], [], [\
+AT_CHECK_UNQUOTED([../../qr ""], [1], [], [\
Error: no input specified
-Usage: qr [[OPTIONS]] STRING
+Usage: qr [[OPTIONS]] [[STRING]]
or: cat FILE | qr [[OPTIONS]]
Options:
+ -a produce animated QR code
-m QR mode [[na8k]] (n = number, a = alphabet, 8 = 8-bit, k = Kanji)
-v QR version [[1-40]]
-e QR EC level [[lmqh]] or [[1-4]]
- -l use two characters per block
+ -l large mode
-c compact mode
-b border width [[1-4]] (the default is 1)
-i invert colors
-p force colorless output
+ -u ensure output has UTF-8 BOM
-h print help info and exit
-V print version info and exit
@@ -96,18 +98,20 @@ AT_SETUP([fails and prints help information when no arguments provided])
AT_CHECK_UNQUOTED([./../../qr], [1], [], [\
Error: no input specified
-Usage: qr [[OPTIONS]] STRING
+Usage: qr [[OPTIONS]] [[STRING]]
or: cat FILE | qr [[OPTIONS]]
Options:
+ -a produce animated QR code
-m QR mode [[na8k]] (n = number, a = alphabet, 8 = 8-bit, k = Kanji)
-v QR version [[1-40]]
-e QR EC level [[lmqh]] or [[1-4]]
- -l use two characters per block
+ -l large mode
-c compact mode
-b border width [[1-4]] (the default is 1)
-i invert colors
-p force colorless output
+ -u ensure output has UTF-8 BOM
-h print help info and exit
-V print version info and exit
@@ -116,19 +120,21 @@ AT_CLEANUP
## 12
AT_SETUP([prints help information when help flag is set])
-AT_CHECK_UNQUOTED([./../../qr -h], [0], [\
-Usage: qr [[OPTIONS]] STRING
+AT_CHECK_UNQUOTED([../../qr -h], [0], [\
+Usage: qr [[OPTIONS]] [[STRING]]
or: cat FILE | qr [[OPTIONS]]
Options:
+ -a produce animated QR code
-m QR mode [[na8k]] (n = number, a = alphabet, 8 = 8-bit, k = Kanji)
-v QR version [[1-40]]
-e QR EC level [[lmqh]] or [[1-4]]
- -l use two characters per block
+ -l large mode
-c compact mode
-b border width [[1-4]] (the default is 1)
-i invert colors
-p force colorless output
+ -u ensure output has UTF-8 BOM
-h print help info and exit
-V print version info and exit
@@ -137,13 +143,13 @@ AT_CLEANUP
## 13
AT_SETUP([prints version informaton when version flag is set])
-AT_CHECK_UNQUOTED([./../../qr -V], [0], [qr 1.0.0
+AT_CHECK_UNQUOTED([../../qr -V], [0], [qr 2.0.0
], [])
AT_CLEANUP
## 14
AT_SETUP([fails if the input is too long])
-AT_CHECK_UNQUOTED([./../../qr "${EXTRA_LONG_INPUT}"], [1], [], [\
+AT_CHECK_UNQUOTED([../../qr "${EXTRA_LONG_INPUT}"], [1], [], [\
Error: failed to generate QR code
])
AT_CLEANUP