1
0
mirror of https://github.com/pdewacht/brlaser synced 2025-04-07 13:16:43 +02:00

Get rid of iconv()

PJL has a job name field. I don't think this is used for anything, but
just in case I want to put something human-readable there. But it's
also probably a good idea to keep this pure ASCII text.

Previously I used iconv() to convert the CUPS job name to ASCII. But:
- on FreeBSD, an explicit "-liconv" seems to be necessary (#10),
- there's an autoconf macro to deal with this, but it's tangled up
  with gettext and it seems like a hassle,
- the //TRANSLIT//IGNORE feature I used seems to be a GNU extension
  and probably won't work on other systems anyway.

So instead, let's just concatenate some job information together,
dropping any non-ASCII component. That's probably good enough.
This commit is contained in:
Peter De Wachter 2017-10-23 22:09:29 +02:00
parent 853db9e5a2
commit 931c677443

View File

@ -18,7 +18,6 @@
#include <stdio.h> #include <stdio.h>
#include <signal.h> #include <signal.h>
#include <locale.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>
@ -51,41 +50,37 @@ bool next_line(uint8_t *buf) {
return cupsRasterReadPixels(ras, buf, bytes) == bytes; return cupsRasterReadPixels(ras, buf, bytes) == bytes;
} }
// POSIX says the second argument of iconv has type 'char **', but bool plain_ascii_string(const char *str) {
// some systems have 'const char **'. This class is used to work bool result = true;
// around this incompatibility. for (; result && *str; str++) {
class sloppy_ptr { result = *str >= 32 && *str <= 126;
public: }
explicit sloppy_ptr(const char **ptr): ptr_(ptr) { } return result;
operator const char **() { return ptr_; } }
operator char **() { return const_cast<char **>(ptr_); }
private:
const char **ptr_;
};
std::string ascii_job_name(const char *job_name, const char *charset) { std::string ascii_job_name(const char *job_id, const char *job_user, const char *job_name) {
if (job_name && charset) { std::array<const char *, 3> parts = {{
iconv_t cd = iconv_open("ASCII//TRANSLIT//IGNORE", charset); job_id,
if (cd != (iconv_t) -1) { job_user,
char ascii[80]; job_name
const char *in_ptr = job_name; }};
size_t in_left = strlen(job_name); std::string result;
char *out_ptr = ascii; for (const char *part : parts) {
size_t out_left = sizeof(ascii) - 1; if (*part && plain_ascii_string(part)) {
while (in_left > 0) { if (!result.empty()) {
size_t err = iconv(cd, result += '/';
sloppy_ptr(&in_ptr), &in_left, }
&out_ptr, &out_left); result += part;
if (err == (size_t) -1) {
break;
} }
} }
*out_ptr = 0; if (result.empty()) {
iconv_close(cd); result = "brlaser";
return ascii;
} }
const int max_size = 79;
if (result.size() > max_size) {
result.resize(max_size);
} }
return "CUPS"; return result;
} }
page_params build_page_params() { page_params build_page_params() {
@ -139,13 +134,13 @@ int main(int argc, char *argv[]) {
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, ""); setlocale(LC_ALL, "");
@ -169,7 +164,7 @@ int main(int argc, char *argv[]) {
int pages = 0; int pages = 0;
{ {
job job(stdout, ascii_job_name(job_name, job_charset)); job job(stdout, ascii_job_name(job_id, job_user, job_name));
while (!interrupted && cupsRasterReadHeader2(ras, &header)) { while (!interrupted && cupsRasterReadHeader2(ras, &header)) {
if (header.cupsBitsPerPixel != 1 if (header.cupsBitsPerPixel != 1
|| header.cupsBitsPerColor != 1 || header.cupsBitsPerColor != 1