diff --git a/xcpt.c b/xcpt.c
index deca8dd9021e9a9c12cc66a7fa1ded157c485c5d..4dac72577ddfe8420ae9b3e0b6bb3d8be9e0a073 100644
--- a/xcpt.c
+++ b/xcpt.c
@@ -33,6 +33,8 @@ static void PRINTF(1,2) NONRET bug(const char *fmt, ...)
exit(1);
}
+#define ASSERT(_cond) do { if (!(_cond)) bug("Assertion failed: %s", #_cond); } while (0)
+
#if 0
static void PRINTF(1,2) error(const char *fmt, ...)
{
@@ -101,11 +103,11 @@ static void set_option(char *key, char *val)
for (int i=0; i<OPT_MAX; i++)
if (!strcmp(opt_names[i], key))
{
- debug("Setting %s=<%s>\n", key, val);
+ debug("Setting %s=<%s>", key, val);
opt[i] = xstrdup(val);
return;
}
- debug("Unrecognized option <%s>\n", key);
+ debug("Unrecognized option <%s>", key);
}
/**
@@ -231,6 +233,231 @@ static void parse_pjl(void)
}
}
+/*** XCPT generator ***/
+
+#define STACK_DEPTH 10
+
+static int xcpt_level;
+static const char *xcpt_stack[STACK_DEPTH];
+
+static void xcpt_start_line(void)
+{
+ printf("@PJL XCPT ");
+ for (int i=0; i<xcpt_level; i++)
+ putchar('\t');
+}
+
+static void xcpt_printf(const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+
+ xcpt_start_line();
+ vprintf(fmt, args);
+ putchar('\n');
+
+ va_end(args);
+}
+
+static void xcpt_push(const char *name)
+{
+ ASSERT(xcpt_level < STACK_DEPTH);
+ xcpt_stack[xcpt_level++] = xstrdup(name);
+}
+
+static void xcpt_open(const char *name)
+{
+ xcpt_printf("<%s>", name);
+ xcpt_push(name);
+}
+
+static void xcpt_close(void)
+{
+ ASSERT(xcpt_level);
+ const char *name = xcpt_stack[--xcpt_level];
+ xcpt_printf("</%s>", name);
+ free((char *) name);
+}
+
+static void xcpt_integer(const char *name, int value)
+{
+ xcpt_printf("<%s syntax=\"integer\">%d</%s>", name, value, name);
+}
+
+static void xcpt_keyword(const char *name, const char *value)
+{
+ xcpt_printf("<%s syntax=\"keyword\">%s</%s>", name, value, name);
+}
+
+static void xcpt_enum(const char *name, int value)
+{
+ xcpt_printf("<%s syntax=\"enum\">%d</%s>", name, value, name);
+}
+
+static void xcpt_media_type(const char *name, const char *value)
+{
+ xcpt_printf("<%s syntax=\"mimeMediaType\">%s</%s>", name, value, name);
+}
+
+static void xcpt_collection_open(const char *name)
+{
+ xcpt_printf("<%s syntax=\"collection\">", name);
+ xcpt_push(name);
+}
+
+static void xcpt_set_open(const char *name)
+{
+ xcpt_printf("<%s syntax=\"1setOf\">", name);
+ xcpt_push(name);
+}
+
+static void xcpt_cdata(const char *text)
+{
+ int c;
+ while (c = *text++)
+ switch (c)
+ {
+ case '<':
+ printf("<");
+ break;
+ case '>':
+ printf(">");
+ break;
+ case '&':
+ printf("&");
+ break;
+ case '"':
+ printf(""");
+ break;
+ default:
+ putchar(c);
+ }
+}
+
+static void xcpt_text(const char *name, const char *text)
+{
+ xcpt_start_line();
+ printf("<%s syntax=\"text\" xml:space=\"preserve\">", name);
+ xcpt_cdata(text);
+ printf("</%s>\n", name);
+}
+
+static void xcpt_name(const char *name, const char *text)
+{
+ xcpt_start_line();
+ printf("<%s syntax=\"name\" xml:space=\"preserve\">", name);
+ xcpt_cdata(text);
+ printf("</%s>\n", name);
+}
+
+static void gen_job_template(void)
+{
+ xcpt_integer("adjust-contrast", 0);
+ xcpt_integer("adjust-cyan-red", 0);
+ xcpt_integer("adjust-lightness", 0);
+ xcpt_integer("adjust-magenta-green", 0);
+ xcpt_integer("adjust-saturation", 0);
+ xcpt_integer("adjust-yellow-blue", 0);
+ xcpt_keyword("color-adjustment-set", "automatic");
+ xcpt_keyword("color-effects-type", "color");
+ xcpt_integer("copies", 1);
+ xcpt_keyword("document-reading-orientation", "portrait");
+ xcpt_keyword("embedded-profiles", "automatic");
+
+ xcpt_set_open("finishings");
+ xcpt_enum("value", 3);
+ xcpt_close();
+
+ xcpt_keyword("halftone-text", "ignore-pdl");
+ xcpt_keyword("hold-for-authentication", "none");
+
+ xcpt_collection_open("interleaved-sheets-col");
+ xcpt_keyword("interleaved-sheets-type", "none");
+ xcpt_close();
+
+ xcpt_set_open("job-offset");
+ xcpt_keyword("value", "offset-set");
+ xcpt_close();
+
+ xcpt_collection_open("job-save-disposition");
+ xcpt_keyword("save", "none");
+ xcpt_close();
+
+ xcpt_keyword("job-sheets", "job-start-sheet");
+
+ xcpt_collection_open("client-default-attributes-col");
+ xcpt_collection_open("media-col");
+ xcpt_keyword("input-tray", "automatic");
+ xcpt_keyword("media-color", "white");
+ xcpt_collection_open("media-size");
+ xcpt_integer("x-dimension", 21000);
+ xcpt_integer("y-dimension", 29700);
+ xcpt_close();
+ xcpt_keyword("media-type", "system-default");
+ xcpt_close();
+ xcpt_keyword("print-quality-level", "standard");
+ xcpt_keyword("sides", "two-sided-long-edge");
+ xcpt_close();
+
+ xcpt_keyword("output-bin", "automatic");
+ xcpt_keyword("print-settings", "none");
+ xcpt_keyword("rendering-intent-graphics", "automatic");
+ xcpt_keyword("rendering-intent-images", "automatic");
+ xcpt_keyword("rendering-intent-text", "automatic");
+ xcpt_keyword("sheet-collate", "collated");
+ xcpt_keyword("spot-color-mapping", "use-local-printer-values");
+ xcpt_keyword("undefined-source-cmyk-images", "automatic");
+ xcpt_keyword("undefined-source-cmyk-text", "automatic");
+ xcpt_keyword("undefined-source-gray-images", "automatic");
+ xcpt_keyword("undefined-source-gray-text", "automatic");
+ xcpt_keyword("undefined-source-rgb-images", "automatic");
+ xcpt_keyword("undefined-source-rgb-text", "automatic");
+ xcpt_keyword("undefined-spot-color-images", "automatic");
+ xcpt_keyword("undefined-spot-color-text", "automatic");
+}
+
+static void gen_job_operation(void)
+{
+ xcpt_keyword("creator-name-attributes", "windows-ps-driver");
+ xcpt_keyword("creator-name-pdl", "explorer");
+ xcpt_text("creator-version-attributes", "cups-xcpt");
+ xcpt_text("creator-version-pdl", "6.1.7601.17567"); // FIXME
+ xcpt_media_type("document-format", "application/postscript"); // FIXME
+ xcpt_name("job-id-from-client", "TOP SECRET JOB #1");
+ xcpt_name("job-name", "Test Page");
+ xcpt_name("job-originating-user-domain", "KAM");
+ xcpt_name("job-originating-user-name", "nobody");
+ xcpt_name("requesting-user-name", "nobody");
+}
+
+static void gen_xcpt(void)
+{
+ printf("\e%%-12345X@PJL JOB\n");
+ xcpt_printf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+ xcpt_printf("<!DOCTYPE xpif SYSTEM \"xpif-v02081.dtd\">");
+ xcpt_printf("<xpif version=\"1.0\" cpss-version=\"2.07\" xml:lang=\"en-US\">");
+ xcpt_push("xpif");
+
+ xcpt_open("job-template-attributes");
+ gen_job_template();
+ xcpt_close();
+
+ xcpt_open("job-operation-attributes");
+ gen_job_operation();
+ xcpt_close();
+
+ xcpt_close();
+ ASSERT(!xcpt_level);
+ printf("@PJL ENTER LANGUAGE = %s\n", opt[OPT_LANGUAGE]);
+}
+
+static void copy_body(void)
+{
+ // FIXME
+}
+
+/*** Main ***/
+
int main(int argc, char **argv)
{
if (argc < 5)
@@ -246,7 +473,9 @@ int main(int argc, char **argv)
parse_pjl();
for (int i=0; i<OPT_MAX; i++)
- DEBUG("Option %s=<%s>\n", opt_names[i], opt[i]);
+ DEBUG("Option %s=<%s>", opt_names[i], opt[i]);
+ gen_xcpt();
+ copy_body();
return 0;
}