mirror of
https://github.com/pdewacht/brlaser
synced 2025-04-20 01:56:45 +02:00
Compare commits
No commits in common. "master" and "v1" have entirely different histories.
39
.github/workflows/build.yml
vendored
39
.github/workflows/build.yml
vendored
@ -1,39 +0,0 @@
|
|||||||
name: build
|
|
||||||
on: [ push, pull_request ]
|
|
||||||
jobs:
|
|
||||||
linux:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
compiler: [ clang++, gcc++ ]
|
|
||||||
steps:
|
|
||||||
- name: Add repository
|
|
||||||
run: sudo apt-add-repository -y "ppa:ubuntu-toolchain-r/test"
|
|
||||||
- name: Install packages
|
|
||||||
run: sudo apt install libcups2-dev
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- name: Configure
|
|
||||||
run: cmake .
|
|
||||||
- name: Make
|
|
||||||
run: make
|
|
||||||
env:
|
|
||||||
CXX: ${{ matrix.compiler }}
|
|
||||||
- name: Run tests
|
|
||||||
run: make check
|
|
||||||
macos:
|
|
||||||
runs-on: macos-latest
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
compiler: [ clang++, gcc++ ]
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- name: Configure
|
|
||||||
run: cmake .
|
|
||||||
- name: Make
|
|
||||||
run: make
|
|
||||||
env:
|
|
||||||
CXX: ${{ matrix.compiler }}
|
|
||||||
- name: Run tests
|
|
||||||
run: make check
|
|
23
.gitignore
vendored
23
.gitignore
vendored
@ -1,2 +1,21 @@
|
|||||||
*~
|
#
|
||||||
build/
|
# Autotools
|
||||||
|
#
|
||||||
|
/Makefile
|
||||||
|
/Makefile.in
|
||||||
|
/aclocal.m4
|
||||||
|
/autom4te.cache
|
||||||
|
/build-aux
|
||||||
|
/config.*
|
||||||
|
/configure
|
||||||
|
/stamp-*
|
||||||
|
.deps/
|
||||||
|
.dirstamp
|
||||||
|
|
||||||
|
#
|
||||||
|
# Binaries
|
||||||
|
#
|
||||||
|
/rastertobrlaser
|
||||||
|
/brdecode
|
||||||
|
/brlaser.drv
|
||||||
|
*.o
|
||||||
|
140
CMakeLists.txt
140
CMakeLists.txt
@ -1,140 +0,0 @@
|
|||||||
cmake_minimum_required(VERSION 3.1)
|
|
||||||
project(brlaser CXX)
|
|
||||||
set(BRLASER_VERSION "6")
|
|
||||||
|
|
||||||
if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
|
||||||
message(STATUS "No build type selected, default to RelWithDebInfo")
|
|
||||||
set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING "Build type (default RelWithDebInfo)" FORCE)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
include(CMakePushCheckState)
|
|
||||||
include(CheckCXXCompilerFlag)
|
|
||||||
include(CheckIncludeFileCXX)
|
|
||||||
|
|
||||||
|
|
||||||
## Enable assertions for all builds
|
|
||||||
## (cmake by default sets NDEBUG for release builds)
|
|
||||||
|
|
||||||
foreach(var
|
|
||||||
CMAKE_CXX_FLAGS_RELEASE
|
|
||||||
CMAKE_CXX_FLAGS_RELWITHDEBINFO
|
|
||||||
CMAKE_CXX_FLAGS_MINSIZEREL)
|
|
||||||
string(REGEX REPLACE "(^| )[/-]D *NDEBUG($| )" " " "${var}" "${${var}}")
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
|
|
||||||
## Configure the compiler
|
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 11)
|
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
|
||||||
|
|
||||||
macro(extra_cxx_compiler_flag FLAG)
|
|
||||||
string(REGEX REPLACE "[^A-Za-z_0-9]" "_" SFLAG ${FLAG})
|
|
||||||
check_cxx_compiler_flag(${FLAG} COMPILER_SUPPORT_${SFLAG})
|
|
||||||
if(COMPILER_SUPPORT_${SFLAG})
|
|
||||||
set(EXTRA_CXX_FLAGS "${EXTRA_CXX_FLAGS} ${FLAG}")
|
|
||||||
endif()
|
|
||||||
endmacro(extra_cxx_compiler_flag)
|
|
||||||
|
|
||||||
# Compiler warnings
|
|
||||||
extra_cxx_compiler_flag("-Wall")
|
|
||||||
extra_cxx_compiler_flag("-Wno-missing-braces")
|
|
||||||
extra_cxx_compiler_flag("-Wdate-time")
|
|
||||||
# Some hardening flags
|
|
||||||
extra_cxx_compiler_flag("-fstack-protector-strong")
|
|
||||||
extra_cxx_compiler_flag("-Wformat")
|
|
||||||
extra_cxx_compiler_flag("-Wformat -Werror=format-security")
|
|
||||||
extra_cxx_compiler_flag("-D_FORTIFY_SOURCE=2")
|
|
||||||
# Enable the supported flags, but give priority to CXXFLAGS env var
|
|
||||||
set(CMAKE_CXX_FLAGS "${EXTRA_CXX_FLAGS} ${CMAKE_CXX_FLAGS}")
|
|
||||||
|
|
||||||
|
|
||||||
## Configure CUPS
|
|
||||||
|
|
||||||
find_program(CUPS_CONFIG NAMES cups-config)
|
|
||||||
if(NOT CUPS_CONFIG)
|
|
||||||
message(FATAL_ERROR "cups-config command not found. Are the CUPS development packages installed?")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(NOT CUPS_DATA_DIR)
|
|
||||||
execute_process(
|
|
||||||
COMMAND "${CUPS_CONFIG}" --datadir
|
|
||||||
OUTPUT_VARIABLE CUPS_DATA_DIR
|
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
|
||||||
endif()
|
|
||||||
if(NOT CUPS_SERVER_BIN)
|
|
||||||
execute_process(
|
|
||||||
COMMAND "${CUPS_CONFIG}" --serverbin
|
|
||||||
OUTPUT_VARIABLE CUPS_SERVER_BIN
|
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
|
||||||
endif()
|
|
||||||
if(NOT CUPS_CFLAGS)
|
|
||||||
execute_process(
|
|
||||||
COMMAND "${CUPS_CONFIG}" --cflags
|
|
||||||
OUTPUT_VARIABLE CUPS_CFLAGS
|
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
|
||||||
endif()
|
|
||||||
if(NOT CUPS_LDFLAGS)
|
|
||||||
execute_process(
|
|
||||||
COMMAND "${CUPS_CONFIG}" --ldflags
|
|
||||||
OUTPUT_VARIABLE CUPS_LDFLAGS
|
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
|
||||||
endif()
|
|
||||||
if(NOT CUPS_LIBS)
|
|
||||||
execute_process(
|
|
||||||
COMMAND "${CUPS_CONFIG}" --image --libs
|
|
||||||
OUTPUT_VARIABLE CUPS_LIBS
|
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
cmake_push_check_state()
|
|
||||||
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${CUPS_CFLAGS}")
|
|
||||||
check_include_file_cxx(cups/raster.h HAVE_CUPS_RASTER_H)
|
|
||||||
cmake_pop_check_state()
|
|
||||||
if(NOT HAVE_CUPS_RASTER_H)
|
|
||||||
message(SEND_ERROR "<cups/raster.h> header not found. Are the CUPS development packages installed?")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
||||||
## Build instructions
|
|
||||||
|
|
||||||
configure_file(
|
|
||||||
"${PROJECT_SOURCE_DIR}/brlaser.drv.in"
|
|
||||||
"${PROJECT_BINARY_DIR}/brlaser.drv")
|
|
||||||
|
|
||||||
configure_file(
|
|
||||||
"${PROJECT_SOURCE_DIR}/config.h.in"
|
|
||||||
"${PROJECT_BINARY_DIR}/config.h")
|
|
||||||
|
|
||||||
include_directories("${PROJECT_BINARY_DIR}")
|
|
||||||
|
|
||||||
add_executable(rastertobrlaser src/main.cc src/job.cc src/line.cc src/debug.cc)
|
|
||||||
target_compile_options(rastertobrlaser PRIVATE ${CUPS_CFLAGS})
|
|
||||||
target_link_libraries(rastertobrlaser ${CUPS_LIBS})
|
|
||||||
target_link_libraries(rastertobrlaser ${CUPS_LDFLAGS})
|
|
||||||
|
|
||||||
add_executable(brdecode EXCLUDE_FROM_ALL src/brdecode.cc)
|
|
||||||
add_executable(test_lest test/test_lest.cc)
|
|
||||||
add_executable(test_line test/test_line.cc src/line.cc)
|
|
||||||
add_executable(test_block test/test_block.cc)
|
|
||||||
add_executable(test_job test/test_job.cc src/job.cc src/line.cc)
|
|
||||||
|
|
||||||
enable_testing()
|
|
||||||
add_test(test_lest test_lest)
|
|
||||||
add_test(test_line test_line)
|
|
||||||
add_test(test_block test_block)
|
|
||||||
add_test(test_job test_job)
|
|
||||||
|
|
||||||
# Autotools-style "make check" command
|
|
||||||
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND})
|
|
||||||
add_dependencies(check test_lest test_line test_block test_job)
|
|
||||||
|
|
||||||
|
|
||||||
# Installation
|
|
||||||
|
|
||||||
install(
|
|
||||||
TARGETS rastertobrlaser
|
|
||||||
DESTINATION "${CUPS_SERVER_BIN}/filter")
|
|
||||||
install(
|
|
||||||
FILES "${PROJECT_BINARY_DIR}/brlaser.drv"
|
|
||||||
DESTINATION "${CUPS_DATA_DIR}/drv")
|
|
23
ChangeLog
23
ChangeLog
@ -1,23 +0,0 @@
|
|||||||
brlaser v6 (2019-09-22)
|
|
||||||
Added support for some more Brother HL-series printers. These printers
|
|
||||||
had glitched output in earlier releases.
|
|
||||||
|
|
||||||
brlaser v5 (2019-05-18)
|
|
||||||
Fixed problems with Brother HL-series printers in 600 dpi mode. Thanks
|
|
||||||
to Onno Kortmann for the fix.
|
|
||||||
Added several printers.
|
|
||||||
|
|
||||||
brlaser v4 (2018-02-25)
|
|
||||||
Added several printers.
|
|
||||||
Merged duplex printing support from @xc-racer99. Enabled for DCP-7065DN.
|
|
||||||
Switched to a CMake build system.
|
|
||||||
|
|
||||||
brlaser v3 (2014-07-07)
|
|
||||||
Added DCP-7065DN description.
|
|
||||||
|
|
||||||
brlaser v2 (2014-06-29)
|
|
||||||
Suppport compilation with GCC 4.6.
|
|
||||||
Add a basic test suite.
|
|
||||||
|
|
||||||
brlaser v1 (2013-12-30)
|
|
||||||
Initial release.
|
|
24
Makefile.am
Normal file
24
Makefile.am
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
ACLOCAL_AMFLAGS = -I m4
|
||||||
|
|
||||||
|
filter_PROGRAMS = rastertobrlaser
|
||||||
|
filterdir = $(CUPS_SERVERBIN)/filter
|
||||||
|
|
||||||
|
drv_DATA = brlaser.drv
|
||||||
|
drvdir = $(CUPS_DATADIR)/drv
|
||||||
|
|
||||||
|
noinst_PROGRAMS = brdecode
|
||||||
|
|
||||||
|
|
||||||
|
rastertobrlaser_SOURCES = \
|
||||||
|
src/main.cc \
|
||||||
|
src/debug.h \
|
||||||
|
src/debug.cc \
|
||||||
|
src/job.h \
|
||||||
|
src/job.cc \
|
||||||
|
src/line.h \
|
||||||
|
src/line.cc
|
||||||
|
rastertobrlaser_CPPFLAGS = $(CUPS_CFLAGS)
|
||||||
|
rastertobrlaser_LDADD = $(CUPS_LIBS)
|
||||||
|
|
||||||
|
brdecode_SOURCES = \
|
||||||
|
src/brdecode.cc
|
103
README.md
103
README.md
@ -1,98 +1,23 @@
|
|||||||
brlaser: Brother laser printer driver
|
"brlaser" Brother DCP-7030 printer driver
|
||||||
=====================================
|
=========================================
|
||||||
|
|
||||||
brlaser is a CUPS driver for Brother laser printers.
|
This is a driver for the Brother DCP-7030 laser printer. It might also
|
||||||
|
be worth trying if you have some other old Brother monochrome laser
|
||||||
|
printer.
|
||||||
|
|
||||||
Although most Brother printers support a standard printer language
|
Currently this printer is not supported by other free software
|
||||||
such as PCL or PostScript, not all do. If you have a monochrome
|
drivers. Ghostscript's hl1250 driver almost works, but has glitches
|
||||||
Brother laser printer (or multi-function device) and the other open
|
with some fonts. (That driver tries to use PCL emulation, but that
|
||||||
source drivers don't work, this one might help.
|
seems to be buggy on this printer. The proprietary driver never uses
|
||||||
|
that mode.)
|
||||||
|
|
||||||
This driver has been reported to work with these printers:
|
Brother provides a non-free x86-only driver.
|
||||||
|
|
||||||
* Brother DCP-1510 series
|
Requirements
|
||||||
* Brother DCP-1600 series
|
|
||||||
* Brother DCP-7030
|
|
||||||
* Brother DCP-7040
|
|
||||||
* Brother DCP-7055
|
|
||||||
* Brother DCP-7055W
|
|
||||||
* Brother DCP-7060D
|
|
||||||
* Brother DCP-7065DN
|
|
||||||
* Brother DCP-7080
|
|
||||||
* Brother DCP-L2500D series
|
|
||||||
* Brother DCP-L2520D series
|
|
||||||
* Brother DCP-L2520DW series
|
|
||||||
* Brother DCP-L2540DW series
|
|
||||||
* Brother HL-1110 series
|
|
||||||
* Brother HL-1200 series
|
|
||||||
* Brother HL-2030 series
|
|
||||||
* Brother HL-2140 series
|
|
||||||
* Brother HL-2220 series
|
|
||||||
* Brother HL-2270DW series
|
|
||||||
* Brother HL-5030 series
|
|
||||||
* Brother HL-L2300D series
|
|
||||||
* Brother HL-L2320D series
|
|
||||||
* Brother HL-L2340D series
|
|
||||||
* Brother HL-L2360D series
|
|
||||||
* Brother HL-L2375DW series
|
|
||||||
* Brother HL-L2390DW
|
|
||||||
* Brother MFC-1910W
|
|
||||||
* Brother MFC-7240
|
|
||||||
* Brother MFC-7360N
|
|
||||||
* Brother MFC-7365DN
|
|
||||||
* Brother MFC-7420
|
|
||||||
* Brother MFC-7460DN
|
|
||||||
* Brother MFC-7840W
|
|
||||||
* Brother MFC-L2710DW series
|
|
||||||
* Lenovo M7605D
|
|
||||||
|
|
||||||
|
|
||||||
Other printers
|
|
||||||
--------------
|
|
||||||
|
|
||||||
If your printer isn't included in the list above, just try selecting
|
|
||||||
any entry marked 'brlaser' and see if it works.
|
|
||||||
|
|
||||||
If it does, please create a new issue here in Github and include the
|
|
||||||
output of this command:
|
|
||||||
|
|
||||||
sudo lpinfo --include-schemes usb -l -v
|
|
||||||
|
|
||||||
Then I'll be able to add a proper entry for your printer.
|
|
||||||
|
|
||||||
|
|
||||||
Installation
|
|
||||||
------------
|
------------
|
||||||
|
|
||||||
Some operating systems already ship this driver. This is the case for
|
* CUPS: tested with version 1.6.
|
||||||
at least Debian, Gentoo, Ubuntu, Raspbian, openSUSE, NixOS, Arch Linux
|
* A C++11 compiler. A recent version of GCC or Clang will work.
|
||||||
and Guix.
|
|
||||||
Look for a package named `printer-driver-brlaser`.
|
|
||||||
|
|
||||||
You'll also need Ghostscript, in case that's not installed
|
|
||||||
automatically.
|
|
||||||
|
|
||||||
Once brlaser is installed, you can add your printer using the usual
|
|
||||||
CUPS interface.
|
|
||||||
|
|
||||||
|
|
||||||
Building from source
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
To compile brlaser you'll need CMake and the CUPS development packages
|
|
||||||
(libcups2-dev, libcupsimage2-dev or similar).
|
|
||||||
|
|
||||||
Get the code by cloning the git repo <!-- or downloading the [latest
|
|
||||||
release] -->. Compile and install with these commands:
|
|
||||||
|
|
||||||
cmake .
|
|
||||||
make
|
|
||||||
sudo make install
|
|
||||||
|
|
||||||
It might be needed to restart CUPS after this.
|
|
||||||
|
|
||||||
[latest release]: https://github.com/pdewacht/brlaser/releases/latest
|
|
||||||
|
|
||||||
|
|
||||||
Copyright
|
Copyright
|
||||||
---------
|
---------
|
||||||
|
15
autogen.sh
Executable file
15
autogen.sh
Executable file
@ -0,0 +1,15 @@
|
|||||||
|
#! /bin/sh
|
||||||
|
|
||||||
|
srcdir=`dirname "$0"`
|
||||||
|
test -z "$srcdir" && srcdir=.
|
||||||
|
|
||||||
|
ORIGDIR=`pwd`
|
||||||
|
cd "$srcdir"
|
||||||
|
|
||||||
|
autoreconf --force -v --install || exit 1
|
||||||
|
cd "$ORIGDIR" || exit $?
|
||||||
|
|
||||||
|
if test -z "$NOCONFIGURE"; then
|
||||||
|
exec "$srcdir"/configure "$@"
|
||||||
|
fi
|
||||||
|
|
269
brlaser.drv.in
269
brlaser.drv.in
@ -15,8 +15,6 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with brlaser. If not, see <http://www.gnu.org/licenses/>.
|
// along with brlaser. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#define USING "using @CMAKE_PROJECT_NAME@ v@BRLASER_VERSION@"
|
|
||||||
|
|
||||||
// Include standard font and media definitions
|
// Include standard font and media definitions
|
||||||
#include <font.defs>
|
#include <font.defs>
|
||||||
#include <media.defs>
|
#include <media.defs>
|
||||||
@ -26,7 +24,7 @@ Font *
|
|||||||
|
|
||||||
// Manufacturer and driver version.
|
// Manufacturer and driver version.
|
||||||
Manufacturer "Brother"
|
Manufacturer "Brother"
|
||||||
Version "@BRLASER_VERSION@"
|
Version @VERSION@
|
||||||
|
|
||||||
// Each filter provided by the driver...
|
// Each filter provided by the driver...
|
||||||
Filter application/vnd.cups-raster 33 rastertobrlaser
|
Filter application/vnd.cups-raster 33 rastertobrlaser
|
||||||
@ -35,9 +33,7 @@ Filter application/vnd.cups-raster 33 rastertobrlaser
|
|||||||
// The 1200dpi mode is weird: we need to send 1200x1200dpi raster
|
// The 1200dpi mode is weird: we need to send 1200x1200dpi raster
|
||||||
// data, but Brother only advertises 1200x600dpi. I wonder what
|
// data, but Brother only advertises 1200x600dpi. I wonder what
|
||||||
// is going on there.
|
// is going on there.
|
||||||
// The 300dpi mode is reportedly not supported on all printers, so
|
Resolution k 1 0 0 0 "300dpi/300 DPI"
|
||||||
// it's listed in individual printer blocks where we believe it works.
|
|
||||||
// Resolution k 1 0 0 0 "300dpi/300 DPI"
|
|
||||||
*Resolution k 1 0 0 0 "600dpi/600 DPI"
|
*Resolution k 1 0 0 0 "600dpi/600 DPI"
|
||||||
Resolution k 1 0 0 0 "1200dpi/1200HQ"
|
Resolution k 1 0 0 0 "1200dpi/1200HQ"
|
||||||
|
|
||||||
@ -50,7 +46,7 @@ MediaSize B5
|
|||||||
MediaSize B6
|
MediaSize B6
|
||||||
MediaSize EnvC5
|
MediaSize EnvC5
|
||||||
MediaSize EnvMonarch
|
MediaSize EnvMonarch
|
||||||
MediaSize EnvDL
|
MediaSize EnvPRC5
|
||||||
MediaSize Executive
|
MediaSize Executive
|
||||||
MediaSize Legal
|
MediaSize Legal
|
||||||
MediaSize Letter
|
MediaSize Letter
|
||||||
@ -79,266 +75,9 @@ Option "brlaserEconomode/Toner save mode" Boolean AnySetup 10
|
|||||||
Choice True/On "<</cupsInteger10 1>>setpagedevice"
|
Choice True/On "<</cupsInteger10 1>>setpagedevice"
|
||||||
|
|
||||||
|
|
||||||
{
|
|
||||||
ModelName "DCP-1510"
|
|
||||||
Attribute "NickName" "" "Brother DCP-1510 series, $USING"
|
|
||||||
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,XL2HB;MDL:DCP-1510 series;CLS:PRINTER;CID:Brother Laser Type1;"
|
|
||||||
Resolution k 1 0 0 0 "300dpi/300 DPI"
|
|
||||||
PCFileName "br1510.ppd"
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
ModelName "DCP-1600 series"
|
|
||||||
Attribute "NickName" "" "Brother DCP-1600 series, $USING"
|
|
||||||
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,XL2HB;MDL:DCP-1600 series;CLS:PRINTER;CID:Brother Laser Type1;"
|
|
||||||
PCFileName "br1600.ppd"
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
ModelName "DCP-7030"
|
ModelName "DCP-7030"
|
||||||
Attribute "NickName" "" "Brother DCP-7030, $USING"
|
Attribute "NickName" "" "Brother DCP-7030, using @PACKAGE@ v@VERSION@"
|
||||||
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,HBP;MDL:DCP-7030;CLS:PRINTER;"
|
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,HBP;MDL:DCP-7030;CLS:PRINTER;"
|
||||||
Resolution k 1 0 0 0 "300dpi/300 DPI"
|
|
||||||
PCFileName "br7030.ppd"
|
PCFileName "br7030.ppd"
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
|
||||||
ModelName "DCP-7040"
|
|
||||||
Attribute "NickName" "" "Brother DCP-7040, $USING"
|
|
||||||
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,HBP;MDL:DCP-7040;CLS:PRINTER;"
|
|
||||||
Resolution k 1 0 0 0 "300dpi/300 DPI"
|
|
||||||
PCFileName "br7040.ppd"
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
ModelName "DCP-7055"
|
|
||||||
Attribute "NickName" "" "Brother DCP-7055, $USING"
|
|
||||||
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,HBP;MDL:DCP-7055;CLS:PRINTER;CID:Brother Laser Type1;"
|
|
||||||
Resolution k 1 0 0 0 "300dpi/300 DPI"
|
|
||||||
PCFileName "br7055.ppd"
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
ModelName "DCP-7055W"
|
|
||||||
Attribute "NickName" "" "Brother DCP-7055W, $USING"
|
|
||||||
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,HBP;MDL:DCP-7055W;CLS:PRINTER;CID:Brother Laser Type1;"
|
|
||||||
Resolution k 1 0 0 0 "300dpi/300 DPI"
|
|
||||||
PCFileName "br7055w.ppd"
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
ModelName "DCP-7060D"
|
|
||||||
Attribute "NickName" "" "Brother DCP-7060D, $USING"
|
|
||||||
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,HBP;MDL:DCP-7060D;CLS:PRINTER;CID:Brother Laser Type1;"
|
|
||||||
Duplex rotated
|
|
||||||
PCFileName "br7060d.ppd"
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
ModelName "DCP-7065DN"
|
|
||||||
Attribute "NickName" "" "Brother DCP-7065DN, $USING"
|
|
||||||
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,HBP;MDL:DCP-7065DN;CLS:PRINTER;CID:Brother Laser Type1;"
|
|
||||||
Duplex rotated
|
|
||||||
PCFileName "br7065dn.ppd"
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
ModelName "DCP-7080"
|
|
||||||
Attribute "NickName" "" "Brother DCP-7080, $USING"
|
|
||||||
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,HBP;MDL:DCP-7080;CLS:PRINTER;CID:Brother Laser Type1;"
|
|
||||||
PCFileName "br7080.ppd"
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
ModelName "DCP-7080D"
|
|
||||||
Attribute "NickName" "" "Brother DCP-7080D, $USING"
|
|
||||||
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,HBP;MDL:DCP-7080D;CLS:PRINTER;CID:Brother Laser Type1;"
|
|
||||||
Duplex rotated
|
|
||||||
PCFileName "br7080d.ppd"
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
ModelName "DCP-L2500D"
|
|
||||||
Attribute "NickName" "" "Brother DCP-L2500D series, $USING"
|
|
||||||
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,HBP;MDL:DCP-L2500D series;CLS:PRINTER;CID:Brother Laser Type1;"
|
|
||||||
Duplex rotated
|
|
||||||
PCFileName "brl2500d.ppd"
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
ModelName "DCP-L2520D"
|
|
||||||
Attribute "NickName" "" "Brother DCP-L2520D series, $USING"
|
|
||||||
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,HBP;MDL:DCP-L2520D series;CLS:PRINTER;CID:Brother Laser Type1;"
|
|
||||||
Duplex rotated
|
|
||||||
PCFileName "brl2520d.ppd"
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
ModelName "DCP-L2520DW"
|
|
||||||
Attribute "NickName" "" "Brother DCP-L2520DW series, $USING"
|
|
||||||
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,HBP;MDL:DCP-L2520DW series;CLS:PRINTER;CID:Brother Laser Type1;"
|
|
||||||
Duplex rotated
|
|
||||||
PCFileName "brl2520dw.ppd"
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
ModelName "DCP-L2540DW"
|
|
||||||
Attribute "NickName" "" "Brother DCP-L2540DW series, $USING"
|
|
||||||
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,HBP;MDL:DCP-L2540DW series;CLS:PRINTER;CID:Brother Laser Type1;"
|
|
||||||
Duplex rotated
|
|
||||||
PCFileName "brl2540.ppd"
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
ModelName "HL-1110"
|
|
||||||
Attribute "NickName" "" "Brother HL-1110 series, $USING"
|
|
||||||
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,HBP;MDL:HL-1110 series;CLS:PRINTER;CID:Brother Laser Type3;"
|
|
||||||
Resolution k 1 0 0 0 "300dpi/300 DPI"
|
|
||||||
PCFileName "br1110.ppd"
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
ModelName "HL-1200"
|
|
||||||
Attribute "NickName" "" "Brother HL-1200 series, $USING"
|
|
||||||
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,HBP;MDL:HL-1200 series;CLS:PRINTER;CID:Brother Laser Type3;"
|
|
||||||
PCFileName "br1200.ppd"
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
ModelName "HL-2030 series"
|
|
||||||
Attribute "NickName" "" "Brother HL-2030 series, $USING"
|
|
||||||
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,HBP;MDL:HL-2030 series;CLS:PRINTER;"
|
|
||||||
PCFileName "br2030.ppd"
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
ModelName "HL-2140 series"
|
|
||||||
Attribute "NickName" "" "Brother HL-2140 series, $USING"
|
|
||||||
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,HBP;MDL:HL-2140 series;CLS:PRINTER;"
|
|
||||||
PCFileName "br2140.ppd"
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
ModelName "HL-2220 series"
|
|
||||||
Attribute "NickName" "" "Brother HL-2220 series, $USING"
|
|
||||||
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,HBP;MDL:HL-2220 series;CLS:PRINTER;"
|
|
||||||
PCFileName "br2220.ppd"
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
ModelName "HL-2270DW series"
|
|
||||||
Attribute "NickName" "" "Brother HL-2270DW series, $USING"
|
|
||||||
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,PCL,PCLXL;MDL:HL-2270DW series;CLS:PRINTER;CID:Brother Laser Type1;"
|
|
||||||
Resolution k 1 0 0 0 "300dpi/300 DPI"
|
|
||||||
Duplex rotated
|
|
||||||
PCFileName "br2270dw.ppd"
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
ModelName "HL-5030 series"
|
|
||||||
Attribute "NickName" "" "Brother HL-5030 series, $USING"
|
|
||||||
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,PCL;MDL:HL-5030 series;CLS:PRINTER;"
|
|
||||||
PCFileName "br5030.ppd"
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
ModelName "HL-L2300D"
|
|
||||||
Attribute "NickName" "" "Brother HL-L2300D series, $USING"
|
|
||||||
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,HBP;MDL:HL-L2300D series;CLS:PRINTER;CID:Brother Laser Type1;"
|
|
||||||
Duplex rotated
|
|
||||||
PCFileName "brl2300d.ppd"
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
ModelName "HL-L2320D"
|
|
||||||
Attribute "NickName" "" "Brother HL-L2320D series, $USING"
|
|
||||||
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,HBP;MDL:HL-L2320D series;CLS:PRINTER;CID:Brother Laser Type1;"
|
|
||||||
Duplex rotated
|
|
||||||
PCFileName "brl2320d.ppd"
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
ModelName "HL-L2340D"
|
|
||||||
Attribute "NickName" "" "Brother HL-L2340D series, $USING"
|
|
||||||
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,HBP,URF;MDL:HL-L2340D series;CLS:PRINTER;CID:Brother Laser Type1;URF:W8,CP1,IS4-1,MT1-3-4-5-8,OB10,PQ4,RS300-600,V1.3,DM1;"
|
|
||||||
Duplex rotated
|
|
||||||
PCFileName "brl2340d.ppd"
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
ModelName "HL-L2360D"
|
|
||||||
Attribute "NickName" "" "Brother HL-L2360D series, $USING"
|
|
||||||
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,PCL,PCLXL,URF;MDL:HL-L2360D series;CLS:PRINTER;CID:Brother Laser Type1;URF:W8,CP1,IS4-1,MT1-3-4-5-8,OB10,PQ4,RS300-600,V1.3,DM1;"
|
|
||||||
Duplex rotated
|
|
||||||
PCFileName "brl2360d.ppd"
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
ModelName "HL-L2375DW"
|
|
||||||
Attribute "NickName" "" "Brother HL-L2375DW series, $USING"
|
|
||||||
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,PCL,PCLXL,URF;MDL:HL-L2375DW series;CLS:PRINTER;CID:Brother Laser Type1;URF:W8,CP1,IS4-1,MT1-3-4-5-8,OB10,PQ3-4-5,RS300-600-1200,V1.4,DM1;"
|
|
||||||
Duplex rotated
|
|
||||||
PCFileName "brl2375w.ppd"
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
ModelName "HL-L2390DW"
|
|
||||||
Attribute "NickName" "" "Brother HL-L2390DW, $USING"
|
|
||||||
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,HBP,URF;MDL:HL-L2390DW;CLS:PRINTER;CID:Brother Laser Type1;URF:W8,CP1,IS4-1,MT1-3-4-5-8,OB10,PQ3-4-5,RS300-600-1200,V1.4,DM1;"
|
|
||||||
Duplex rotated
|
|
||||||
PCFileName "brl2390w.ppd"
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
ModelName "MFC-1910W"
|
|
||||||
Attribute "NickName" "" "Brother MFC-1910W, $USING"
|
|
||||||
Attribute "1284DeviceID" "" "MFG:Brother;MFG:Brother;CMD:PJL,HBP;MDL:MFC-1910W series;CLS:PRINTER;CID:Brother Laser Type1;"
|
|
||||||
PCFileName "br1910w.ppd"
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
ModelName "MFC-7240"
|
|
||||||
Attribute "NickName" "" "Brother MFC-7240, $USING"
|
|
||||||
Attribute "1284DeviceID" "" "MFG:Brother;MFG:Brother;CMD:PJL,HBP;MDL:MFC-7240;CLS:PRINTER;CID:Brother Laser Type1;"
|
|
||||||
PCFileName "br7240.ppd"
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
ModelName "MFC-7360N"
|
|
||||||
Attribute "NickName" "" "Brother MFC-7360N, $USING"
|
|
||||||
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,HBP;MDL:MFC-7360N;CLS:PRINTER;CID:Brother Laser Type1;"
|
|
||||||
PCFileName "br7360n.ppd"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
{
|
|
||||||
ModelName "MFC-7365DN"
|
|
||||||
Attribute "NickName" "" "Brother MFC-7365DN, $USING"
|
|
||||||
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,HBP;MDL:MFC-7365DN;CLS:PRINTER;CID:Brother Laser Type1;"
|
|
||||||
Resolution k 1 0 0 0 "300dpi/300 DPI"
|
|
||||||
Duplex rotated
|
|
||||||
PCFileName "br7365dn.ppd"
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
ModelName "MFC-7420"
|
|
||||||
Attribute "NickName" "" "Brother Brother MFC-7420, $USING"
|
|
||||||
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,HBP;MDL:MFC-7420;CLS:PRINTER;"
|
|
||||||
PCFileName "br7420.ppd"
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
ModelName "MFC-7460DN"
|
|
||||||
Attribute "NickName" "" "Brother MFC-7460DN, $USING"
|
|
||||||
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,HBP;MDL:MFC-7460DN;CLS:PRINTER;CID:Brother Laser Type1;"
|
|
||||||
Duplex rotated
|
|
||||||
PCFileName "br7460dn.ppd"
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
ModelName "MFC-L2710DW series"
|
|
||||||
Attribute "NickName" "" "Brother MFC-L2710DW series, $USING"
|
|
||||||
Attribute "1284DeviceID" "" "MFG:Brother;CMD:PJL,HBP,URF;MDL:MFC-L2710DW series;CLS:PRINTER;CID:Brother Laser Type1;URF:W8,CP1,IS4-1,MT1-3-4-5-8,OB10,PQ3-4-5,RS300-600-1200,V1.4,DM1;"
|
|
||||||
Duplex rotated
|
|
||||||
PCFileName "brl2710.ppd"
|
|
||||||
}
|
|
||||||
|
@ -1,2 +0,0 @@
|
|||||||
#define PACKAGE "@CMAKE_PROJECT_NAME@"
|
|
||||||
#define VERSION "@BRLASER_VERSION@"
|
|
57
configure.ac
Normal file
57
configure.ac
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
# This file is part of the brlaser printer driver.
|
||||||
|
#
|
||||||
|
# Copyright 2013 Peter De Wachter
|
||||||
|
#
|
||||||
|
# brlaser is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# brlaser is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with brlaser. If not, see <http:#www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
AC_PREREQ(2.68)
|
||||||
|
AC_INIT([brlaser], [1], [pdewacht@gmail.com], [brlaser],
|
||||||
|
[https://github.com/pdewacht/brlaser])
|
||||||
|
|
||||||
|
AC_CONFIG_SRCDIR([src/line.cc])
|
||||||
|
AC_CONFIG_MACRO_DIR([m4])
|
||||||
|
AC_CONFIG_AUX_DIR([build-aux])
|
||||||
|
AC_LANG([C++])
|
||||||
|
|
||||||
|
AM_INIT_AUTOMAKE([1.11.1 foreign subdir-objects dist-xz -Wall -Werror])
|
||||||
|
AM_MAINTAINER_MODE([enable])
|
||||||
|
AM_SILENT_RULES([yes])
|
||||||
|
|
||||||
|
AC_PROG_CXX
|
||||||
|
AX_CXX_COMPILE_STDCXX_11
|
||||||
|
AX_CXXFLAGS_WARN_ALL
|
||||||
|
|
||||||
|
dnl Use cups-config to detect the CUPS configuration.
|
||||||
|
AC_PATH_PROG(CUPS_CONFIG, cups-config)
|
||||||
|
AS_IF([test -z "$CUPS_CONFIG"],
|
||||||
|
[AC_MSG_ERROR(["cups-config" command not found. Please install the CUPS development package.])])
|
||||||
|
CUPS_CFLAGS=`"$CUPS_CONFIG" --cflags`
|
||||||
|
CUPS_LIBS=`"$CUPS_CONFIG" --image --libs`
|
||||||
|
CUPS_SERVERBIN=`"$CUPS_CONFIG" --serverbin`
|
||||||
|
CUPS_DATADIR=`"$CUPS_CONFIG" --datadir`
|
||||||
|
AC_SUBST(CUPS_CFLAGS)
|
||||||
|
AC_SUBST(CUPS_LIBS)
|
||||||
|
AC_SUBST(CUPS_SERVERBIN)
|
||||||
|
AC_SUBST(CUPS_DATADIR)
|
||||||
|
|
||||||
|
dnl 'cups-config --libs' lists a lot of libs we don't need/want,
|
||||||
|
dnl try to figure out whether the linker knows about --as-needed.
|
||||||
|
AC_ARG_ENABLE([as-needed],
|
||||||
|
AC_HELP_STRING([--disable-as-needed], [disable overlinking protection]))
|
||||||
|
AS_IF([test "x$enable_as_needed" != "xno"],
|
||||||
|
[AX_APPEND_LINK_FLAGS([-Wl,--as-needed])])
|
||||||
|
|
||||||
|
AC_CONFIG_HEADERS([config.h])
|
||||||
|
AC_CONFIG_FILES([Makefile brlaser.drv])
|
||||||
|
AC_OUTPUT
|
69
m4/ax_append_flag.m4
Normal file
69
m4/ax_append_flag.m4
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
# ===========================================================================
|
||||||
|
# http://www.gnu.org/software/autoconf-archive/ax_append_flag.html
|
||||||
|
# ===========================================================================
|
||||||
|
#
|
||||||
|
# SYNOPSIS
|
||||||
|
#
|
||||||
|
# AX_APPEND_FLAG(FLAG, [FLAGS-VARIABLE])
|
||||||
|
#
|
||||||
|
# DESCRIPTION
|
||||||
|
#
|
||||||
|
# FLAG is appended to the FLAGS-VARIABLE shell variable, with a space
|
||||||
|
# added in between.
|
||||||
|
#
|
||||||
|
# If FLAGS-VARIABLE is not specified, the current language's flags (e.g.
|
||||||
|
# CFLAGS) is used. FLAGS-VARIABLE is not changed if it already contains
|
||||||
|
# FLAG. If FLAGS-VARIABLE is unset in the shell, it is set to exactly
|
||||||
|
# FLAG.
|
||||||
|
#
|
||||||
|
# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION.
|
||||||
|
#
|
||||||
|
# LICENSE
|
||||||
|
#
|
||||||
|
# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
|
||||||
|
# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify it
|
||||||
|
# under the terms of the GNU General Public License as published by the
|
||||||
|
# Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
# option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful, but
|
||||||
|
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
# Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along
|
||||||
|
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
# As a special exception, the respective Autoconf Macro's copyright owner
|
||||||
|
# gives unlimited permission to copy, distribute and modify the configure
|
||||||
|
# scripts that are the output of Autoconf when processing the Macro. You
|
||||||
|
# need not follow the terms of the GNU General Public License when using
|
||||||
|
# or distributing such scripts, even though portions of the text of the
|
||||||
|
# Macro appear in them. The GNU General Public License (GPL) does govern
|
||||||
|
# all other use of the material that constitutes the Autoconf Macro.
|
||||||
|
#
|
||||||
|
# This special exception to the GPL applies to versions of the Autoconf
|
||||||
|
# Macro released by the Autoconf Archive. When you make and distribute a
|
||||||
|
# modified version of the Autoconf Macro, you may extend this special
|
||||||
|
# exception to the GPL to apply to your modified version as well.
|
||||||
|
|
||||||
|
#serial 2
|
||||||
|
|
||||||
|
AC_DEFUN([AX_APPEND_FLAG],
|
||||||
|
[AC_PREREQ(2.59)dnl for _AC_LANG_PREFIX
|
||||||
|
AS_VAR_PUSHDEF([FLAGS], [m4_default($2,_AC_LANG_PREFIX[FLAGS])])dnl
|
||||||
|
AS_VAR_SET_IF(FLAGS,
|
||||||
|
[case " AS_VAR_GET(FLAGS) " in
|
||||||
|
*" $1 "*)
|
||||||
|
AC_RUN_LOG([: FLAGS already contains $1])
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
AC_RUN_LOG([: FLAGS="$FLAGS $1"])
|
||||||
|
AS_VAR_SET(FLAGS, ["AS_VAR_GET(FLAGS) $1"])
|
||||||
|
;;
|
||||||
|
esac],
|
||||||
|
[AS_VAR_SET(FLAGS,["$1"])])
|
||||||
|
AS_VAR_POPDEF([FLAGS])dnl
|
||||||
|
])dnl AX_APPEND_FLAG
|
61
m4/ax_append_link_flags.m4
Normal file
61
m4/ax_append_link_flags.m4
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
# ===========================================================================
|
||||||
|
# http://www.gnu.org/software/autoconf-archive/ax_append_link_flags.html
|
||||||
|
# ===========================================================================
|
||||||
|
#
|
||||||
|
# SYNOPSIS
|
||||||
|
#
|
||||||
|
# AX_APPEND_LINK_FLAGS([FLAG1 FLAG2 ...], [FLAGS-VARIABLE], [EXTRA-FLAGS])
|
||||||
|
#
|
||||||
|
# DESCRIPTION
|
||||||
|
#
|
||||||
|
# For every FLAG1, FLAG2 it is checked whether the linker works with the
|
||||||
|
# flag. If it does, the flag is added FLAGS-VARIABLE
|
||||||
|
#
|
||||||
|
# If FLAGS-VARIABLE is not specified, the linker's flags (LDFLAGS) is
|
||||||
|
# used. During the check the flag is always added to the linker's flags.
|
||||||
|
#
|
||||||
|
# If EXTRA-FLAGS is defined, it is added to the linker's default flags
|
||||||
|
# when the check is done. The check is thus made with the flags: "LDFLAGS
|
||||||
|
# EXTRA-FLAGS FLAG". This can for example be used to force the linker to
|
||||||
|
# issue an error when a bad flag is given.
|
||||||
|
#
|
||||||
|
# NOTE: This macro depends on the AX_APPEND_FLAG and AX_CHECK_LINK_FLAG.
|
||||||
|
# Please keep this macro in sync with AX_APPEND_COMPILE_FLAGS.
|
||||||
|
#
|
||||||
|
# LICENSE
|
||||||
|
#
|
||||||
|
# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify it
|
||||||
|
# under the terms of the GNU General Public License as published by the
|
||||||
|
# Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
# option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful, but
|
||||||
|
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
# Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along
|
||||||
|
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
# As a special exception, the respective Autoconf Macro's copyright owner
|
||||||
|
# gives unlimited permission to copy, distribute and modify the configure
|
||||||
|
# scripts that are the output of Autoconf when processing the Macro. You
|
||||||
|
# need not follow the terms of the GNU General Public License when using
|
||||||
|
# or distributing such scripts, even though portions of the text of the
|
||||||
|
# Macro appear in them. The GNU General Public License (GPL) does govern
|
||||||
|
# all other use of the material that constitutes the Autoconf Macro.
|
||||||
|
#
|
||||||
|
# This special exception to the GPL applies to versions of the Autoconf
|
||||||
|
# Macro released by the Autoconf Archive. When you make and distribute a
|
||||||
|
# modified version of the Autoconf Macro, you may extend this special
|
||||||
|
# exception to the GPL to apply to your modified version as well.
|
||||||
|
|
||||||
|
#serial 2
|
||||||
|
|
||||||
|
AC_DEFUN([AX_APPEND_LINK_FLAGS],
|
||||||
|
[for flag in $1; do
|
||||||
|
AX_CHECK_LINK_FLAG([$flag], [AX_APPEND_FLAG([$flag], [m4_default([$2], [LDFLAGS])])], [], [$3])
|
||||||
|
done
|
||||||
|
])dnl AX_APPEND_LINK_FLAGS
|
122
m4/ax_cflags_warn_all.m4
Normal file
122
m4/ax_cflags_warn_all.m4
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
# ===========================================================================
|
||||||
|
# http://www.gnu.org/software/autoconf-archive/ax_cflags_warn_all.html
|
||||||
|
# ===========================================================================
|
||||||
|
#
|
||||||
|
# SYNOPSIS
|
||||||
|
#
|
||||||
|
# AX_CFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])]
|
||||||
|
# AX_CXXFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])]
|
||||||
|
# AX_FCFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])]
|
||||||
|
#
|
||||||
|
# DESCRIPTION
|
||||||
|
#
|
||||||
|
# Try to find a compiler option that enables most reasonable warnings.
|
||||||
|
#
|
||||||
|
# For the GNU compiler it will be -Wall (and -ansi -pedantic) The result
|
||||||
|
# is added to the shellvar being CFLAGS, CXXFLAGS, or FCFLAGS by default.
|
||||||
|
#
|
||||||
|
# Currently this macro knows about the GCC, Solaris, Digital Unix, AIX,
|
||||||
|
# HP-UX, IRIX, NEC SX-5 (Super-UX 10), Cray J90 (Unicos 10.0.0.8), and
|
||||||
|
# Intel compilers. For a given compiler, the Fortran flags are much more
|
||||||
|
# experimental than their C equivalents.
|
||||||
|
#
|
||||||
|
# - $1 shell-variable-to-add-to : CFLAGS, CXXFLAGS, or FCFLAGS
|
||||||
|
# - $2 add-value-if-not-found : nothing
|
||||||
|
# - $3 action-if-found : add value to shellvariable
|
||||||
|
# - $4 action-if-not-found : nothing
|
||||||
|
#
|
||||||
|
# NOTE: These macros depend on AX_APPEND_FLAG.
|
||||||
|
#
|
||||||
|
# LICENSE
|
||||||
|
#
|
||||||
|
# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
|
||||||
|
# Copyright (c) 2010 Rhys Ulerich <rhys.ulerich@gmail.com>
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify it
|
||||||
|
# under the terms of the GNU General Public License as published by the
|
||||||
|
# Free Software Foundation; either version 3 of the License, or (at your
|
||||||
|
# option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful, but
|
||||||
|
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
# Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along
|
||||||
|
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
# As a special exception, the respective Autoconf Macro's copyright owner
|
||||||
|
# gives unlimited permission to copy, distribute and modify the configure
|
||||||
|
# scripts that are the output of Autoconf when processing the Macro. You
|
||||||
|
# need not follow the terms of the GNU General Public License when using
|
||||||
|
# or distributing such scripts, even though portions of the text of the
|
||||||
|
# Macro appear in them. The GNU General Public License (GPL) does govern
|
||||||
|
# all other use of the material that constitutes the Autoconf Macro.
|
||||||
|
#
|
||||||
|
# This special exception to the GPL applies to versions of the Autoconf
|
||||||
|
# Macro released by the Autoconf Archive. When you make and distribute a
|
||||||
|
# modified version of the Autoconf Macro, you may extend this special
|
||||||
|
# exception to the GPL to apply to your modified version as well.
|
||||||
|
|
||||||
|
#serial 14
|
||||||
|
|
||||||
|
AC_DEFUN([AX_FLAGS_WARN_ALL],[dnl
|
||||||
|
AS_VAR_PUSHDEF([FLAGS],[_AC_LANG_PREFIX[]FLAGS])dnl
|
||||||
|
AS_VAR_PUSHDEF([VAR],[ac_cv_[]_AC_LANG_ABBREV[]flags_warn_all])dnl
|
||||||
|
AC_CACHE_CHECK([m4_ifval($1,$1,FLAGS) for maximum warnings],
|
||||||
|
VAR,[VAR="no, unknown"
|
||||||
|
ac_save_[]FLAGS="$[]FLAGS"
|
||||||
|
for ac_arg dnl
|
||||||
|
in "-warn all % -warn all" dnl Intel
|
||||||
|
"-pedantic % -Wall" dnl GCC
|
||||||
|
"-xstrconst % -v" dnl Solaris C
|
||||||
|
"-std1 % -verbose -w0 -warnprotos" dnl Digital Unix
|
||||||
|
"-qlanglvl=ansi % -qsrcmsg -qinfo=all:noppt:noppc:noobs:nocnd" dnl AIX
|
||||||
|
"-ansi -ansiE % -fullwarn" dnl IRIX
|
||||||
|
"+ESlit % +w1" dnl HP-UX C
|
||||||
|
"-Xc % -pvctl[,]fullmsg" dnl NEC SX-5 (Super-UX 10)
|
||||||
|
"-h conform % -h msglevel 2" dnl Cray C (Unicos)
|
||||||
|
#
|
||||||
|
do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'`
|
||||||
|
AC_COMPILE_IFELSE([AC_LANG_PROGRAM],
|
||||||
|
[VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break])
|
||||||
|
done
|
||||||
|
FLAGS="$ac_save_[]FLAGS"
|
||||||
|
])
|
||||||
|
AS_VAR_POPDEF([FLAGS])dnl
|
||||||
|
AC_REQUIRE([AX_APPEND_FLAG])
|
||||||
|
case ".$VAR" in
|
||||||
|
.ok|.ok,*) m4_ifvaln($3,$3) ;;
|
||||||
|
.|.no|.no,*) m4_default($4,[m4_ifval($2,[AX_APPEND_FLAG([$2], [$1])])]) ;;
|
||||||
|
*) m4_default($3,[AX_APPEND_FLAG([$VAR], [$1])]) ;;
|
||||||
|
esac
|
||||||
|
AS_VAR_POPDEF([VAR])dnl
|
||||||
|
])dnl AX_FLAGS_WARN_ALL
|
||||||
|
dnl implementation tactics:
|
||||||
|
dnl the for-argument contains a list of options. The first part of
|
||||||
|
dnl these does only exist to detect the compiler - usually it is
|
||||||
|
dnl a global option to enable -ansi or -extrawarnings. All other
|
||||||
|
dnl compilers will fail about it. That was needed since a lot of
|
||||||
|
dnl compilers will give false positives for some option-syntax
|
||||||
|
dnl like -Woption or -Xoption as they think of it is a pass-through
|
||||||
|
dnl to later compile stages or something. The "%" is used as a
|
||||||
|
dnl delimiter. A non-option comment can be given after "%%" marks
|
||||||
|
dnl which will be shown but not added to the respective C/CXXFLAGS.
|
||||||
|
|
||||||
|
AC_DEFUN([AX_CFLAGS_WARN_ALL],[dnl
|
||||||
|
AC_LANG_PUSH([C])
|
||||||
|
AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4])
|
||||||
|
AC_LANG_POP([C])
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN([AX_CXXFLAGS_WARN_ALL],[dnl
|
||||||
|
AC_LANG_PUSH([C++])
|
||||||
|
AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4])
|
||||||
|
AC_LANG_POP([C++])
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN([AX_FCFLAGS_WARN_ALL],[dnl
|
||||||
|
AC_LANG_PUSH([Fortran])
|
||||||
|
AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4])
|
||||||
|
AC_LANG_POP([Fortran])
|
||||||
|
])
|
73
m4/ax_check_link_flag.m4
Normal file
73
m4/ax_check_link_flag.m4
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
# ===========================================================================
|
||||||
|
# http://www.gnu.org/software/autoconf-archive/ax_check_link_flag.html
|
||||||
|
# ===========================================================================
|
||||||
|
#
|
||||||
|
# SYNOPSIS
|
||||||
|
#
|
||||||
|
# AX_CHECK_LINK_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT])
|
||||||
|
#
|
||||||
|
# DESCRIPTION
|
||||||
|
#
|
||||||
|
# Check whether the given FLAG works with the linker or gives an error.
|
||||||
|
# (Warnings, however, are ignored)
|
||||||
|
#
|
||||||
|
# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
|
||||||
|
# success/failure.
|
||||||
|
#
|
||||||
|
# If EXTRA-FLAGS is defined, it is added to the linker's default flags
|
||||||
|
# when the check is done. The check is thus made with the flags: "LDFLAGS
|
||||||
|
# EXTRA-FLAGS FLAG". This can for example be used to force the linker to
|
||||||
|
# issue an error when a bad flag is given.
|
||||||
|
#
|
||||||
|
# INPUT gives an alternative input source to AC_LINK_IFELSE.
|
||||||
|
#
|
||||||
|
# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
|
||||||
|
# macro in sync with AX_CHECK_{PREPROC,COMPILE}_FLAG.
|
||||||
|
#
|
||||||
|
# LICENSE
|
||||||
|
#
|
||||||
|
# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
|
||||||
|
# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify it
|
||||||
|
# under the terms of the GNU General Public License as published by the
|
||||||
|
# Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
# option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful, but
|
||||||
|
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
# Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along
|
||||||
|
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
# As a special exception, the respective Autoconf Macro's copyright owner
|
||||||
|
# gives unlimited permission to copy, distribute and modify the configure
|
||||||
|
# scripts that are the output of Autoconf when processing the Macro. You
|
||||||
|
# need not follow the terms of the GNU General Public License when using
|
||||||
|
# or distributing such scripts, even though portions of the text of the
|
||||||
|
# Macro appear in them. The GNU General Public License (GPL) does govern
|
||||||
|
# all other use of the material that constitutes the Autoconf Macro.
|
||||||
|
#
|
||||||
|
# This special exception to the GPL applies to versions of the Autoconf
|
||||||
|
# Macro released by the Autoconf Archive. When you make and distribute a
|
||||||
|
# modified version of the Autoconf Macro, you may extend this special
|
||||||
|
# exception to the GPL to apply to your modified version as well.
|
||||||
|
|
||||||
|
#serial 3
|
||||||
|
|
||||||
|
AC_DEFUN([AX_CHECK_LINK_FLAG],
|
||||||
|
[AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_ldflags_$4_$1])dnl
|
||||||
|
AC_CACHE_CHECK([whether the linker accepts $1], CACHEVAR, [
|
||||||
|
ax_check_save_flags=$LDFLAGS
|
||||||
|
LDFLAGS="$LDFLAGS $4 $1"
|
||||||
|
AC_LINK_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])],
|
||||||
|
[AS_VAR_SET(CACHEVAR,[yes])],
|
||||||
|
[AS_VAR_SET(CACHEVAR,[no])])
|
||||||
|
LDFLAGS=$ax_check_save_flags])
|
||||||
|
AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes],
|
||||||
|
[m4_default([$2], :)],
|
||||||
|
[m4_default([$3], :)])
|
||||||
|
AS_VAR_POPDEF([CACHEVAR])dnl
|
||||||
|
])dnl AX_CHECK_LINK_FLAGS
|
133
m4/ax_cxx_compile_stdcxx_11.m4
Normal file
133
m4/ax_cxx_compile_stdcxx_11.m4
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
# ============================================================================
|
||||||
|
# http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_11.html
|
||||||
|
# ============================================================================
|
||||||
|
#
|
||||||
|
# SYNOPSIS
|
||||||
|
#
|
||||||
|
# AX_CXX_COMPILE_STDCXX_11([ext|noext],[mandatory|optional])
|
||||||
|
#
|
||||||
|
# DESCRIPTION
|
||||||
|
#
|
||||||
|
# Check for baseline language coverage in the compiler for the C++11
|
||||||
|
# standard; if necessary, add switches to CXXFLAGS to enable support.
|
||||||
|
#
|
||||||
|
# The first argument, if specified, indicates whether you insist on an
|
||||||
|
# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g.
|
||||||
|
# -std=c++11). If neither is specified, you get whatever works, with
|
||||||
|
# preference for an extended mode.
|
||||||
|
#
|
||||||
|
# The second argument, if specified 'mandatory' or if left unspecified,
|
||||||
|
# indicates that baseline C++11 support is required and that the macro
|
||||||
|
# should error out if no mode with that support is found. If specified
|
||||||
|
# 'optional', then configuration proceeds regardless, after defining
|
||||||
|
# HAVE_CXX11 if and only if a supporting mode is found.
|
||||||
|
#
|
||||||
|
# LICENSE
|
||||||
|
#
|
||||||
|
# Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>
|
||||||
|
# Copyright (c) 2012 Zack Weinberg <zackw@panix.com>
|
||||||
|
# Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu>
|
||||||
|
#
|
||||||
|
# Copying and distribution of this file, with or without modification, are
|
||||||
|
# permitted in any medium without royalty provided the copyright notice
|
||||||
|
# and this notice are preserved. This file is offered as-is, without any
|
||||||
|
# warranty.
|
||||||
|
|
||||||
|
#serial 3
|
||||||
|
|
||||||
|
m4_define([_AX_CXX_COMPILE_STDCXX_11_testbody], [
|
||||||
|
template <typename T>
|
||||||
|
struct check
|
||||||
|
{
|
||||||
|
static_assert(sizeof(int) <= sizeof(T), "not big enough");
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef check<check<bool>> right_angle_brackets;
|
||||||
|
|
||||||
|
int a;
|
||||||
|
decltype(a) b;
|
||||||
|
|
||||||
|
typedef check<int> check_type;
|
||||||
|
check_type c;
|
||||||
|
check_type&& cr = static_cast<check_type&&>(c);
|
||||||
|
|
||||||
|
auto d = a;
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN([AX_CXX_COMPILE_STDCXX_11], [dnl
|
||||||
|
m4_if([$1], [], [],
|
||||||
|
[$1], [ext], [],
|
||||||
|
[$1], [noext], [],
|
||||||
|
[m4_fatal([invalid argument `$1' to AX_CXX_COMPILE_STDCXX_11])])dnl
|
||||||
|
m4_if([$2], [], [ax_cxx_compile_cxx11_required=true],
|
||||||
|
[$2], [mandatory], [ax_cxx_compile_cxx11_required=true],
|
||||||
|
[$2], [optional], [ax_cxx_compile_cxx11_required=false],
|
||||||
|
[m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX_11])])dnl
|
||||||
|
AC_LANG_PUSH([C++])dnl
|
||||||
|
ac_success=no
|
||||||
|
AC_CACHE_CHECK(whether $CXX supports C++11 features by default,
|
||||||
|
ax_cv_cxx_compile_cxx11,
|
||||||
|
[AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
|
||||||
|
[ax_cv_cxx_compile_cxx11=yes],
|
||||||
|
[ax_cv_cxx_compile_cxx11=no])])
|
||||||
|
if test x$ax_cv_cxx_compile_cxx11 = xyes; then
|
||||||
|
ac_success=yes
|
||||||
|
fi
|
||||||
|
|
||||||
|
m4_if([$1], [noext], [], [dnl
|
||||||
|
if test x$ac_success = xno; then
|
||||||
|
for switch in -std=gnu++11 -std=gnu++0x; do
|
||||||
|
cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch])
|
||||||
|
AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch,
|
||||||
|
$cachevar,
|
||||||
|
[ac_save_CXXFLAGS="$CXXFLAGS"
|
||||||
|
CXXFLAGS="$CXXFLAGS $switch"
|
||||||
|
AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
|
||||||
|
[eval $cachevar=yes],
|
||||||
|
[eval $cachevar=no])
|
||||||
|
CXXFLAGS="$ac_save_CXXFLAGS"])
|
||||||
|
if eval test x\$$cachevar = xyes; then
|
||||||
|
CXXFLAGS="$CXXFLAGS $switch"
|
||||||
|
ac_success=yes
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi])
|
||||||
|
|
||||||
|
m4_if([$1], [ext], [], [dnl
|
||||||
|
if test x$ac_success = xno; then
|
||||||
|
for switch in -std=c++11 -std=c++0x; do
|
||||||
|
cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch])
|
||||||
|
AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch,
|
||||||
|
$cachevar,
|
||||||
|
[ac_save_CXXFLAGS="$CXXFLAGS"
|
||||||
|
CXXFLAGS="$CXXFLAGS $switch"
|
||||||
|
AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
|
||||||
|
[eval $cachevar=yes],
|
||||||
|
[eval $cachevar=no])
|
||||||
|
CXXFLAGS="$ac_save_CXXFLAGS"])
|
||||||
|
if eval test x\$$cachevar = xyes; then
|
||||||
|
CXXFLAGS="$CXXFLAGS $switch"
|
||||||
|
ac_success=yes
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi])
|
||||||
|
AC_LANG_POP([C++])
|
||||||
|
if test x$ax_cxx_compile_cxx11_required = xtrue; then
|
||||||
|
if test x$ac_success = xno; then
|
||||||
|
AC_MSG_ERROR([*** A compiler with support for C++11 language features is required.])
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if test x$ac_success = xno; then
|
||||||
|
HAVE_CXX11=0
|
||||||
|
AC_MSG_NOTICE([No compiler with C++11 support was found])
|
||||||
|
else
|
||||||
|
HAVE_CXX11=1
|
||||||
|
AC_DEFINE(HAVE_CXX11,1,
|
||||||
|
[define if the compiler supports basic C++11 syntax])
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_SUBST(HAVE_CXX11)
|
||||||
|
fi
|
||||||
|
])
|
65
src/block.h
65
src/block.h
@ -1,65 +0,0 @@
|
|||||||
// This file is part of the brlaser printer driver.
|
|
||||||
//
|
|
||||||
// Copyright 2013 Peter De Wachter
|
|
||||||
//
|
|
||||||
// brlaser is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 2 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// brlaser is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with brlaser. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
#ifndef BLOCK_H
|
|
||||||
#define BLOCK_H
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
class block {
|
|
||||||
public:
|
|
||||||
block(): line_bytes_(0) {
|
|
||||||
}
|
|
||||||
|
|
||||||
bool empty() const {
|
|
||||||
return line_bytes_ == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void add_line(std::vector<uint8_t> &&line) {
|
|
||||||
assert(!line.empty());
|
|
||||||
assert(line_fits(line.size()));
|
|
||||||
line_bytes_ += line.size();
|
|
||||||
lines_.emplace_back(line);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool line_fits(unsigned size) {
|
|
||||||
return line_bytes_ + size < max_block_size_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void flush(FILE *f) {
|
|
||||||
if (!empty()) {
|
|
||||||
fprintf(f, "%dw%c%c",
|
|
||||||
line_bytes_ + 2, 0,
|
|
||||||
static_cast<int>(lines_.size()));
|
|
||||||
for (auto &line : lines_) {
|
|
||||||
fwrite(line.data(), 1, line.size(), f);
|
|
||||||
}
|
|
||||||
line_bytes_ = 0;
|
|
||||||
lines_.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
static const unsigned max_block_size_ = 16350;
|
|
||||||
|
|
||||||
std::vector<std::vector<uint8_t>> lines_;
|
|
||||||
int line_bytes_;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // BLOCK_H
|
|
@ -16,12 +16,10 @@
|
|||||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <exception>
|
#include <exception>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
@ -129,9 +127,9 @@ void read_line() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void read_block() {
|
void read_block() {
|
||||||
unsigned count = get();
|
uint8_t count = get();
|
||||||
count = count * 256 + get();
|
count = count * 256 + get();
|
||||||
for (unsigned i = 0; i < count; ++i) {
|
for (int i = 0; i < count; ++i) {
|
||||||
read_line();
|
read_line();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -144,6 +142,7 @@ bool read_page() {
|
|||||||
line.clear();
|
line.clear();
|
||||||
while ((ch = getc(in_file)) >= 0) {
|
while ((ch = getc(in_file)) >= 0) {
|
||||||
if (ch == '\f') {
|
if (ch == '\f') {
|
||||||
|
in_esc = false;
|
||||||
break;
|
break;
|
||||||
} else if (ch == 033) {
|
} else if (ch == 033) {
|
||||||
in_esc = true;
|
in_esc = true;
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with brlaser. If not, see <http://www.gnu.org/licenses/>.
|
// along with brlaser. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <typeinfo>
|
#include <typeinfo>
|
||||||
@ -24,12 +23,12 @@ namespace {
|
|||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void dump(const char *name, const T &value) {
|
void dump(const char *name, const T &value) {
|
||||||
std::cerr << "DEBUG: " PACKAGE ": page header: " << name << " = " << value << '\n';
|
std::cerr << "DEBUG: page header: " << name << " = " << value << '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, int N>
|
template <typename T, int N>
|
||||||
void dump(const char *name, const T (&value)[N]) {
|
void dump(const char *name, const T (&value)[N]) {
|
||||||
std::cerr << "DEBUG: " PACKAGE ": page header: " << name << " =";
|
std::cerr << "DEBUG: page header: " << name << " =";
|
||||||
for (int i = 0; i < N; ++i) {
|
for (int i = 0; i < N; ++i) {
|
||||||
std::cerr << ' ' << value[i];
|
std::cerr << ' ' << value[i];
|
||||||
}
|
}
|
||||||
@ -37,12 +36,12 @@ void dump(const char *name, const T (&value)[N]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void dump(const char *name, const char *value) {
|
void dump(const char *name, const char *value) {
|
||||||
std::cerr << "DEBUG: " PACKAGE ": page header: " << name << " = \"" << value << "\"\n";
|
std::cerr << "DEBUG: page header: " << name << " = \"" << value << "\"\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
template <int N, int M>
|
template <int N, int M>
|
||||||
void dump(const char *name, const char (&value)[N][M]) {
|
void dump(const char *name, const char (&value)[N][M]) {
|
||||||
std::cerr << "DEBUG: " PACKAGE ": page header: " << name << " =";
|
std::cerr << "DEBUG: page header: " << name << " =";
|
||||||
for (int i = 0; i < N; ++i) {
|
for (int i = 0; i < N; ++i) {
|
||||||
std::cerr << " \"" << value[i] << '"';
|
std::cerr << " \"" << value[i] << '"';
|
||||||
}
|
}
|
||||||
|
86
src/job.cc
86
src/job.cc
@ -20,24 +20,61 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "line.h"
|
#include "line.h"
|
||||||
#include "block.h"
|
|
||||||
|
|
||||||
|
using std::vector;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class block {
|
||||||
|
public:
|
||||||
|
void add_line(vector<uint8_t> &&line) {
|
||||||
|
assert(!line.empty());
|
||||||
|
line_bytes_ += line.size();
|
||||||
|
lines_.push_back(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool line_fits(unsigned size) {
|
||||||
|
return lines_.size() != max_lines_per_block_
|
||||||
|
&& line_bytes_ + size < max_block_size_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void flush(FILE *f) {
|
||||||
|
if (line_bytes_) {
|
||||||
|
fprintf(f, "%dw%c%c",
|
||||||
|
line_bytes_ + 2, 0,
|
||||||
|
static_cast<int>(lines_.size()));
|
||||||
|
for (auto &line : lines_) {
|
||||||
|
fwrite(line.data(), 1, line.size(), f);
|
||||||
|
}
|
||||||
|
line_bytes_ = 0;
|
||||||
|
lines_.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const unsigned max_block_size_ = 16350;
|
||||||
|
const unsigned max_lines_per_block_ = 128;
|
||||||
|
|
||||||
|
vector<vector<uint8_t>> lines_;
|
||||||
|
int line_bytes_ = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
job::job(FILE *out, const std::string &job_name)
|
job::job(FILE *out, const std::string &job_name)
|
||||||
: out_(out),
|
: out_(out),
|
||||||
job_name_(job_name),
|
job_name_(job_name),
|
||||||
page_params_(),
|
page_params_() {
|
||||||
pages_(0) {
|
|
||||||
// Delete dubious characters from job name
|
// Delete dubious characters from job name
|
||||||
std::replace_if(job_name_.begin(), job_name_.end(), [](char c) {
|
std::replace_if(job_name_.begin(), job_name_.end(), [](char c) {
|
||||||
return c < 32 || c >= 127 || c == '"' || c == '\\';
|
return c < 32 || c >= 127 || c == '"' || c == '\\';
|
||||||
}, ' ');
|
}, ' ');
|
||||||
|
|
||||||
|
begin_job();
|
||||||
}
|
}
|
||||||
|
|
||||||
job::~job() {
|
job::~job() {
|
||||||
if (pages_ != 0) {
|
end_job();
|
||||||
end_job();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void job::begin_job() {
|
void job::begin_job() {
|
||||||
@ -74,55 +111,36 @@ void job::write_page_header() {
|
|||||||
fprintf(out_, "@PJL SET PAGEPROTECT = AUTO\n");
|
fprintf(out_, "@PJL SET PAGEPROTECT = AUTO\n");
|
||||||
fprintf(out_, "@PJL SET ORIENTATION = PORTRAIT\n");
|
fprintf(out_, "@PJL SET ORIENTATION = PORTRAIT\n");
|
||||||
fprintf(out_, "@PJL ENTER LANGUAGE = PCL\n");
|
fprintf(out_, "@PJL ENTER LANGUAGE = PCL\n");
|
||||||
|
|
||||||
fputs("\033E", out_);
|
|
||||||
fprintf(out_, "\033&l%dX", std::max(1, page_params_.num_copies));
|
|
||||||
|
|
||||||
if (page_params_.duplex) {
|
|
||||||
fputs("\033&l2S", out_);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void job::encode_page(const page_params &page_params,
|
void job::encode_page(const page_params &page_params,
|
||||||
|
int num_copies,
|
||||||
int lines,
|
int lines,
|
||||||
int linesize,
|
int linesize,
|
||||||
nextline_fn nextline) {
|
nextline_fn nextline) {
|
||||||
if (pages_ == 0) {
|
|
||||||
begin_job();
|
|
||||||
}
|
|
||||||
++pages_;
|
|
||||||
|
|
||||||
if (!(page_params_ == page_params)) {
|
if (!(page_params_ == page_params)) {
|
||||||
page_params_ = page_params;
|
page_params_ = page_params;
|
||||||
write_page_header();
|
write_page_header();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint8_t> line(linesize);
|
vector<uint8_t> line(linesize);
|
||||||
std::vector<uint8_t> reference(linesize);
|
vector<uint8_t> reference(linesize);
|
||||||
block block;
|
block block;
|
||||||
|
|
||||||
if (!nextline(line)) {
|
if (!nextline(line.data())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
block.add_line(encode_line(line));
|
block.add_line(encode_line(line));
|
||||||
std::swap(line, reference);
|
std::swap(line, reference);
|
||||||
|
|
||||||
|
fputs("\033E", out_);
|
||||||
|
fprintf(out_, "\033&l%dX", std::max(1, num_copies));
|
||||||
fputs("\033*b1030m", out_);
|
fputs("\033*b1030m", out_);
|
||||||
|
|
||||||
// XXX brother driver uses 128 lines per band
|
for (int i = 1; i < lines && nextline(line.data()); ++i) {
|
||||||
const int lines_per_band = 64;
|
vector<uint8_t> encoded = encode_line(line, reference);
|
||||||
|
if (!block.line_fits(encoded.size())) {
|
||||||
for (int i = 1; i < lines && nextline(line); ++i) {
|
|
||||||
std::vector<uint8_t> encoded;
|
|
||||||
if (i % lines_per_band == 0) {
|
|
||||||
block.flush(out_);
|
block.flush(out_);
|
||||||
encoded = encode_line(line);
|
|
||||||
} else {
|
|
||||||
encoded = encode_line(line, reference);
|
|
||||||
if (!block.line_fits(encoded.size())) {
|
|
||||||
block.flush(out_);
|
|
||||||
encoded = encode_line(line);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
block.add_line(std::move(encoded));
|
block.add_line(std::move(encoded));
|
||||||
std::swap(line, reference);
|
std::swap(line, reference);
|
||||||
|
15
src/job.h
15
src/job.h
@ -21,21 +21,16 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
struct page_params {
|
struct page_params {
|
||||||
int num_copies;
|
|
||||||
int resolution;
|
int resolution;
|
||||||
bool duplex;
|
|
||||||
bool economode;
|
bool economode;
|
||||||
std::string sourcetray;
|
std::string sourcetray;
|
||||||
std::string mediatype;
|
std::string mediatype;
|
||||||
std::string papersize;
|
std::string papersize;
|
||||||
|
|
||||||
bool operator==(const page_params &o) const {
|
bool operator==(const page_params &o) const {
|
||||||
return num_copies == o.num_copies
|
return resolution == o.resolution
|
||||||
&& resolution == o.resolution
|
|
||||||
&& duplex == o.duplex
|
|
||||||
&& economode == o.economode
|
&& economode == o.economode
|
||||||
&& sourcetray == o.sourcetray
|
&& sourcetray == o.sourcetray
|
||||||
&& mediatype == o.mediatype
|
&& mediatype == o.mediatype
|
||||||
@ -45,20 +40,17 @@ struct page_params {
|
|||||||
|
|
||||||
class job {
|
class job {
|
||||||
public:
|
public:
|
||||||
typedef bool (*nextline_fn)(std::vector<uint8_t> &buf);
|
typedef bool (*nextline_fn)(uint8_t *buf);
|
||||||
|
|
||||||
explicit job(FILE *out, const std::string &job_name);
|
explicit job(FILE *out, const std::string &job_name);
|
||||||
~job();
|
~job();
|
||||||
|
|
||||||
void encode_page(const page_params ¶ms,
|
void encode_page(const page_params ¶ms,
|
||||||
|
int num_copies,
|
||||||
int lines,
|
int lines,
|
||||||
int linesize,
|
int linesize,
|
||||||
nextline_fn nextline);
|
nextline_fn nextline);
|
||||||
|
|
||||||
int pages() const {
|
|
||||||
return pages_;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void begin_job();
|
void begin_job();
|
||||||
void end_job();
|
void end_job();
|
||||||
@ -67,7 +59,6 @@ class job {
|
|||||||
FILE *out_;
|
FILE *out_;
|
||||||
std::string job_name_;
|
std::string job_name_;
|
||||||
page_params page_params_;
|
page_params page_params_;
|
||||||
int pages_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // JOB_H
|
#endif // JOB_H
|
||||||
|
12
src/line.cc
12
src/line.cc
@ -145,12 +145,10 @@ vector<uint8_t> encode_line(const vector<uint8_t> &line,
|
|||||||
int num_edits = 0;
|
int num_edits = 0;
|
||||||
|
|
||||||
auto line_it = line.begin();
|
auto line_it = line.begin();
|
||||||
auto line_end_it =
|
|
||||||
std::mismatch(line.rbegin(), line.rend(), reference.rbegin()).first.base();
|
|
||||||
auto ref_it = reference.begin();
|
auto ref_it = reference.begin();
|
||||||
while (1) {
|
while (1) {
|
||||||
int offset = skip_to_next_mismatch(&line_it, line_end_it, &ref_it);
|
int offset = skip_to_next_mismatch(&line_it, line.end(), &ref_it);
|
||||||
if (line_it == line_end_it) {
|
if (line_it == line.end()) {
|
||||||
// No more differences, we're done.
|
// No more differences, we're done.
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -158,17 +156,17 @@ vector<uint8_t> encode_line(const vector<uint8_t> &line,
|
|||||||
if (++num_edits == max_edits) {
|
if (++num_edits == max_edits) {
|
||||||
// We've run out of edits. Just output the rest of the line in a big
|
// We've run out of edits. Just output the rest of the line in a big
|
||||||
// substitute command.
|
// substitute command.
|
||||||
write_substitute(offset, line_it, line_end_it, &output);
|
write_substitute(offset, line_it, line.end(), &output);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
int s = substitute_length(line_it, line_end_it, ref_it);
|
int s = substitute_length(line_it, line.end(), ref_it);
|
||||||
if (s > 0) {
|
if (s > 0) {
|
||||||
write_substitute(offset, line_it, std::next(line_it, s), &output);
|
write_substitute(offset, line_it, std::next(line_it, s), &output);
|
||||||
line_it += s;
|
line_it += s;
|
||||||
ref_it += s;
|
ref_it += s;
|
||||||
} else {
|
} else {
|
||||||
int r = repeat_length(line_it, line_end_it);
|
int r = repeat_length(line_it, line.end());
|
||||||
assert(r >= 2);
|
assert(r >= 2);
|
||||||
write_repeat(offset, r, *line_it, &output);
|
write_repeat(offset, r, *line_it, &output);
|
||||||
line_it += r;
|
line_it += r;
|
||||||
|
137
src/main.cc
137
src/main.cc
@ -17,6 +17,8 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#include <locale.h>
|
||||||
|
#include <iconv.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <cups/raster.h>
|
#include <cups/raster.h>
|
||||||
@ -29,64 +31,64 @@
|
|||||||
#include "job.h"
|
#include "job.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
#ifndef O_BINARY
|
|
||||||
#define O_BINARY 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
cups_raster_t *ras;
|
|
||||||
volatile sig_atomic_t interrupted = 0;
|
volatile sig_atomic_t interrupted = 0;
|
||||||
|
|
||||||
|
|
||||||
void sigterm_handler(int sig) {
|
void sigterm_handler(int sig) {
|
||||||
interrupted = 1;
|
interrupted = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool next_line(std::vector<uint8_t> &buf) {
|
cups_raster_t *ras;
|
||||||
|
cups_page_header2_t header;
|
||||||
|
|
||||||
|
bool next_line(uint8_t *buf) {
|
||||||
if (interrupted) {
|
if (interrupted) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return cupsRasterReadPixels(ras, buf.data(), buf.size()) == buf.size();
|
unsigned bytes = header.cupsBytesPerLine;
|
||||||
|
return cupsRasterReadPixels(ras, buf, bytes) == bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// POSIX says the second argument of iconv has type 'char **', but
|
||||||
|
// some systems have 'const char **'. This class is used to work
|
||||||
|
// around this incompatibility.
|
||||||
|
class sloppy_ptr {
|
||||||
|
public:
|
||||||
|
explicit sloppy_ptr(const char **ptr): ptr_(ptr) { }
|
||||||
|
operator const char **() { return ptr_; }
|
||||||
|
operator char **() { return const_cast<char **>(ptr_); }
|
||||||
|
private:
|
||||||
|
const char **ptr_;
|
||||||
|
};
|
||||||
|
|
||||||
bool plain_ascii_string(const char *str) {
|
std::string ascii_job_name(const char *job_name, const char *charset) {
|
||||||
bool result = true;
|
if (job_name && charset) {
|
||||||
for (; result && *str; str++) {
|
iconv_t cd = iconv_open("ASCII//TRANSLIT//IGNORE", charset);
|
||||||
result = *str >= 32 && *str <= 126;
|
if (cd != (iconv_t) -1) {
|
||||||
}
|
char ascii[80];
|
||||||
return result;
|
const char *in_ptr = job_name;
|
||||||
}
|
size_t in_left = strlen(job_name);
|
||||||
|
char *out_ptr = ascii;
|
||||||
std::string ascii_job_name(const char *job_id, const char *job_user, const char *job_name) {
|
size_t out_left = sizeof(ascii) - 1;
|
||||||
std::array<const char *, 3> parts = {{
|
while (in_left > 0) {
|
||||||
job_id,
|
size_t err = iconv(cd,
|
||||||
job_user,
|
sloppy_ptr(&in_ptr), &in_left,
|
||||||
job_name
|
&out_ptr, &out_left);
|
||||||
}};
|
if (err == (size_t) -1) {
|
||||||
std::string result;
|
break;
|
||||||
for (const char *part : parts) {
|
}
|
||||||
if (*part && plain_ascii_string(part)) {
|
|
||||||
if (!result.empty()) {
|
|
||||||
result += '/';
|
|
||||||
}
|
}
|
||||||
result += part;
|
*out_ptr = 0;
|
||||||
|
iconv_close(cd);
|
||||||
|
return ascii;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (result.empty()) {
|
return "CUPS";
|
||||||
result = "brlaser";
|
|
||||||
}
|
|
||||||
const int max_size = 79;
|
|
||||||
if (result.size() > max_size) {
|
|
||||||
result.resize(max_size);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
page_params build_page_params(const cups_page_header2_t &header) {
|
page_params build_page_params() {
|
||||||
static const std::array<std::string, 6> sources = {{
|
static const std::array<std::string, 6> sources = {{
|
||||||
"AUTO", "T1", "T2", "T3", "MP", "MANUAL"
|
"AUTO", "T1", "T2", "T3", "MP", "MANUAL"
|
||||||
}};
|
}};
|
||||||
@ -99,18 +101,15 @@ page_params build_page_params(const cups_page_header2_t &header) {
|
|||||||
{ "EnvC5", "C5" },
|
{ "EnvC5", "C5" },
|
||||||
{ "EnvMonarch", "MONARCH" },
|
{ "EnvMonarch", "MONARCH" },
|
||||||
{ "EnvPRC5", "DL" },
|
{ "EnvPRC5", "DL" },
|
||||||
{ "EnvDL", "DL" },
|
|
||||||
{ "Executive", "EXECUTIVE" },
|
{ "Executive", "EXECUTIVE" },
|
||||||
{ "Legal", "LEGAL" },
|
{ "Legal", "LEGAL" },
|
||||||
{ "Letter", "LETTER" }
|
{ "Letter", "LETTER" }
|
||||||
};
|
};
|
||||||
|
|
||||||
page_params p = { };
|
page_params p = { };
|
||||||
p.num_copies = header.NumCopies;
|
|
||||||
p.resolution = header.HWResolution[0];
|
p.resolution = header.HWResolution[0];
|
||||||
p.economode = header.cupsInteger[10];
|
p.economode = header.cupsInteger[10];
|
||||||
p.mediatype = header.MediaType;
|
p.mediatype = header.MediaType;
|
||||||
p.duplex = header.Duplex;
|
|
||||||
|
|
||||||
if (header.MediaPosition < sources.size())
|
if (header.MediaPosition < sources.size())
|
||||||
p.sourcetray = sources[header.MediaPosition];
|
p.sourcetray = sources[header.MediaPosition];
|
||||||
@ -129,78 +128,66 @@ page_params build_page_params(const cups_page_header2_t &header) {
|
|||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
fprintf(stderr, "INFO: %s version %s\n", PACKAGE, VERSION);
|
fprintf(stderr, "INFO: %s version %s\n", PACKAGE, VERSION);
|
||||||
|
|
||||||
if (argc != 6 && argc != 7) {
|
if (argc != 6 && argc != 7) {
|
||||||
fprintf(stderr, "ERROR: rastertobrlaser job-id user title copies options [file]\n");
|
fprintf(stderr, "ERROR: %s job-id user title copies options [file]\n", argv[0]);
|
||||||
fprintf(stderr, "INFO: This program is a CUPS filter. It is not intended to be run manually.\n");
|
fprintf(stderr, "INFO: This program is a CUPS filter. It is not intended to be run manually.\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
const char *job_id = argv[1];
|
// const char *job_id = argv[1];
|
||||||
const char *job_user = argv[2];
|
// const char *job_user = argv[2];
|
||||||
const char *job_name = argv[3];
|
const char *job_name = argv[3];
|
||||||
// const int job_copies = atoi(argv[4]);
|
// const int job_copies = atoi(argv[4]);
|
||||||
// const char *job_options = argv[5];
|
// const char *job_options = argv[5];
|
||||||
const char *job_filename = argv[6];
|
const char *job_filename = argv[6];
|
||||||
// const char *job_charset = getenv("CHARSET");
|
const char *job_charset = getenv("CHARSET");
|
||||||
|
|
||||||
|
setlocale(LC_ALL, "");
|
||||||
|
|
||||||
signal(SIGTERM, sigterm_handler);
|
signal(SIGTERM, sigterm_handler);
|
||||||
signal(SIGPIPE, SIG_IGN);
|
signal(SIGPIPE, SIG_IGN);
|
||||||
|
|
||||||
int fd = STDIN_FILENO;
|
int fd = 0;
|
||||||
if (job_filename) {
|
if (job_filename) {
|
||||||
fd = open(job_filename, O_RDONLY | O_BINARY);
|
fd = open(job_filename, O_RDONLY);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
fprintf(stderr, "ERROR: " PACKAGE ": Unable to open raster file\n");
|
fprintf(stderr, "ERROR: Unable to open raster file\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __OpenBSD__
|
|
||||||
if (pledge("stdio", nullptr) != 0) {
|
|
||||||
fprintf(stderr, "ERROR: " PACKAGE ": pledge failed\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ras = cupsRasterOpen(fd, CUPS_RASTER_READ);
|
ras = cupsRasterOpen(fd, CUPS_RASTER_READ);
|
||||||
if (!ras) {
|
if (!ras) {
|
||||||
fprintf(stderr, "DEBUG: " PACKAGE ": Cannot read raster data. Most likely an earlier filter in the pipeline failed.\n");
|
fprintf(stderr, "ERROR: Can't read raster data\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int pages = 0;
|
||||||
{
|
{
|
||||||
job job(stdout, ascii_job_name(job_id, job_user, job_name));
|
job job(stdout, ascii_job_name(job_name, job_charset));
|
||||||
cups_page_header2_t header;
|
|
||||||
while (!interrupted && cupsRasterReadHeader2(ras, &header)) {
|
while (!interrupted && cupsRasterReadHeader2(ras, &header)) {
|
||||||
if (header.cupsBitsPerPixel != 1
|
if (pages == 0) {
|
||||||
|| header.cupsBitsPerColor != 1
|
|
||||||
|| header.cupsNumColors != 1
|
|
||||||
|| header.cupsBytesPerLine > 10000) {
|
|
||||||
fprintf(stderr, "ERROR: " PACKAGE ": Page %d: Bogus raster data.\n", job.pages() + 1);
|
|
||||||
dump_page_header(header);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (job.pages() == 0) {
|
|
||||||
fprintf(stderr, "DEBUG: " PACKAGE ": Page header of first page\n");
|
|
||||||
dump_page_header(header);
|
dump_page_header(header);
|
||||||
}
|
}
|
||||||
job.encode_page(build_page_params(header),
|
job.encode_page(build_page_params(),
|
||||||
|
header.NumCopies,
|
||||||
header.cupsHeight,
|
header.cupsHeight,
|
||||||
header.cupsBytesPerLine,
|
header.cupsBytesPerLine,
|
||||||
next_line);
|
next_line);
|
||||||
fprintf(stderr, "PAGE: %d %d\n", job.pages(), header.NumCopies);
|
fprintf(stderr, "PAGE: %d %d\n", ++pages, header.NumCopies);
|
||||||
}
|
|
||||||
|
|
||||||
if (job.pages() == 0) {
|
|
||||||
fprintf(stderr, "ERROR: " PACKAGE ": No pages were found.\n");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (pages == 0) {
|
||||||
|
fprintf(stderr, "ERROR: No pages were found.");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
if (ferror(stdout)) {
|
if (ferror(stdout)) {
|
||||||
fprintf(stderr, "DEBUG: " PACKAGE ": Could not write print data. Most likely the CUPS backend failed.\n");
|
fprintf(stderr, "ERROR: Could not write print data\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
199
test/lest.hpp
199
test/lest.hpp
@ -1,199 +0,0 @@
|
|||||||
// Copyright 2013 by Martin Moene
|
|
||||||
//
|
|
||||||
// lest is based on ideas by Kevlin Henney, see video at
|
|
||||||
// http://skillsmatter.com/podcast/agile-testing/kevlin-henney-rethinking-unit-testing-in-c-plus-plus
|
|
||||||
//
|
|
||||||
// Distributed under the Boost Software License, Version 1.0:
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
// obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
// this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
// execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
// Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
// do so, all subject to the following:
|
|
||||||
//
|
|
||||||
// The copyright notices in the Software and this entire statement, including
|
|
||||||
// the above license grant, this restriction and the following disclaimer,
|
|
||||||
// must be included in all copies of the Software, in whole or in part, and
|
|
||||||
// all derivative works of the Software, unless such copies or derivative
|
|
||||||
// works are solely in the form of machine-executable object code generated by
|
|
||||||
// a source language processor.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
// DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
#ifndef LEST_LEST_H_INCLUDED
|
|
||||||
#define LEST_LEST_H_INCLUDED
|
|
||||||
|
|
||||||
#include <functional>
|
|
||||||
#include <iostream>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <string>
|
|
||||||
#include <cstddef>
|
|
||||||
|
|
||||||
#ifndef lest_NO_SHORT_ASSERTION_NAMES
|
|
||||||
# define EXPECT lest_EXPECT
|
|
||||||
# define EXPECT_THROWS lest_EXPECT_THROWS
|
|
||||||
# define EXPECT_THROWS_AS lest_EXPECT_THROWS_AS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define lest_EXPECT( expr ) \
|
|
||||||
try \
|
|
||||||
{ \
|
|
||||||
if ( ! (expr) ) \
|
|
||||||
throw lest::failure{ lest_LOCATION, #expr }; \
|
|
||||||
} \
|
|
||||||
catch( lest::failure const & ) \
|
|
||||||
{ \
|
|
||||||
throw ; \
|
|
||||||
} \
|
|
||||||
catch( std::exception const & e ) \
|
|
||||||
{ \
|
|
||||||
throw lest::unexpected{ lest_LOCATION, #expr, lest::with_message( e.what() ) }; \
|
|
||||||
} \
|
|
||||||
catch(...) \
|
|
||||||
{ \
|
|
||||||
throw lest::unexpected{ lest_LOCATION, #expr, "of unknown type" }; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define lest_EXPECT_THROWS( expr ) \
|
|
||||||
for (;;) \
|
|
||||||
{ \
|
|
||||||
try { lest::serum( expr ); } catch (...) { break; } \
|
|
||||||
throw lest::expected{ lest_LOCATION, #expr }; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define lest_EXPECT_THROWS_AS( expr, excpt ) \
|
|
||||||
for (;;) \
|
|
||||||
{ \
|
|
||||||
try { lest::serum( expr ); } catch ( excpt & ) { break; } catch (...) {} \
|
|
||||||
throw lest::expected{ lest_LOCATION, #expr, lest::of_type( #excpt ) }; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define lest_LOCATION lest::location{__FILE__, __LINE__}
|
|
||||||
|
|
||||||
namespace lest {
|
|
||||||
|
|
||||||
struct test
|
|
||||||
{
|
|
||||||
const std::string name;
|
|
||||||
const std::function<void()> behaviour;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct location
|
|
||||||
{
|
|
||||||
const std::string file;
|
|
||||||
const int line;
|
|
||||||
|
|
||||||
location( std::string file, int line )
|
|
||||||
: file{ file }, line{ line } {}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct comment
|
|
||||||
{
|
|
||||||
const std::string text;
|
|
||||||
|
|
||||||
comment( std::string text ) : text{ text } {}
|
|
||||||
explicit operator bool() { return ! text.empty(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct message : std::runtime_error
|
|
||||||
{
|
|
||||||
const std::string kind;
|
|
||||||
const location where;
|
|
||||||
const comment note;
|
|
||||||
|
|
||||||
~message() throw() {} // GCC 4.6
|
|
||||||
|
|
||||||
message( std::string kind, location where, std::string expr, std::string note = "" )
|
|
||||||
: std::runtime_error{ expr }, kind{ kind }, where{ where }, note{ note } {}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct failure : message
|
|
||||||
{
|
|
||||||
failure( location where, std::string expr )
|
|
||||||
: message{ "failed", where, expr } {}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct expected : message
|
|
||||||
{
|
|
||||||
expected( location where, std::string expr, std::string excpt = "" )
|
|
||||||
: message{ "failed: didn't get exception", where, expr, excpt } {}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct unexpected : message
|
|
||||||
{
|
|
||||||
unexpected( location where, std::string expr, std::string note )
|
|
||||||
: message{ "failed: got unexpected exception", where, expr, note } {}
|
|
||||||
};
|
|
||||||
|
|
||||||
inline bool serum( bool verum ) { return verum; }
|
|
||||||
|
|
||||||
inline std::string with_message( std::string text )
|
|
||||||
{
|
|
||||||
return "with message \"" + text + "\"";
|
|
||||||
}
|
|
||||||
|
|
||||||
inline std::string of_type( std::string text )
|
|
||||||
{
|
|
||||||
return "of type " + text;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline std::string pluralise( int n, std::string text )
|
|
||||||
{
|
|
||||||
return n == 1 ? text : text + "s";
|
|
||||||
}
|
|
||||||
|
|
||||||
inline std::ostream & operator<<( std::ostream & os, comment note )
|
|
||||||
{
|
|
||||||
return os << (note ? " " + note.text : "" );
|
|
||||||
}
|
|
||||||
|
|
||||||
inline std::ostream & operator<<( std::ostream & os, location where )
|
|
||||||
{
|
|
||||||
#ifdef __GNUG__
|
|
||||||
return os << where.file << ":" << where.line;
|
|
||||||
#else
|
|
||||||
return os << where.file << "(" << where.line << ")";
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void report( std::ostream & os, message const & e, std::string test )
|
|
||||||
{
|
|
||||||
os << e.where << ": " << e.kind << e.note << ": " << test << ": " << e.what() << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<std::size_t N>
|
|
||||||
int run( test const (&specification)[N], std::ostream & os = std::cout )
|
|
||||||
{
|
|
||||||
int failures = 0;
|
|
||||||
|
|
||||||
for ( auto & testing : specification )
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
testing.behaviour();
|
|
||||||
}
|
|
||||||
catch( message const & e )
|
|
||||||
{
|
|
||||||
++failures;
|
|
||||||
report( os, e, testing.name );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( failures > 0 )
|
|
||||||
{
|
|
||||||
os << failures << " out of " << N << " " << pluralise(N, "test") << " failed." << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
return failures;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace lest
|
|
||||||
|
|
||||||
#endif // LEST_LEST_H_INCLUDED
|
|
@ -1,55 +0,0 @@
|
|||||||
// This file is part of the brlaser printer driver.
|
|
||||||
//
|
|
||||||
// Copyright 2014 Peter De Wachter
|
|
||||||
//
|
|
||||||
// brlaser is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 2 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// brlaser is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with brlaser. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
#ifndef TEMPFILE_H
|
|
||||||
#define TEMPFILE_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
class tempfile {
|
|
||||||
public:
|
|
||||||
explicit tempfile()
|
|
||||||
: ptr_(0),
|
|
||||||
size_(0),
|
|
||||||
file_(open_memstream(&ptr_, &size_)) {
|
|
||||||
}
|
|
||||||
|
|
||||||
~tempfile() {
|
|
||||||
fclose(file_);
|
|
||||||
free(ptr_);
|
|
||||||
}
|
|
||||||
|
|
||||||
FILE *file() {
|
|
||||||
return file_;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<uint8_t> data() {
|
|
||||||
if (fflush(file_))
|
|
||||||
return std::vector<uint8_t>();
|
|
||||||
return std::vector<uint8_t>(ptr_, ptr_ + size_);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
char *ptr_;
|
|
||||||
size_t size_;
|
|
||||||
FILE *file_;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // TEMPFILE_H
|
|
@ -1,81 +0,0 @@
|
|||||||
// This file is part of the brlaser printer driver.
|
|
||||||
//
|
|
||||||
// Copyright 2014 Peter De Wachter
|
|
||||||
//
|
|
||||||
// brlaser is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 2 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// brlaser is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with brlaser. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
#include "lest.hpp"
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <vector>
|
|
||||||
#include "tempfile.h"
|
|
||||||
#include "../src/block.h"
|
|
||||||
|
|
||||||
typedef std::vector<uint8_t> vec;
|
|
||||||
|
|
||||||
const lest::test specification[] = {
|
|
||||||
"A block is created empty",
|
|
||||||
[] {
|
|
||||||
block b;
|
|
||||||
EXPECT(b.empty());
|
|
||||||
},
|
|
||||||
|
|
||||||
"Adding a line makes a block no longer empty",
|
|
||||||
[] {
|
|
||||||
block b;
|
|
||||||
b.add_line(vec{1});
|
|
||||||
EXPECT(!b.empty());
|
|
||||||
},
|
|
||||||
|
|
||||||
"A block has a size limit of about 16 kilobyte",
|
|
||||||
[] {
|
|
||||||
block b;
|
|
||||||
for (int i = 0; i < 16; ++i) {
|
|
||||||
EXPECT(b.line_fits(1000));
|
|
||||||
b.add_line(vec(1000));
|
|
||||||
}
|
|
||||||
EXPECT(!b.line_fits(400));
|
|
||||||
},
|
|
||||||
|
|
||||||
"Flushing an empty block does nothing",
|
|
||||||
[] {
|
|
||||||
block b;
|
|
||||||
tempfile f;
|
|
||||||
b.flush(f.file());
|
|
||||||
EXPECT(f.data().empty());
|
|
||||||
},
|
|
||||||
|
|
||||||
"Flush() writes the lines to a file with a proper header",
|
|
||||||
[] {
|
|
||||||
block b;
|
|
||||||
for (uint8_t n = 1; n < 6; ++n) {
|
|
||||||
b.add_line(vec{n, n});
|
|
||||||
}
|
|
||||||
tempfile f;
|
|
||||||
b.flush(f.file());
|
|
||||||
EXPECT(( f.data() == vec{'1','2','w',0,5,1,1,2,2,3,3,4,4,5,5} ));
|
|
||||||
},
|
|
||||||
|
|
||||||
"After flush() a block is empty again",
|
|
||||||
[] {
|
|
||||||
block b;
|
|
||||||
b.add_line(vec{1});
|
|
||||||
tempfile f;
|
|
||||||
b.flush(f.file());
|
|
||||||
EXPECT(b.empty());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
return lest::run(specification);
|
|
||||||
}
|
|
@ -1,35 +0,0 @@
|
|||||||
// This file is part of the brlaser printer driver.
|
|
||||||
//
|
|
||||||
// Copyright 2020 Peter De Wachter
|
|
||||||
//
|
|
||||||
// brlaser is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 2 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// brlaser is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with brlaser. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
#include "lest.hpp"
|
|
||||||
#include "tempfile.h"
|
|
||||||
#include "../src/job.h"
|
|
||||||
|
|
||||||
const lest::test specification[] = {
|
|
||||||
"An empty job produces no output",
|
|
||||||
[] {
|
|
||||||
tempfile f;
|
|
||||||
{
|
|
||||||
job j(f.file(), "name");
|
|
||||||
}
|
|
||||||
EXPECT(f.data().empty());
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
return lest::run(specification);
|
|
||||||
}
|
|
@ -1,291 +0,0 @@
|
|||||||
// Copyright 2013 by Martin Moene
|
|
||||||
//
|
|
||||||
// Distributed under the Boost Software License, Version 1.0:
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
// obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
// this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
// execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
// Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
// do so, all subject to the following:
|
|
||||||
//
|
|
||||||
// The copyright notices in the Software and this entire statement, including
|
|
||||||
// the above license grant, this restriction and the following disclaimer,
|
|
||||||
// must be included in all copies of the Software, in whole or in part, and
|
|
||||||
// all derivative works of the Software, unless such copies or derivative
|
|
||||||
// works are solely in the form of machine-executable object code generated by
|
|
||||||
// a source language processor.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
// DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
#include "lest.hpp"
|
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
using namespace lest;
|
|
||||||
|
|
||||||
const lest::test specification[] =
|
|
||||||
{
|
|
||||||
"Function to suppress warning \"expression has no effect\" acts as identity function", []
|
|
||||||
{
|
|
||||||
EXPECT( false == serum( false ) );
|
|
||||||
EXPECT( true == serum( true ) );
|
|
||||||
},
|
|
||||||
|
|
||||||
"Function with_message() returns correct string", []
|
|
||||||
{
|
|
||||||
std::string msg = "Let writing tests become irresistibly easy and attractive.";
|
|
||||||
EXPECT( "with message \"" + msg + "\"" == with_message( msg ) );
|
|
||||||
},
|
|
||||||
|
|
||||||
"Function of_type() returns correct string", []
|
|
||||||
{
|
|
||||||
std::string msg = "this_type";
|
|
||||||
EXPECT( "of type " + msg == of_type( msg ) );
|
|
||||||
},
|
|
||||||
|
|
||||||
"Function pluralise() adds 's' except for 1 item", []
|
|
||||||
{
|
|
||||||
std::string word = "hammer";
|
|
||||||
EXPECT( word == pluralise( 1, word ) );
|
|
||||||
for ( auto i : {0,2,3,4,5,6,7,8,9,10,11,12} )
|
|
||||||
EXPECT( word + "s" == pluralise( i, word ) );
|
|
||||||
},
|
|
||||||
|
|
||||||
"Location constructs properly", []
|
|
||||||
{
|
|
||||||
char const * file = __FILE__; int line = __LINE__;
|
|
||||||
location where{ file, line };
|
|
||||||
EXPECT( file == where.file );
|
|
||||||
EXPECT( line == where.line );
|
|
||||||
},
|
|
||||||
|
|
||||||
"Comment constructs properly", []
|
|
||||||
{
|
|
||||||
std::string text = __FILE__;
|
|
||||||
comment note = text;
|
|
||||||
EXPECT( text == note.text );
|
|
||||||
},
|
|
||||||
|
|
||||||
"Comment converted to bool indicates absence or presence of comment", []
|
|
||||||
{
|
|
||||||
EXPECT( false == bool( comment( "") ) );
|
|
||||||
EXPECT( true == bool( comment("x") ) );
|
|
||||||
},
|
|
||||||
|
|
||||||
"Failure exception type constructs and prints properly", []
|
|
||||||
{
|
|
||||||
std::string name = "test-name";
|
|
||||||
failure msg( location{"filename.cpp", 765}, "expression" );
|
|
||||||
|
|
||||||
std::ostringstream os;
|
|
||||||
report( os, msg, name );
|
|
||||||
|
|
||||||
#ifndef __GNUG__
|
|
||||||
EXPECT( os.str() == "filename.cpp(765): failed: test-name: expression\n" );
|
|
||||||
#else
|
|
||||||
EXPECT( os.str() == "filename.cpp:765: failed: test-name: expression\n" );
|
|
||||||
#endif
|
|
||||||
},
|
|
||||||
|
|
||||||
"Expected exception type constructs and prints properly", []
|
|
||||||
{
|
|
||||||
std::string name = "test-name";
|
|
||||||
expected msg( location{"filename.cpp", 765}, "expression" );
|
|
||||||
|
|
||||||
std::ostringstream os;
|
|
||||||
report( os, msg, name );
|
|
||||||
|
|
||||||
#ifndef __GNUG__
|
|
||||||
EXPECT( os.str() == "filename.cpp(765): failed: didn't get exception: test-name: expression\n" );
|
|
||||||
#else
|
|
||||||
EXPECT( os.str() == "filename.cpp:765: failed: didn't get exception: test-name: expression\n" );
|
|
||||||
#endif
|
|
||||||
},
|
|
||||||
|
|
||||||
"Unexpected exception type constructs and prints properly", []
|
|
||||||
{
|
|
||||||
std::string name = "test-name";
|
|
||||||
unexpected msg( location{"filename.cpp", 765}, "expression", "exception-type" );
|
|
||||||
|
|
||||||
std::ostringstream os;
|
|
||||||
report( os, msg, name );
|
|
||||||
|
|
||||||
#ifndef __GNUG__
|
|
||||||
EXPECT( os.str() == "filename.cpp(765): failed: got unexpected exception exception-type: test-name: expression\n" );
|
|
||||||
#else
|
|
||||||
EXPECT( os.str() == "filename.cpp:765: failed: got unexpected exception exception-type: test-name: expression\n" );
|
|
||||||
#endif
|
|
||||||
},
|
|
||||||
|
|
||||||
"Expect generates no message exception for a succeeding test", []
|
|
||||||
{
|
|
||||||
test pass = { "P", [] { EXPECT( true ); } };
|
|
||||||
|
|
||||||
try { pass.behaviour(); }
|
|
||||||
catch(...) { throw failure(location{__FILE__,__LINE__}, "unexpected error generated"); }
|
|
||||||
},
|
|
||||||
|
|
||||||
"Expect generates a message exception for a failing test", []
|
|
||||||
{
|
|
||||||
test fail = { "F", [] { EXPECT( false ); } };
|
|
||||||
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
try { fail.behaviour(); } catch ( message & ) { break; }
|
|
||||||
throw failure(location{__FILE__,__LINE__}, "no error generated");
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
"Expect succeeds for success (true) and failure (false)", []
|
|
||||||
{
|
|
||||||
test pass[] = {{ "P", [] { EXPECT( true ); } }};
|
|
||||||
test fail[] = {{ "F", [] { EXPECT( false ); } }};
|
|
||||||
|
|
||||||
std::ostringstream os;
|
|
||||||
|
|
||||||
EXPECT( 0 == run( pass, os ) );
|
|
||||||
EXPECT( 1 == run( fail, os ) );
|
|
||||||
},
|
|
||||||
|
|
||||||
"Expect succeeds for integer comparation", []
|
|
||||||
{
|
|
||||||
test pass [] = {{ "P" , [] { EXPECT( 7 == 7 ); EXPECT( 7 != 8 );
|
|
||||||
EXPECT( 7 >= 6 ); EXPECT( 7 <= 8 );
|
|
||||||
EXPECT( 7 > 6 ); EXPECT( 7 < 8 ); } }};
|
|
||||||
test fail_1[] = {{ "F1", [] { EXPECT( 7 == 8 ); } }};
|
|
||||||
test fail_2[] = {{ "F2", [] { EXPECT( 7 != 7 ); } }};
|
|
||||||
test fail_3[] = {{ "F3", [] { EXPECT( 7 <= 6 ); } }};
|
|
||||||
test fail_4[] = {{ "F4", [] { EXPECT( 7 >= 8 ); } }};
|
|
||||||
test fail_5[] = {{ "F5", [] { EXPECT( 7 < 6 ); } }};
|
|
||||||
test fail_6[] = {{ "F6", [] { EXPECT( 7 > 8 ); } }};
|
|
||||||
|
|
||||||
std::ostringstream os;
|
|
||||||
|
|
||||||
EXPECT( 0 == run( pass , os ) );
|
|
||||||
EXPECT( 1 == run( fail_1, os ) );
|
|
||||||
EXPECT( 1 == run( fail_2, os ) );
|
|
||||||
EXPECT( 1 == run( fail_3, os ) );
|
|
||||||
EXPECT( 1 == run( fail_4, os ) );
|
|
||||||
EXPECT( 1 == run( fail_5, os ) );
|
|
||||||
EXPECT( 1 == run( fail_6, os ) );
|
|
||||||
},
|
|
||||||
|
|
||||||
"Expect succeeds for string comparation", []
|
|
||||||
{
|
|
||||||
std::string a("a"); std::string b("b");
|
|
||||||
test pass [] = {{ "P" , [=]() { EXPECT( a == a ); EXPECT( a != b );
|
|
||||||
EXPECT( b >= a ); EXPECT( a <= b );
|
|
||||||
EXPECT( b > a ); EXPECT( a < b ); } }};
|
|
||||||
test fail_1[] = {{ "F1", [=]() { EXPECT( a == b ); } }};
|
|
||||||
test fail_2[] = {{ "F2", [=]() { EXPECT( a != a ); } }};
|
|
||||||
test fail_3[] = {{ "F3", [=]() { EXPECT( b <= a ); } }};
|
|
||||||
test fail_4[] = {{ "F4", [=]() { EXPECT( a >= b ); } }};
|
|
||||||
test fail_5[] = {{ "F5", [=]() { EXPECT( b < a ); } }};
|
|
||||||
test fail_6[] = {{ "F6", [=]() { EXPECT( a > b ); } }};
|
|
||||||
|
|
||||||
std::ostringstream os;
|
|
||||||
|
|
||||||
EXPECT( 0 == run( pass , os ) );
|
|
||||||
EXPECT( 1 == run( fail_1, os ) );
|
|
||||||
EXPECT( 1 == run( fail_2, os ) );
|
|
||||||
EXPECT( 1 == run( fail_3, os ) );
|
|
||||||
EXPECT( 1 == run( fail_4, os ) );
|
|
||||||
EXPECT( 1 == run( fail_5, os ) );
|
|
||||||
EXPECT( 1 == run( fail_6, os ) );
|
|
||||||
},
|
|
||||||
|
|
||||||
"Function run() returns the right failure count", []
|
|
||||||
{
|
|
||||||
test pass [] = {{ "P" , [] { EXPECT( 1==1 ); } }};
|
|
||||||
test fail_1[] = {{ "F1", [] { EXPECT( 0==1 ); } }};
|
|
||||||
test fail_3[] = {{ "F1", [] { EXPECT( 0==1 ); } },
|
|
||||||
{ "F2", [] { EXPECT( 0==1 ); } },
|
|
||||||
{ "F3", [] { EXPECT( 0==1 ); } },};
|
|
||||||
|
|
||||||
std::ostringstream os;
|
|
||||||
|
|
||||||
EXPECT( 0 == run( pass , os ) );
|
|
||||||
EXPECT( 1 == run( fail_1, os ) );
|
|
||||||
EXPECT( 3 == run( fail_3, os ) );
|
|
||||||
},
|
|
||||||
|
|
||||||
"Expect succeeds with an unexpected standard exception", []
|
|
||||||
{
|
|
||||||
std::string text = "hello-world";
|
|
||||||
test pass[] = {{ "P", [=]() { EXPECT( (throw std::runtime_error(text), true) ); } }};
|
|
||||||
|
|
||||||
std::ostringstream os;
|
|
||||||
|
|
||||||
EXPECT( 1 == run( pass, os ) );
|
|
||||||
EXPECT( std::string::npos != os.str().find(text) );
|
|
||||||
},
|
|
||||||
|
|
||||||
"Expect succeeds with an unexpected non-standard exception", []
|
|
||||||
{
|
|
||||||
test pass[] = {{ "P", [] { EXPECT( (throw 77, true) ); } }};
|
|
||||||
|
|
||||||
std::ostringstream os;
|
|
||||||
|
|
||||||
EXPECT( 1 == run( pass, os ) );
|
|
||||||
},
|
|
||||||
|
|
||||||
"Expect_throws succeeds with an expected standard exception", []
|
|
||||||
{
|
|
||||||
std::string text = "hello-world";
|
|
||||||
test pass[] = {{ "P", [=]() { EXPECT_THROWS( (throw std::runtime_error(text), true) ); } }};
|
|
||||||
test fail[] = {{ "F", [ ]() { EXPECT_THROWS( true ); } }};
|
|
||||||
|
|
||||||
std::ostringstream os;
|
|
||||||
|
|
||||||
EXPECT( 0 == run( pass, os ) );
|
|
||||||
EXPECT( 1 == run( fail, os ) );
|
|
||||||
},
|
|
||||||
|
|
||||||
"Expect_throws succeeds with an expected non-standard exception", []
|
|
||||||
{
|
|
||||||
test pass[] = {{ "P", [] { EXPECT_THROWS( (throw 77, true) ); } }};
|
|
||||||
test fail[] = {{ "F", [] { EXPECT_THROWS( true ); } }};
|
|
||||||
|
|
||||||
std::ostringstream os;
|
|
||||||
|
|
||||||
EXPECT( 0 == run( pass, os ) );
|
|
||||||
EXPECT( 1 == run( fail, os ) );
|
|
||||||
},
|
|
||||||
|
|
||||||
"Expect_throws_as succeeds with a specific expected standard exception", []
|
|
||||||
{
|
|
||||||
test pass[] = {{ "P", [] { EXPECT_THROWS_AS( (throw std::bad_alloc(), true), std::bad_alloc ); } }};
|
|
||||||
test fail[] = {{ "F", [] { EXPECT_THROWS_AS( (throw std::bad_alloc(), true), std::runtime_error ); } }};
|
|
||||||
|
|
||||||
std::ostringstream os;
|
|
||||||
|
|
||||||
EXPECT( 0 == run( pass, os ) );
|
|
||||||
EXPECT( 1 == run( fail, os ) );
|
|
||||||
},
|
|
||||||
|
|
||||||
"Expect_throws_as succeeds with a specific expected non-standard exception", []
|
|
||||||
{
|
|
||||||
test pass[] = {{ "P", [] { EXPECT_THROWS_AS( (throw 77, true), int ); } }};
|
|
||||||
test fail[] = {{ "F", [] { EXPECT_THROWS_AS( (throw 77, true), std::runtime_error ); } }};
|
|
||||||
|
|
||||||
std::ostringstream os;
|
|
||||||
|
|
||||||
EXPECT( 0 == run( pass, os ) );
|
|
||||||
EXPECT( 1 == run( fail, os ) );
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
return lest::run( specification );
|
|
||||||
}
|
|
||||||
|
|
||||||
// cl -nologo -Wall -EHsc test_lest.cpp && test_lest
|
|
||||||
// g++ -Wall -Wextra -Weffc++ -std=c++11 -o test_lest.exe test_lest.cpp && test_lest
|
|
||||||
|
|
@ -1,150 +0,0 @@
|
|||||||
// This file is part of the brlaser printer driver.
|
|
||||||
//
|
|
||||||
// Copyright 2014 Peter De Wachter
|
|
||||||
//
|
|
||||||
// brlaser is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 2 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// brlaser is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with brlaser. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
#include "lest.hpp"
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <vector>
|
|
||||||
#include "../src/line.h"
|
|
||||||
|
|
||||||
typedef std::vector<uint8_t> vec;
|
|
||||||
|
|
||||||
|
|
||||||
uint8_t sub(uint8_t offset, uint8_t count) {
|
|
||||||
assert(offset < 16);
|
|
||||||
assert(count < 8);
|
|
||||||
return (offset << 3) | count;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t rep(uint8_t offset, uint8_t count) {
|
|
||||||
assert(offset < 4);
|
|
||||||
assert(count < 32);
|
|
||||||
return 128 | (offset << 5) | count;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const lest::test specification[] = {
|
|
||||||
"Don't crash on zero-length lines",
|
|
||||||
[] {
|
|
||||||
EXPECT(( encode_line(vec{}) == vec{0xFF} ));
|
|
||||||
EXPECT(( encode_line(vec{}, vec{}) == vec{0xFF} ));
|
|
||||||
},
|
|
||||||
|
|
||||||
"Encoding an initial blank line",
|
|
||||||
[] {
|
|
||||||
EXPECT(( encode_line(vec{0,0,0}) == vec{0xFF} ));
|
|
||||||
},
|
|
||||||
|
|
||||||
"Encoding an initial non-blank line",
|
|
||||||
[] {
|
|
||||||
EXPECT(( encode_line(vec{1,2,3}) == (vec{1,sub(0,2),1,2,3}) ));
|
|
||||||
},
|
|
||||||
|
|
||||||
"Encoding a (non-initial) blank line",
|
|
||||||
[] {
|
|
||||||
EXPECT(( encode_line(vec{0,0,0}, vec{1,2,3}) == vec{0xFF} ));
|
|
||||||
},
|
|
||||||
|
|
||||||
"Encoding a repeated line",
|
|
||||||
[] {
|
|
||||||
EXPECT(( encode_line(vec{1,2,3}, vec{1,2,3}) == vec{0} ));
|
|
||||||
},
|
|
||||||
|
|
||||||
"Using a subsitute command",
|
|
||||||
[] {
|
|
||||||
EXPECT(( encode_line(vec{0,0,1,2,3,0,0}, vec(7)) == vec{1,sub(2,2),1,2,3} ));
|
|
||||||
},
|
|
||||||
|
|
||||||
"Using a repeat command",
|
|
||||||
[] {
|
|
||||||
EXPECT(( encode_line(vec{0,0,1,1,0,0}, vec(6)) == vec{1,rep(2,0),1} ));
|
|
||||||
},
|
|
||||||
|
|
||||||
"Repeat command followed by substitute command",
|
|
||||||
[] {
|
|
||||||
EXPECT(( encode_line(vec{1,1,1,2,3}, vec(5)) == vec{2,rep(0,1),1,sub(0,1),2,3} ));
|
|
||||||
},
|
|
||||||
|
|
||||||
"Substitute comand followed by repeat command",
|
|
||||||
[] {
|
|
||||||
EXPECT(( encode_line(vec{3,2,1,1,1}, vec(5)) == vec{2,sub(0,1),3,2,rep(0,1),1} ));
|
|
||||||
},
|
|
||||||
|
|
||||||
"Substitute with an unmodified byte in the middle",
|
|
||||||
[] {
|
|
||||||
EXPECT(( encode_line(vec{1,2,3,0,1,2,3}, vec(7)) == vec{1,sub(0,6),1,2,3,0,1,2,3} ));
|
|
||||||
},
|
|
||||||
|
|
||||||
"Substitue with two unmodified bytes in the middle",
|
|
||||||
[] {
|
|
||||||
EXPECT(( encode_line(vec{1,2,3,0,0,1,2,3}, vec(8)) == vec{2,sub(0,2),1,2,3,sub(2,2),1,2,3} ));
|
|
||||||
},
|
|
||||||
|
|
||||||
"Repeat with an unmodified byte in the middle",
|
|
||||||
[] {
|
|
||||||
EXPECT(( encode_line(vec{1,1,1,0,1,1,1}, vec(7)) == vec{2,rep(0,1),1,rep(1,1),1} ));
|
|
||||||
},
|
|
||||||
|
|
||||||
"254 edits needed for a single line",
|
|
||||||
[] {
|
|
||||||
vec line, result;
|
|
||||||
for (int i = 0; i < 254; ++i)
|
|
||||||
line.insert(line.end(), {0,0,1});
|
|
||||||
result.push_back(254);
|
|
||||||
for (int i = 0; i < 254; ++i)
|
|
||||||
result.insert(result.end(), {sub(2,0),1});
|
|
||||||
EXPECT(( encode_line(line, vec(line.size())) == result ));
|
|
||||||
},
|
|
||||||
|
|
||||||
"Give up if more than 254 edits needed...",
|
|
||||||
[] {
|
|
||||||
vec line, result;
|
|
||||||
for (int i = 0; i < 255; ++i)
|
|
||||||
line.insert(line.end(), {0,0,1});
|
|
||||||
result.push_back(254);
|
|
||||||
for (int i = 0; i < 253; ++i)
|
|
||||||
result.insert(result.end(), {sub(2,0),1});
|
|
||||||
result.insert(result.end(), {sub(2,3),1,0,0,1});
|
|
||||||
EXPECT(( encode_line(line, vec(line.size())) == result ));
|
|
||||||
},
|
|
||||||
|
|
||||||
"Repeat command with overflow bytes",
|
|
||||||
[] {
|
|
||||||
vec line(3, 0);
|
|
||||||
line.insert(line.end(), 512, 1);
|
|
||||||
vec ref(line.size(), 0);
|
|
||||||
vec expected{1,rep(3,31),0,255,224,1};
|
|
||||||
EXPECT(encode_line(line, ref) == expected);
|
|
||||||
},
|
|
||||||
|
|
||||||
"Substitute command with overflow bytes",
|
|
||||||
[] {
|
|
||||||
vec expected{1,sub(15,7),255,0,255,237};
|
|
||||||
vec line(270, 0);
|
|
||||||
for (int i = 0; i < 250; ++i) {
|
|
||||||
expected.insert(expected.end(), {1,2});
|
|
||||||
line.insert(line.end(), {1,2});
|
|
||||||
}
|
|
||||||
vec ref(line.size(), 0);
|
|
||||||
EXPECT(encode_line(line, ref) == expected);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
return lest::run(specification);
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user