Skip to content
Snippets Groups Projects
Commit aa418630 authored by Martin Mareš's avatar Martin Mareš
Browse files

Initial version

Currently, we are just parsing PJL and gathering options.
More to come...
parents
No related branches found
No related tags found
No related merge requests found
CC=gcc
CFLAGS=-O2 -Wall -W -Wno-parentheses -Wstrict-prototypes -Wmissing-prototypes -Wundef -Wredundant-decls -std=gnu99
all: xcpt
clean:
rm -f `find . -name "*~" -or -name "*.[oa]" -or -name TAGS -or -name core -or -name .depend -or -name .#*`
rm -f xcpt
xcpt.c 0 → 100644
/*
* CUPS Filter Generating XCPT
*
* (c) 2016 Martin Mares <mj@ucw.cz>
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#define PRINTF(i,j) __attribute__((format(printf,i,j)))
#define NONRET __attribute__((noreturn))
/*** Utility functions ***/
static void PRINTF(1,2) NONRET bug(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
fprintf(stderr, "ERROR: ");
vfprintf(stderr, fmt, args);
fputc('\n', stderr);
va_end(args);
exit(1);
}
#if 0
static void PRINTF(1,2) error(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
fprintf(stderr, "ERROR: ");
vfprintf(stderr, fmt, args);
fputc('\n', stderr);
va_end(args);
}
#endif
static void PRINTF(1,2) debug(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
fprintf(stderr, "DEBUG: ");
vfprintf(stderr, fmt, args);
fputc('\n', stderr);
va_end(args);
}
static char *xstrdup(const char *x)
{
char *p = strdup(x);
if (!p)
bug("Out of memory");
return p;
}
/*** Options ***/
#define OPTIONS \
O(LANGUAGE, "?") \
O(MEDIASIZE, "A4")
enum option {
#define O(name, val) OPT_##name,
OPTIONS
#undef O
OPT_MAX
};
const char *opt_names[] = {
#define O(name, val) #name,
OPTIONS
#undef O
};
char *opt[] = {
#define O(name, val) [OPT_##name] = val,
OPTIONS
#undef O
};
static void set_option(char *key, char *val)
{
for (int i=0; i<OPT_MAX; i++)
if (!strcmp(opt_names[i], key))
{
opt[i] = xstrdup(val);
return;
}
debug("SET: Unrecognized option <%s>\n", key);
}
/*** PJL parser ***/
#define LINESIZE 256
static char *skip_spaces(char *p)
{
while (*p == ' ' || *p == '\t')
p++;
return p;
}
static int my_toupper(int c)
{
if (c >= 'a' && c <= 'z')
return c - 32;
else
return c;
}
static char *token_buf;
static char *get_token(char **pp)
{
char *token_start = token_buf;
char *tok = token_start;
char *p = skip_spaces(*pp);
if (!*p)
return NULL;
int c = my_toupper(*p);
if (c >= 'A' && c <= 'Z' || c >= '0' && c <= '9')
{
while (c >= 'A' && c <= 'Z' || c >= '0' && c <= '9')
{
*tok++ = c;
c = my_toupper(*++p);
}
}
else
*tok++ = *p++;
*tok++ = 0;
*pp = skip_spaces(p);
token_buf = tok;
return token_start;
}
static void parse_pjl(void)
{
static const char uel[] = "\e%-12345X";
for (int i=0; uel[i]; i++)
if (getchar() != uel[i])
bug("PJL error: No UEL found (pos %u)", i);
char line[LINESIZE], tokens[2*LINESIZE];
for (;;)
{
int i = 0;
for (;;)
{
int c = getchar();
if (c < 0)
bug("PJL error: Premature EOF");
if (i < 4 && c != "@PJL"[i])
bug("PJL error: Unrecognized line");
if (c == '\r')
continue;
if (c == '\n')
{
line[i] = 0;
break;
}
if (i >= LINESIZE-1)
bug("PJL error: Line too long");
line[i++] = c;
}
debug("PJL: %s", line);
char *p = line+1;
token_buf = tokens;
char *t;
if (!(t = get_token(&p)) || strcasecmp(t, "PJL"))
bug("PJL error: Malformed line");
if (!(t = get_token(&p)))
continue;
if (!strcasecmp(t, "ENTER"))
{
char *t2 = get_token(&p);
if (t2 && !strcasecmp(t2, "LANGUAGE"))
{
char *t3 = get_token(&p);
if (t3 && !strcasecmp(t3, "="))
{
set_option("LANGUAGE", p);
break;
}
}
}
if (!strcasecmp(t, "SET"))
{
char *t2 = get_token(&p);
if (t2)
{
char *t3 = get_token(&p);
if (t3 && !strcasecmp(t3, "="))
{
if (*p == '"')
{
*p++ = 0;
char *q = p;
while (*q && *q != '"')
q++;
if (*q)
*q = 0;
}
set_option(t2, p);
}
}
}
}
}
int main(int argc, const char **argv)
{
if (argc < 5)
{
fprintf(stderr, "Usage: xcpt <job> <user> <title> <num-copies> [<options>]\n");
return 1;
}
(void) argv; // FIXME
parse_pjl();
for (int i=0; i<OPT_MAX; i++)
debug("Option %s=<%s>\n", opt_names[i], opt[i]);
return 0;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment