Merge remote-tracking branch 'refs/remotes/lz4/dev' into dev
This commit is contained in:
commit
5ae0e789fc
@ -130,7 +130,7 @@ matrix:
|
||||
packages:
|
||||
- clang
|
||||
|
||||
- env: Ubu=14.04 Cmd='make clean all CC=gcc-4.4 MOREFLAGS=-Werror' COMPILER=gcc-4.4
|
||||
- env: Ubu=14.04 Cmd='make clean all CC=gcc-4.4 MOREFLAGS=-Werror && make clean && CFLAGS=-fPIC LDFLAGS="-pie -fPIE -D_FORTIFY_SOURCE=2" make -C programs' COMPILER=gcc-4.4
|
||||
dist: trusty
|
||||
sudo: required
|
||||
addons:
|
||||
|
9
NEWS
9
NEWS
@ -1,7 +1,14 @@
|
||||
v1.7.5
|
||||
cli : fix minor notification when using -r recursive mode
|
||||
doc : markdown version of man page, by Takayuki Matsuoka
|
||||
|
||||
v1.7.4.2
|
||||
fix : Makefile : release build compatible with PIE and customized compilation directives provided through environment variables (#274, reported by Antoine Martin)
|
||||
|
||||
v1.7.4
|
||||
Improved : much better speed in -mx32 mode
|
||||
cli : fix : Large file support in 32-bits mode on Mac OS-X
|
||||
fix : compilation on gcc 4.4 (#282), reported by Antoine Martin
|
||||
fix : compilation on gcc 4.4 (#272), reported by Antoine Martin
|
||||
|
||||
v1.7.3
|
||||
Changed : moved to versioning; package, cli and library have same version number
|
||||
|
45
lib/Makefile
45
lib/Makefile
@ -38,23 +38,24 @@ LIBVER_SCRIPT:= $(LIBVER_MAJOR_SCRIPT).$(LIBVER_MINOR_SCRIPT).$(LIBVER_PATCH_SCR
|
||||
LIBVER_MAJOR := $(shell echo $(LIBVER_MAJOR_SCRIPT))
|
||||
LIBVER_MINOR := $(shell echo $(LIBVER_MINOR_SCRIPT))
|
||||
LIBVER_PATCH := $(shell echo $(LIBVER_PATCH_SCRIPT))
|
||||
LIBVER := $(shell echo $(LIBVER_SCRIPT))
|
||||
LIBVER := $(shell echo $(LIBVER_SCRIPT))
|
||||
|
||||
BUILD_STATIC:= yes
|
||||
|
||||
DESTDIR?=
|
||||
PREFIX ?= /usr/local
|
||||
CPPFLAGS= -DXXH_NAMESPACE=LZ4_
|
||||
CFLAGS ?= -O3
|
||||
CFLAGS += -g -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \
|
||||
-Wswitch-enum -Wdeclaration-after-statement -Wstrict-prototypes -Wundef \
|
||||
-Wpointer-arith -Wstrict-aliasing=1
|
||||
CFLAGS += $(MOREFLAGS)
|
||||
FLAGS = $(CPPFLAGS) $(CFLAGS) $(LDFLAGS)
|
||||
|
||||
LIBDIR?= $(PREFIX)/lib
|
||||
DESTDIR ?=
|
||||
PREFIX ?= /usr/local
|
||||
LIBDIR ?= $(PREFIX)/lib
|
||||
INCLUDEDIR=$(PREFIX)/include
|
||||
|
||||
CPPFLAGS+= -DXXH_NAMESPACE=LZ4_
|
||||
CFLAGS ?= -O3
|
||||
DEBUGFLAGS:=-g -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \
|
||||
-Wswitch-enum -Wdeclaration-after-statement -Wstrict-prototypes -Wundef \
|
||||
-Wpointer-arith -Wstrict-aliasing=1
|
||||
CFLAGS += $(MOREFLAGS)
|
||||
FLAGS = $(CPPFLAGS) $(CFLAGS) $(LDFLAGS)
|
||||
|
||||
|
||||
|
||||
# OS X linker doesn't support -soname, and use different extension
|
||||
# see : https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/DynamicLibraries/100-Articles/DynamicLibraryDesignGuidelines.html
|
||||
@ -72,20 +73,20 @@ endif
|
||||
|
||||
default: lib-release
|
||||
|
||||
lib-release: liblz4.a liblz4
|
||||
|
||||
lib: CFLAGS += $(DEBUGFLAGS)
|
||||
lib: lib-release
|
||||
|
||||
all: lib
|
||||
|
||||
all32: CFLAGS+=-m32
|
||||
all32: all
|
||||
|
||||
lib: liblz4.a liblz4
|
||||
|
||||
lib-release: CFLAGS := -O3
|
||||
lib-release: lib
|
||||
|
||||
liblz4.a: *.c
|
||||
ifeq ($(BUILD_STATIC),yes)
|
||||
@echo compiling static library
|
||||
@$(CC) $(FLAGS) -c $^
|
||||
@$(CC) $(CPPFLAGS) $(CFLAGS) -c $^
|
||||
@$(AR) rcs $@ *.o
|
||||
endif
|
||||
|
||||
@ -114,10 +115,10 @@ ifneq (,$(filter $(shell uname),Linux Darwin GNU/kFreeBSD GNU FreeBSD))
|
||||
liblz4.pc: liblz4.pc.in Makefile
|
||||
@echo creating pkgconfig
|
||||
@sed -e 's|@PREFIX@|$(PREFIX)|' \
|
||||
-e 's|@LIBDIR@|$(LIBDIR)|' \
|
||||
-e 's|@INCLUDEDIR@|$(INCLUDEDIR)|' \
|
||||
-e 's|@VERSION@|$(LIBVER)|' \
|
||||
$< >$@
|
||||
-e 's|@LIBDIR@|$(LIBDIR)|' \
|
||||
-e 's|@INCLUDEDIR@|$(INCLUDEDIR)|' \
|
||||
-e 's|@VERSION@|$(LIBVER)|' \
|
||||
$< >$@
|
||||
|
||||
install: lib liblz4.pc
|
||||
@install -d -m 755 $(DESTDIR)$(LIBDIR)/pkgconfig/ $(DESTDIR)$(INCLUDEDIR)/
|
||||
|
@ -391,6 +391,7 @@ typedef enum { full = 0, partial = 1 } earlyEnd_directive;
|
||||
* Local Utils
|
||||
**************************************/
|
||||
int LZ4_versionNumber (void) { return LZ4_VERSION_NUMBER; }
|
||||
const char* LZ4_versionString(void) { return LZ4_VERSION_STRING; }
|
||||
int LZ4_compressBound(int isize) { return LZ4_COMPRESSBOUND(isize); }
|
||||
int LZ4_sizeofState() { return LZ4_STREAMSIZE; }
|
||||
|
||||
|
@ -85,7 +85,7 @@ extern "C" {
|
||||
/*========== Version =========== */
|
||||
#define LZ4_VERSION_MAJOR 1 /* for breaking interface changes */
|
||||
#define LZ4_VERSION_MINOR 7 /* for new (non-breaking) interface capabilities */
|
||||
#define LZ4_VERSION_RELEASE 4 /* for tweaks, bug-fixes, or development */
|
||||
#define LZ4_VERSION_RELEASE 5 /* for tweaks, bug-fixes, or development */
|
||||
|
||||
#define LZ4_VERSION_NUMBER (LZ4_VERSION_MAJOR *100*100 + LZ4_VERSION_MINOR *100 + LZ4_VERSION_RELEASE)
|
||||
|
||||
|
@ -27,6 +27,17 @@
|
||||
# lz4c32: Same as lz4c, but forced to compile in 32-bits mode
|
||||
# ##########################################################################
|
||||
|
||||
# Version numbers
|
||||
LIBVER_SRC := ../lib/lz4.h
|
||||
LIBVER_MAJOR_SCRIPT:=`sed -n '/define LZ4_VERSION_MAJOR/s/.*[[:blank:]]\([0-9][0-9]*\).*/\1/p' < $(LIBVER_SRC)`
|
||||
LIBVER_MINOR_SCRIPT:=`sed -n '/define LZ4_VERSION_MINOR/s/.*[[:blank:]]\([0-9][0-9]*\).*/\1/p' < $(LIBVER_SRC)`
|
||||
LIBVER_PATCH_SCRIPT:=`sed -n '/define LZ4_VERSION_RELEASE/s/.*[[:blank:]]\([0-9][0-9]*\).*/\1/p' < $(LIBVER_SRC)`
|
||||
LIBVER_SCRIPT:= $(LIBVER_MAJOR_SCRIPT).$(LIBVER_MINOR_SCRIPT).$(LIBVER_PATCH_SCRIPT)
|
||||
LIBVER_MAJOR := $(shell echo $(LIBVER_MAJOR_SCRIPT))
|
||||
LIBVER_MINOR := $(shell echo $(LIBVER_MINOR_SCRIPT))
|
||||
LIBVER_PATCH := $(shell echo $(LIBVER_PATCH_SCRIPT))
|
||||
LIBVER := $(shell echo $(LIBVER_SCRIPT))
|
||||
|
||||
DESTDIR ?=
|
||||
PREFIX ?= /usr/local
|
||||
BINDIR := $(PREFIX)/bin
|
||||
@ -34,14 +45,18 @@ MANDIR := $(PREFIX)/share/man/man1
|
||||
LZ4DIR := ../lib
|
||||
VOID := /dev/null
|
||||
|
||||
CFLAGS ?= -O3 # allows custom optimization flags. For example : CFLAGS="-O2 -g" make
|
||||
CFLAGS += -g -Wall -Wextra -Wundef -Wcast-qual -Wcast-align -Wshadow \
|
||||
CPPFLAGS+= -I$(LZ4DIR) -DXXH_NAMESPACE=LZ4_
|
||||
CFLAGS ?= -O3
|
||||
DEBUGFLAGS:=-g -Wall -Wextra -Wundef -Wcast-qual -Wcast-align -Wshadow \
|
||||
-Wswitch-enum -Wdeclaration-after-statement -Wstrict-prototypes \
|
||||
-Wpointer-arith -Wstrict-aliasing=1
|
||||
-Wpointer-arith -Wstrict-aliasing=1
|
||||
CFLAGS += $(MOREFLAGS)
|
||||
CPPFLAGS:= -I$(LZ4DIR) -DXXH_NAMESPACE=LZ4_
|
||||
FLAGS = $(CFLAGS) $(CPPFLAGS) $(LDFLAGS)
|
||||
|
||||
LZ4_VERSION=$(LIBVER)
|
||||
MD2ROFF =ronn
|
||||
MD2ROFF_FLAGS = --roff --warnings --manual="User Commands" --organization="lz4 $(LZ4_VERSION)"
|
||||
|
||||
|
||||
# Define *.exe as extension for Windows systems
|
||||
ifneq (,$(filter Windows%,$(OS)))
|
||||
@ -54,17 +69,18 @@ endif
|
||||
|
||||
default: lz4-release
|
||||
|
||||
lz4-release: $(LZ4DIR)/lz4.o $(LZ4DIR)/lz4hc.o $(LZ4DIR)/lz4frame.o $(LZ4DIR)/xxhash.o bench.o lz4io.o lz4cli.o datagen.o
|
||||
$(CC) $(FLAGS) $^ -o lz4$(EXT)
|
||||
|
||||
all: lz4 lz4c
|
||||
|
||||
all32: CFLAGS+=-m32
|
||||
all32: all
|
||||
|
||||
lz4: $(LZ4DIR)/lz4.o $(LZ4DIR)/lz4hc.o $(LZ4DIR)/lz4frame.o $(LZ4DIR)/xxhash.o bench.o lz4io.o lz4cli.o datagen.o
|
||||
$(CC) $(FLAGS) $^ -o $@$(EXT)
|
||||
|
||||
lz4-release: CFLAGS := -O3
|
||||
lz4-release: lz4
|
||||
lz4: CFLAGS += $(DEBUGFLAGS)
|
||||
lz4: lz4-release
|
||||
|
||||
lz4c: CFLAGS += $(DEBUGFLAGS)
|
||||
lz4c : $(LZ4DIR)/lz4.o $(LZ4DIR)/lz4hc.o $(LZ4DIR)/lz4frame.o $(LZ4DIR)/xxhash.o bench.o lz4io.o lz4cli.c datagen.o
|
||||
$(CC) $(FLAGS) -DENABLE_LZ4C_LEGACY_OPTIONS $^ -o $@$(EXT)
|
||||
|
||||
@ -79,6 +95,18 @@ clean:
|
||||
@echo Cleaning completed
|
||||
|
||||
|
||||
lz4.1: lz4.1.md
|
||||
cat $^ | $(MD2ROFF) $(MD2ROFF_FLAGS) | sed -n '/^\.\\\".*/!p' > $@
|
||||
|
||||
man: lz4.1
|
||||
|
||||
clean-man:
|
||||
rm lz4.1
|
||||
|
||||
preview-man: clean-man man
|
||||
man ./lz4.1
|
||||
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#make install is validated only for Linux, OSX, kFreeBSD, Hurd and
|
||||
#FreeBSD targets
|
||||
|
389
programs/lz4.1
389
programs/lz4.1
@ -1,251 +1,206 @@
|
||||
\."
|
||||
\." lz4.1: This is a manual page for 'lz4' program. This file is part of the
|
||||
\." lz4 <http://www.lz4.org/> project.
|
||||
\." Author: Yann Collet
|
||||
\."
|
||||
.
|
||||
\." No hyphenation
|
||||
.hy 0
|
||||
.nr HY 0
|
||||
.TH "LZ4" "1" "November 2016" "lz4 1.7.4" "User Commands"
|
||||
.
|
||||
.TH lz4 "1" "2015-03-21" "lz4" "User Commands"
|
||||
.SH NAME
|
||||
\fBlz4, unlz4, lz4cat\fR \- Compress or decompress .lz4 files
|
||||
|
||||
.SH SYNOPSIS
|
||||
.TP 5
|
||||
\fBlz4\fR [\fBOPTIONS\fR] [-|INPUT-FILE] <OUTPUT-FILE>
|
||||
.PP
|
||||
.B unlz4
|
||||
is equivalent to
|
||||
.BR "lz4 \-d"
|
||||
.br
|
||||
.B lz4cat
|
||||
is equivalent to
|
||||
.BR "lz4 \-dcfm"
|
||||
.br
|
||||
.PP
|
||||
When writing scripts that need to decompress files,
|
||||
it is recommended to always use the name
|
||||
.B lz4
|
||||
with appropriate arguments
|
||||
.RB ( "lz4 \-d"
|
||||
or
|
||||
.BR "lz4 \-dc" )
|
||||
instead of the names
|
||||
.B unlz4
|
||||
and
|
||||
.BR lz4cat .
|
||||
|
||||
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
\fBlz4\fR is an extremely fast lossless compression algorithm,
|
||||
based on \fBbyte-aligned LZ77\fR family of compression scheme.
|
||||
\fBlz4\fR offers compression speeds of 400 MB/s per core, linearly scalable with multi-core CPUs.
|
||||
It features an extremely fast decoder, with speed in multiple GB/s per core,
|
||||
typically reaching RAM speed limit on multi-core systems.
|
||||
The native file format is the
|
||||
.B .lz4
|
||||
format.
|
||||
|
||||
.B lz4
|
||||
supports a command line syntax similar \fIbut not identical\fR to
|
||||
.BR gzip (1).
|
||||
Differences are :
|
||||
\fBlz4\fR preserves original files
|
||||
\fBlz4\fR compresses a single file by default (use \fB-m\fR for multiple files)
|
||||
\fBlz4 file1 file2\fR means : compress file1 \fIinto\fR file2
|
||||
When no destination name is provided, compressed file name receives a \fB.lz4\fR suffix
|
||||
When no destination name is provided, if \fBstdout\fR is \fInot\fR the console, it becomes the output (like a silent \fB-c\fR)
|
||||
Therefore \fBlz4 file > /dev/null\fR will not create \fBfile.lz4\fR
|
||||
\fBlz4 file\fR shows real-time statistics during compression (use \fB-q\fR to silent them)
|
||||
|
||||
Default behaviors can be modified by opt-in commands, described below.
|
||||
\fBlz4 --quiet --multiple\fR more closely mimics \fBgzip\fR behavior.
|
||||
|
||||
.SS "Concatenation of .lz4 files"
|
||||
It is possible to concatenate
|
||||
.B .lz4
|
||||
files as is.
|
||||
.B lz4
|
||||
will decompress such files as if they were a single
|
||||
.B .lz4
|
||||
file. For example:
|
||||
lz4 file1 > foo.lz4
|
||||
lz4 file2 >> foo.lz4
|
||||
then
|
||||
lz4cat foo.lz4
|
||||
is equivalent to :
|
||||
cat file1 file2
|
||||
|
||||
.PP
|
||||
|
||||
.SH OPTIONS
|
||||
.SH "NAME"
|
||||
\fBlz4\fR \- lz4, unlz4, lz4cat \- Compress or decompress \.lz4 files
|
||||
.
|
||||
.SH "SYNOPSIS"
|
||||
\fBlz4\fR [\fIOPTIONS\fR] [\-|INPUT\-FILE] \fIOUTPUT\-FILE\fR
|
||||
.
|
||||
.P
|
||||
\fBunlz4\fR is equivalent to \fBlz4 \-d\fR
|
||||
.
|
||||
.P
|
||||
\fBlz4cat\fR is equivalent to \fBlz4 \-dcfm\fR
|
||||
.
|
||||
.P
|
||||
When writing scripts that need to decompress files, it is recommended to always use the name \fBlz4\fR with appropriate arguments (\fBlz4 \-d\fR or \fBlz4 \-dc\fR) instead of the names \fBunlz4\fR and \fBlz4cat\fR\.
|
||||
.
|
||||
.SH "DESCRIPTION"
|
||||
\fBlz4\fR is an extremely fast lossless compression algorithm, based on \fBbyte\-aligned LZ77\fR family of compression scheme\. \fBlz4\fR offers compression speeds of 400 MB/s per core, linearly scalable with multi\-core CPUs\. It features an extremely fast decoder, with speed in multiple GB/s per core, typically reaching RAM speed limit on multi\-core systems\. The native file format is the \fB\.lz4\fR format\.
|
||||
.
|
||||
.SS "Difference between lz4 and gzip"
|
||||
\fBlz4\fR supports a command line syntax similar \fIbut not identical\fR to \fBgzip(1)\fR\. Differences are :
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
\fBlz4\fR preserves original files
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
\fBlz4\fR compresses a single file by default (see \fB\-m\fR for multiple files)
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
\fBlz4 file1 file2\fR means : compress file1 \fIinto\fR file2
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
\fBlz4\fR shows real\-time notification statistics during compression or decompression of a single file (use \fB\-q\fR to silent them)
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
If no destination name is provided, result is sent to \fBstdout\fR \fIexcept if stdout is the console\fR\.
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
If no destination name is provided, \fBand\fR if \fBstdout\fR is the console, \fBfile\fR is compressed into \fBfile\.lz4\fR\.
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
As a consequence of previous rules, note the following example : \fBlz4 file | consumer\fR sends compressed data to \fBconsumer\fR through \fBstdout\fR, hence it does \fInot\fR create any \fBfile\.lz4\fR\.
|
||||
.
|
||||
.IP "" 0
|
||||
.
|
||||
.P
|
||||
Default behaviors can be modified by opt\-in commands, detailed below\.
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
\fBlz4 \-m\fR makes it possible to provide multiple input filenames, which will be compressed into files using suffix \fB\.lz4\fR\. Progress notifications are also disabled by default\. This mode has a behavior which more closely mimics \fBgzip\fR command line, with the main difference being that source files are preserved by default\.
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
It\'s possible to opt\-in to erase source files on successful compression or decompression, using \fB\-\-rm\fR command\.
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
Consequently, \fBlz4 \-m \-\-rm\fR behaves the same as \fBgzip\fR\.
|
||||
.
|
||||
.IP "" 0
|
||||
.
|
||||
.SS "Concatenation of \.lz4 files"
|
||||
It is possible to concatenate \fB\.lz4\fR files as is\. \fBlz4\fR will decompress such files as if they were a single \fB\.lz4\fR file\. For example: lz4 file1 > foo\.lz4 lz4 file2 >> foo\.lz4
|
||||
.
|
||||
.P
|
||||
then lz4cat foo\.lz4
|
||||
.
|
||||
.P
|
||||
is equivalent to : cat file1 file2
|
||||
.
|
||||
.SH "OPTIONS"
|
||||
.
|
||||
.SS "Short commands concatenation"
|
||||
In some cases, some options can be expressed using short command
|
||||
.B "-x"
|
||||
or long command
|
||||
.B "--long-word" .
|
||||
Short commands can be concatenated together. For example,
|
||||
.B "-d -c"
|
||||
is equivalent to
|
||||
.B "-dc" .
|
||||
Long commands cannot be concatenated.
|
||||
They must be clearly separated by a space.
|
||||
In some cases, some options can be expressed using short command \fB\-x\fR or long command \fB\-\-long\-word\fR\. Short commands can be concatenated together\. For example, \fB\-d \-c\fR is equivalent to \fB\-dc\fR\. Long commands cannot be concatenated\. They must be clearly separated by a space\.
|
||||
.
|
||||
.SS "Multiple commands"
|
||||
When multiple contradictory commands are issued on a same command line,
|
||||
only the latest one will be applied.
|
||||
When multiple contradictory commands are issued on a same command line, only the latest one will be applied\.
|
||||
.
|
||||
.SS "Operation mode"
|
||||
.
|
||||
.TP
|
||||
.BR \-z ", " \-\-compress
|
||||
Compress.
|
||||
This is the default operation mode
|
||||
when no operation mode option is specified ,
|
||||
no other operation mode is implied from the command name
|
||||
(for example,
|
||||
.B unlz4
|
||||
implies
|
||||
.B \-\-decompress ),
|
||||
nor from the input file name
|
||||
(for example, a file extension
|
||||
.B .lz4
|
||||
implies
|
||||
.B \-\-decompress
|
||||
by default).
|
||||
.B -z
|
||||
can also be used to force compression of an already compressed
|
||||
.B .lz4
|
||||
file.
|
||||
\fB\-z\fR \fB\-\-compress\fR
|
||||
Compress\. This is the default operation mode when no operation mode option is specified, no other operation mode is implied from the command name (for example, \fBunlz4\fR implies \fB\-\-decompress\fR), nor from the input file name (for example, a file extension \fB\.lz4\fR implies \fB\-\-decompress\fR by default)\. \fB\-z\fR can also be used to force compression of an already compressed \fB\.lz4\fR file\.
|
||||
.
|
||||
.TP
|
||||
.BR \-d ", " \-\-decompress ", " \-\-uncompress
|
||||
Decompress.
|
||||
.B --decompress
|
||||
is also the default operation when the input filename has an
|
||||
.B .lz4
|
||||
extension.
|
||||
\fB\-d\fR \fB\-\-decompress\fR \fB\-\-uncompress\fR
|
||||
Decompress\. \fB\-\-decompress\fR is also the default operation when the input filename has an \fB\.lz4\fR extension\.
|
||||
.
|
||||
.TP
|
||||
.BR \-t ", " \-\-test
|
||||
Test the integrity of compressed
|
||||
.B .lz4
|
||||
files.
|
||||
The decompressed data is discarded.
|
||||
No files are created nor removed.
|
||||
|
||||
\fB\-t\fR \fB\-\-test\fR
|
||||
Test the integrity of compressed \fB\.lz4\fR files\. The decompressed data is discarded\. No files are created nor removed\.
|
||||
.
|
||||
.TP
|
||||
.BR \-b#
|
||||
Benchmark mode, using # compression level.
|
||||
|
||||
\fB\-b#\fR
|
||||
Benchmark mode, using \fB#\fR compression level\.
|
||||
.
|
||||
.SS "Operation modifiers"
|
||||
.TP
|
||||
.B \-#
|
||||
compression level, with # being any value from 1 to 16.
|
||||
Higher values trade compression speed for compression ratio.
|
||||
Values above 16 are considered the same as 16.
|
||||
Recommended values are 1 for fast compression (default), and 9 for high compression.
|
||||
Speed/compression trade-off will vary depending on data to compress.
|
||||
Decompression speed remains fast at all settings.
|
||||
|
||||
.TP
|
||||
.BR \-f ", " --[no-]force
|
||||
This option has several effects:
|
||||
.RS
|
||||
.IP \(bu 3
|
||||
If the target file already exists,
|
||||
overwrite it without prompting.
|
||||
.IP \(bu 3
|
||||
When used with
|
||||
.B \-\-decompress
|
||||
and
|
||||
.B lz4
|
||||
cannot recognize the type of the source file,
|
||||
copy the source file as is to standard output.
|
||||
This allows
|
||||
.B lz4cat
|
||||
.B \-\-force
|
||||
to be used like
|
||||
.BR cat (1)
|
||||
for files that have not been compressed with
|
||||
.BR lz4 .
|
||||
.RE
|
||||
|
||||
.TP
|
||||
.BR \-c ", " \--stdout ", " \--to-stdout
|
||||
force write to standard output, even if it is the console
|
||||
|
||||
.TP
|
||||
.BR \-m ", " \--multiple
|
||||
Multiple file names.
|
||||
By default, the second filename is used as the destination filename for the compressed file.
|
||||
With
|
||||
.B -m
|
||||
, it is possible to specify any number of input filenames. Each of them will be compressed
|
||||
independently, and the resulting name of each compressed file will be
|
||||
.B filename.lz4
|
||||
.
|
||||
|
||||
.TP
|
||||
.B \-B#
|
||||
block size [4-7](default : 7)
|
||||
B4= 64KB ; B5= 256KB ; B6= 1MB ; B7= 4MB
|
||||
\fB\-#\fR
|
||||
Compression level, with # being any value from 1 to 16\. Higher values trade compression speed for compression ratio\. Values above 16 are considered the same as 16\. Recommended values are 1 for fast compression (default), and 9 for high compression\. Speed/compression trade\-off will vary depending on data to compress\. Decompression speed remains fast at all settings\.
|
||||
.
|
||||
.TP
|
||||
.B \-BD
|
||||
block dependency (improves compression ratio on small blocks)
|
||||
\fB\-f\fR \fB\-\-[no\-]force\fR
|
||||
This option has several effects:
|
||||
.
|
||||
.IP
|
||||
If the target file already exists, overwrite it without prompting\.
|
||||
.
|
||||
.IP
|
||||
When used with \fB\-\-decompress\fR and \fBlz4\fR cannot recognize the type of the source file, copy the source file as is to standard output\. This allows \fBlz4cat \-\-force\fR to be used like \fBcat (1)\fR for files that have not been compressed with \fBlz4\fR\.
|
||||
.
|
||||
.TP
|
||||
.B \--[no-]frame-crc
|
||||
select frame checksum (default:enabled)
|
||||
\fB\-c\fR \fB\-\-stdout\fR \fB\-\-to\-stdout\fR
|
||||
Force write to standard output, even if it is the console\.
|
||||
.
|
||||
.TP
|
||||
.B \--[no-]content-size
|
||||
header includes original size (default:not present)
|
||||
Note : this option can only be activated when the original size can be determined,
|
||||
hence for a file. It won't work with unknown source size, such as stdin or pipe.
|
||||
\fB\-m\fR \fB\-\-multiple\fR
|
||||
Multiple input files\. Compressed file names will be appended a \fB\.lz4\fR suffix\. This mode also reduces notification level\. \fBlz4 \-m\fR has a behavior equivalent to \fBgzip \-k\fR (it preserves source files by default)\.
|
||||
.
|
||||
.TP
|
||||
.B \--[no-]sparse
|
||||
sparse mode support (default:enabled on file, disabled on stdout)
|
||||
\fB\-r\fR
|
||||
operate recursively on directories\. This mode also sets \fB\-m\fR (multiple input files)\.
|
||||
.
|
||||
.TP
|
||||
.B \-l
|
||||
use Legacy format (typically used for Linux Kernel compression)
|
||||
note : \fB-l\fR is not compatible with \fB-m\fR (\fB--multiple\fR)
|
||||
\fB\-B#\fR
|
||||
Block size [4\-7](default : 7)
|
||||
.
|
||||
.br
|
||||
\fB\-B4\fR= 64KB ; \fB\-B5\fR= 256KB ; \fB\-B6\fR= 1MB ; \fB\-B7\fR= 4MB
|
||||
.
|
||||
.TP
|
||||
\fB\-BD\fR
|
||||
Block Dependency (improves compression ratio on small blocks)
|
||||
.
|
||||
.TP
|
||||
\fB\-\-[no\-]frame\-crc\fR
|
||||
Select frame checksum (default:enabled)
|
||||
.
|
||||
.TP
|
||||
\fB\-\-[no\-]content\-size\fR
|
||||
Header includes original size (default:not present)
|
||||
.
|
||||
.br
|
||||
Note : this option can only be activated when the original size can be determined, hence for a file\. It won\'t work with unknown source size, such as stdin or pipe\.
|
||||
.
|
||||
.TP
|
||||
\fB\-\-[no\-]sparse\fR
|
||||
Sparse mode support (default:enabled on file, disabled on stdout)
|
||||
.
|
||||
.TP
|
||||
\fB\-l\fR
|
||||
Use Legacy format (typically for Linux Kernel compression)
|
||||
.
|
||||
.br
|
||||
Note : \fB\-l\fR is not compatible with \fB\-m\fR (\fB\-\-multiple\fR) nor \fB\-r\fR
|
||||
.
|
||||
.SS "Other options"
|
||||
.
|
||||
.TP
|
||||
.BR \-v ", " --verbose
|
||||
verbose mode
|
||||
\fB\-v\fR \fB\-\-verbose\fR
|
||||
Verbose mode
|
||||
.
|
||||
.TP
|
||||
.BR \-q ", " --quiet
|
||||
suppress warnings and real-time statistics; specify twice to suppress errors too
|
||||
\fB\-q\fR \fB\-\-quiet\fR
|
||||
Suppress warnings and real\-time statistics; specify twice to suppress errors too
|
||||
.
|
||||
.TP
|
||||
.B \-h/\-H ", " --help
|
||||
display help/long help and exit
|
||||
\fB\-h\fR \fB\-H\fR \fB\-\-help\fR
|
||||
Display help/long help and exit
|
||||
.
|
||||
.TP
|
||||
.BR \-V ", " \--version
|
||||
display Version number and exit
|
||||
\fB\-V\fR \fB\-\-version\fR
|
||||
Display Version number and exit
|
||||
.
|
||||
.TP
|
||||
.BR \-k ", " \--keep
|
||||
Don't delete source file.
|
||||
This is default behavior anyway, so this option is just for compatibility with gzip/xz.
|
||||
|
||||
\fB\-k\fR \fB\-\-keep\fR
|
||||
Preserve source files (default behavior)
|
||||
.
|
||||
.TP
|
||||
\fB\-\-rm\fR
|
||||
Delete source files on successful compression or decompression
|
||||
.
|
||||
.SS "Benchmark mode"
|
||||
.
|
||||
.TP
|
||||
.B \-b#
|
||||
benchmark file(s), using # compression level
|
||||
\fB\-b#\fR
|
||||
Benchmark file(s), using # compression level
|
||||
.
|
||||
.TP
|
||||
.B \-e#
|
||||
benchmark multiple compression levels, from b# to e# (included)
|
||||
\fB\-e#\fR
|
||||
Benchmark multiple compression levels, from b# to e# (included)
|
||||
.
|
||||
.TP
|
||||
.B \-i#
|
||||
minimum evaluation in seconds [1-9] (default : 3)
|
||||
\fB\-i#\fR
|
||||
Minimum evaluation in seconds [1\-9] (default : 3)
|
||||
.
|
||||
.TP
|
||||
.B \-r
|
||||
operate recursively on directories
|
||||
|
||||
|
||||
.SH BUGS
|
||||
Report bugs at: https://github.com/Cyan4973/lz4/issues
|
||||
|
||||
.SH AUTHOR
|
||||
\fB\-r\fR
|
||||
Operate recursively on directories
|
||||
.
|
||||
.SH "BUGS"
|
||||
Report bugs at: https://github\.com/lz4/lz4/issues
|
||||
.
|
||||
.SH "AUTHOR"
|
||||
Yann Collet
|
||||
|
217
programs/lz4.1.md
Normal file
217
programs/lz4.1.md
Normal file
@ -0,0 +1,217 @@
|
||||
lz4(1) -- lz4, unlz4, lz4cat - Compress or decompress .lz4 files
|
||||
================================================================
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
|
||||
`lz4` [*OPTIONS*] [-|INPUT-FILE] <OUTPUT-FILE>
|
||||
|
||||
`unlz4` is equivalent to `lz4 -d`
|
||||
|
||||
`lz4cat` is equivalent to `lz4 -dcfm`
|
||||
|
||||
When writing scripts that need to decompress files,
|
||||
it is recommended to always use the name `lz4` with appropriate arguments
|
||||
(`lz4 -d` or `lz4 -dc`) instead of the names `unlz4` and `lz4cat`.
|
||||
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
|
||||
`lz4` is an extremely fast lossless compression algorithm,
|
||||
based on **byte-aligned LZ77** family of compression scheme.
|
||||
`lz4` offers compression speeds of 400 MB/s per core, linearly scalable with
|
||||
multi-core CPUs.
|
||||
It features an extremely fast decoder, with speed in multiple GB/s per core,
|
||||
typically reaching RAM speed limit on multi-core systems.
|
||||
The native file format is the `.lz4` format.
|
||||
|
||||
### Difference between lz4 and gzip
|
||||
|
||||
`lz4` supports a command line syntax similar _but not identical_ to `gzip(1)`.
|
||||
Differences are :
|
||||
|
||||
* `lz4` preserves original files
|
||||
* `lz4` compresses a single file by default (see `-m` for multiple files)
|
||||
* `lz4 file1 file2` means : compress file1 _into_ file2
|
||||
* `lz4` shows real-time notification statistics
|
||||
during compression or decompression of a single file
|
||||
(use `-q` to silent them)
|
||||
* If no destination name is provided, result is sent to `stdout`
|
||||
_except if stdout is the console_.
|
||||
* If no destination name is provided, __and__ if `stdout` is the console,
|
||||
`file` is compressed into `file.lz4`.
|
||||
* As a consequence of previous rules, note the following example :
|
||||
`lz4 file | consumer` sends compressed data to `consumer` through `stdout`,
|
||||
hence it does _not_ create any `file.lz4`.
|
||||
|
||||
Default behaviors can be modified by opt-in commands, detailed below.
|
||||
|
||||
* `lz4 -m` makes it possible to provide multiple input filenames,
|
||||
which will be compressed into files using suffix `.lz4`.
|
||||
Progress notifications are also disabled by default.
|
||||
This mode has a behavior which more closely mimics `gzip` command line,
|
||||
with the main difference being that source files are preserved by default.
|
||||
* It's possible to opt-in to erase source files
|
||||
on successful compression or decompression, using `--rm` command.
|
||||
* Consequently, `lz4 -m --rm` behaves the same as `gzip`.
|
||||
|
||||
### Concatenation of .lz4 files
|
||||
|
||||
It is possible to concatenate `.lz4` files as is.
|
||||
`lz4` will decompress such files as if they were a single `.lz4` file.
|
||||
For example:
|
||||
lz4 file1 > foo.lz4
|
||||
lz4 file2 >> foo.lz4
|
||||
|
||||
then
|
||||
lz4cat foo.lz4
|
||||
|
||||
is equivalent to :
|
||||
cat file1 file2
|
||||
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
|
||||
### Short commands concatenation
|
||||
|
||||
In some cases, some options can be expressed using short command `-x`
|
||||
or long command `--long-word`.
|
||||
Short commands can be concatenated together.
|
||||
For example, `-d -c` is equivalent to `-dc`.
|
||||
Long commands cannot be concatenated.
|
||||
They must be clearly separated by a space.
|
||||
|
||||
### Multiple commands
|
||||
|
||||
When multiple contradictory commands are issued on a same command line,
|
||||
only the latest one will be applied.
|
||||
|
||||
### Operation mode
|
||||
|
||||
* `-z` `--compress`:
|
||||
Compress.
|
||||
This is the default operation mode when no operation mode option is
|
||||
specified, no other operation mode is implied from the command name
|
||||
(for example, `unlz4` implies `--decompress`),
|
||||
nor from the input file name
|
||||
(for example, a file extension `.lz4` implies `--decompress` by default).
|
||||
`-z` can also be used to force compression of an already compressed
|
||||
`.lz4` file.
|
||||
|
||||
* `-d` `--decompress` `--uncompress`:
|
||||
Decompress.
|
||||
`--decompress` is also the default operation when the input filename has an
|
||||
`.lz4` extension.
|
||||
|
||||
* `-t` `--test`:
|
||||
Test the integrity of compressed `.lz4` files.
|
||||
The decompressed data is discarded.
|
||||
No files are created nor removed.
|
||||
|
||||
* `-b#`:
|
||||
Benchmark mode, using `#` compression level.
|
||||
|
||||
### Operation modifiers
|
||||
|
||||
* `-#`:
|
||||
Compression level, with # being any value from 1 to 16.
|
||||
Higher values trade compression speed for compression ratio.
|
||||
Values above 16 are considered the same as 16.
|
||||
Recommended values are 1 for fast compression (default),
|
||||
and 9 for high compression.
|
||||
Speed/compression trade-off will vary depending on data to compress.
|
||||
Decompression speed remains fast at all settings.
|
||||
|
||||
* `-f` `--[no-]force`:
|
||||
This option has several effects:
|
||||
|
||||
If the target file already exists, overwrite it without prompting.
|
||||
|
||||
When used with `--decompress` and `lz4` cannot recognize the type of
|
||||
the source file, copy the source file as is to standard output.
|
||||
This allows `lz4cat --force` to be used like `cat (1)` for files
|
||||
that have not been compressed with `lz4`.
|
||||
|
||||
* `-c` `--stdout` `--to-stdout`:
|
||||
Force write to standard output, even if it is the console.
|
||||
|
||||
* `-m` `--multiple`:
|
||||
Multiple input files.
|
||||
Compressed file names will be appended a `.lz4` suffix.
|
||||
This mode also reduces notification level.
|
||||
`lz4 -m` has a behavior equivalent to `gzip -k`
|
||||
(it preserves source files by default).
|
||||
|
||||
* `-r` :
|
||||
operate recursively on directories.
|
||||
This mode also sets `-m` (multiple input files).
|
||||
|
||||
* `-B#`:
|
||||
Block size \[4-7\](default : 7)<br/>
|
||||
`-B4`= 64KB ; `-B5`= 256KB ; `-B6`= 1MB ; `-B7`= 4MB
|
||||
|
||||
* `-BD`:
|
||||
Block Dependency (improves compression ratio on small blocks)
|
||||
|
||||
* `--[no-]frame-crc`:
|
||||
Select frame checksum (default:enabled)
|
||||
|
||||
* `--[no-]content-size`:
|
||||
Header includes original size (default:not present)<br/>
|
||||
Note : this option can only be activated when the original size can be
|
||||
determined, hence for a file. It won't work with unknown source size,
|
||||
such as stdin or pipe.
|
||||
|
||||
* `--[no-]sparse`:
|
||||
Sparse mode support (default:enabled on file, disabled on stdout)
|
||||
|
||||
* `-l`:
|
||||
Use Legacy format (typically for Linux Kernel compression)<br/>
|
||||
Note : `-l` is not compatible with `-m` (`--multiple`) nor `-r`
|
||||
|
||||
### Other options
|
||||
|
||||
* `-v` `--verbose`:
|
||||
Verbose mode
|
||||
|
||||
* `-q` `--quiet`:
|
||||
Suppress warnings and real-time statistics;
|
||||
specify twice to suppress errors too
|
||||
|
||||
* `-h` `-H` `--help`:
|
||||
Display help/long help and exit
|
||||
|
||||
* `-V` `--version`:
|
||||
Display Version number and exit
|
||||
|
||||
* `-k` `--keep`:
|
||||
Preserve source files (default behavior)
|
||||
|
||||
* `--rm` :
|
||||
Delete source files on successful compression or decompression
|
||||
|
||||
|
||||
### Benchmark mode
|
||||
|
||||
* `-b#`:
|
||||
Benchmark file(s), using # compression level
|
||||
|
||||
* `-e#`:
|
||||
Benchmark multiple compression levels, from b# to e# (included)
|
||||
|
||||
* `-i#`:
|
||||
Minimum evaluation in seconds \[1-9\] (default : 3)
|
||||
|
||||
|
||||
BUGS
|
||||
----
|
||||
|
||||
Report bugs at: https://github.com/lz4/lz4/issues
|
||||
|
||||
|
||||
AUTHOR
|
||||
------
|
||||
|
||||
Yann Collet
|
@ -78,7 +78,7 @@
|
||||
******************************/
|
||||
#define COMPRESSOR_NAME "LZ4 command line interface"
|
||||
#define AUTHOR "Yann Collet"
|
||||
#define WELCOME_MESSAGE "*** %s %i-bits v%s, by %s ***\n", COMPRESSOR_NAME, (int)(sizeof(void*)*8), LZ4_VERSION_STRING, AUTHOR
|
||||
#define WELCOME_MESSAGE "*** %s %i-bits v%s, by %s ***\n", COMPRESSOR_NAME, (int)(sizeof(void*)*8), LZ4_versionString(), AUTHOR
|
||||
#define LZ4_EXTENSION ".lz4"
|
||||
#define LZ4CAT "lz4cat"
|
||||
#define UNLZ4 "unlz4"
|
||||
@ -129,19 +129,20 @@ int LZ4IO_compressFilename_Legacy(const char* input_filename, const char* output
|
||||
*****************************/
|
||||
static int usage(const char* exeName)
|
||||
{
|
||||
DISPLAY( "Usage :\n");
|
||||
DISPLAY( " %s [arg] [input] [output]\n", exeName);
|
||||
DISPLAY( "Usage : \n");
|
||||
DISPLAY( " %s [arg] [input] [output] \n", exeName);
|
||||
DISPLAY( "\n");
|
||||
DISPLAY( "input : a filename\n");
|
||||
DISPLAY( "input : a filename \n");
|
||||
DISPLAY( " with no FILE, or when FILE is - or %s, read standard input\n", stdinmark);
|
||||
DISPLAY( "Arguments :\n");
|
||||
DISPLAY( "Arguments : \n");
|
||||
DISPLAY( " -1 : Fast compression (default) \n");
|
||||
DISPLAY( " -9 : High compression \n");
|
||||
DISPLAY( " -d : decompression (default for %s extension)\n", LZ4_EXTENSION);
|
||||
DISPLAY( " -z : force compression\n");
|
||||
DISPLAY( " -z : force compression \n");
|
||||
DISPLAY( " -f : overwrite output without prompting \n");
|
||||
DISPLAY( " -k : preserve source files(s) (default) \n");
|
||||
DISPLAY( "--rm : remove source file(s) after successful de/compression \n");
|
||||
DISPLAY( " -h/-H : display help/long help and exit\n");
|
||||
DISPLAY( " -h/-H : display help/long help and exit \n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -151,33 +152,33 @@ static int usage_advanced(const char* exeName)
|
||||
usage(exeName);
|
||||
DISPLAY( "\n");
|
||||
DISPLAY( "Advanced arguments :\n");
|
||||
DISPLAY( " -V : display Version number and exit\n");
|
||||
DISPLAY( " -v : verbose mode\n");
|
||||
DISPLAY( " -V : display Version number and exit \n");
|
||||
DISPLAY( " -v : verbose mode \n");
|
||||
DISPLAY( " -q : suppress warnings; specify twice to suppress errors too\n");
|
||||
DISPLAY( " -c : force write to standard output, even if it is the console\n");
|
||||
DISPLAY( " -t : test compressed file integrity\n");
|
||||
DISPLAY( " -m : multiple input files (implies automatic output filenames)\n");
|
||||
#ifdef UTIL_HAS_CREATEFILELIST
|
||||
DISPLAY( " -r : operate recursively on directories (sets also -m)\n");
|
||||
DISPLAY( " -r : operate recursively on directories (sets also -m) \n");
|
||||
#endif
|
||||
DISPLAY( " -l : compress using Legacy format (Linux kernel compression)\n");
|
||||
DISPLAY( " -B# : Block size [4-7] (default : 7)\n");
|
||||
DISPLAY( " -BD : Block dependency (improve compression ratio)\n");
|
||||
DISPLAY( " -B# : Block size [4-7] (default : 7) \n");
|
||||
DISPLAY( " -BD : Block dependency (improve compression ratio) \n");
|
||||
/* DISPLAY( " -BX : enable block checksum (default:disabled)\n"); *//* Option currently inactive */
|
||||
DISPLAY( "--no-frame-crc : disable stream checksum (default:enabled)\n");
|
||||
DISPLAY( "--no-frame-crc : disable stream checksum (default:enabled) \n");
|
||||
DISPLAY( "--content-size : compressed frame includes original size (default:not present)\n");
|
||||
DISPLAY( "--[no-]sparse : sparse mode (default:enabled on file, disabled on stdout)\n");
|
||||
DISPLAY( "Benchmark arguments :\n");
|
||||
DISPLAY( "Benchmark arguments : \n");
|
||||
DISPLAY( " -b# : benchmark file(s), using # compression level (default : 1) \n");
|
||||
DISPLAY( " -e# : test all compression levels from -bX to # (default : 1)\n");
|
||||
DISPLAY( " -i# : minimum evaluation time in seconds (default : 3s)\n");
|
||||
DISPLAY( " -B# : cut file into independent blocks of size # bytes [32+]\n");
|
||||
DISPLAY( " or predefined block size [4-7] (default: 7)\n");
|
||||
DISPLAY( " -i# : minimum evaluation time in seconds (default : 3s) \n");
|
||||
DISPLAY( " -B# : cut file into independent blocks of size # bytes [32+] \n");
|
||||
DISPLAY( " or predefined block size [4-7] (default: 7) \n");
|
||||
#if defined(ENABLE_LZ4C_LEGACY_OPTIONS)
|
||||
DISPLAY( "Legacy arguments :\n");
|
||||
DISPLAY( " -c0 : fast compression\n");
|
||||
DISPLAY( " -c1 : high compression\n");
|
||||
DISPLAY( " -hc : high compression\n");
|
||||
DISPLAY( "Legacy arguments : \n");
|
||||
DISPLAY( " -c0 : fast compression \n");
|
||||
DISPLAY( " -c1 : high compression \n");
|
||||
DISPLAY( " -hc : high compression \n");
|
||||
DISPLAY( " -y : overwrite output without prompting \n");
|
||||
#endif /* ENABLE_LZ4C_LEGACY_OPTIONS */
|
||||
EXTENDED_HELP;
|
||||
@ -548,7 +549,7 @@ int main(int argc, const char** argv)
|
||||
}
|
||||
|
||||
/* No output filename ==> try to select one automatically (when possible) */
|
||||
while (!output_filename) {
|
||||
while ((!output_filename) && (multiple_inputs==0)) {
|
||||
if (!IS_CONSOLE(stdout)) { output_filename=stdoutmark; break; } /* Default to stdout whenever possible (i.e. not a console) */
|
||||
if (mode == om_auto) { /* auto-determine compression or decompression, based on file extension */
|
||||
size_t const inSize = strlen(input_filename);
|
||||
@ -583,6 +584,8 @@ int main(int argc, const char** argv)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!output_filename) output_filename = "*\\dummy^!//";
|
||||
|
||||
/* Check if output is defined as console; trigger an error in this case */
|
||||
if (!strcmp(output_filename,stdoutmark) && IS_CONSOLE(stdout) && !forceStdout) {
|
||||
DISPLAYLEVEL(1, "refusing to write to console without -c\n");
|
||||
|
@ -1102,7 +1102,7 @@ int main(int argc, const char** argv)
|
||||
}
|
||||
}
|
||||
|
||||
printf("Starting LZ4 fuzzer (%i-bits, v%s)\n", (int)(sizeof(size_t)*8), LZ4_VERSION_STRING);
|
||||
printf("Starting LZ4 fuzzer (%i-bits, v%s)\n", (int)(sizeof(size_t)*8), LZ4_versionString());
|
||||
|
||||
if (!seedset) {
|
||||
time_t const t = time(NULL);
|
||||
|
Loading…
Reference in New Issue
Block a user