int num_finishings = 0, /* Number of finishing values */
finishings[10]; /* Finishing enum values */
ppd_choice_t *choice; /* Marked choice */
- int finishings_copies = copies;
+ int finishings_copies = copies,
/* Number of copies for finishings */
+ job_pages = 0, /* job-pages value */
+ number_up = 1; /* number-up value */
+ const char *value; /* Option value */
/*
* Map finishing options...
*/
+ if (copies != finishings_copies)
+ {
+ // Figure out the proper job-pages-per-set value...
+ if ((value = cupsGetOption("job-pages", num_options, options)) == NULL)
+ value = cupsGetOption("com.apple.print.PrintSettings.PMTotalBeginPages..n.", num_options, options);
+
+ if (value)
+ job_pages = atoi(value);
+
+ // Adjust for number-up
+ if ((value = cupsGetOption("number-up", num_options, options)) != NULL)
+ number_up = atoi(value);
+
+ job_pages = (job_pages + number_up - 1) / number_up;
+
+ // When duplex printing, raster data will include an extra (blank) page to
+ // make the total number of pages even. Make sure this is reflected in the
+ // page count...
+ if ((job_pages & 1) && (keyword = cupsGetOption("sides", num_options, options)) != NULL && strcmp(keyword, "one-sided"))
+ job_pages ++;
+ }
+
if ((finishing_template = cupsGetOption("cupsFinishingTemplate", num_options, options)) == NULL)
finishing_template = cupsGetOption("finishing-template", num_options, options);
ippAddCollection(request, IPP_TAG_JOB, "finishings-col", fin_col);
ippDelete(fin_col);
- if (copies != finishings_copies && (keyword = cupsGetOption("job-impressions", num_options, options)) != NULL)
+ if (copies != finishings_copies && job_pages > 0)
{
/*
* Send job-pages-per-set attribute to apply finishings correctly...
*/
- ippAddInteger(request, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-pages-per-set", atoi(keyword) / finishings_copies);
+ ippAddInteger(request, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-pages-per-set", job_pages);
}
}
else
{
ippAddIntegers(request, IPP_TAG_JOB, IPP_TAG_ENUM, "finishings", num_finishings, finishings);
- if (copies != finishings_copies && (keyword = cupsGetOption("job-impressions", num_options, options)) != NULL)
+ if (copies != finishings_copies && job_pages > 0)
{
/*
* Send job-pages-per-set attribute to apply finishings correctly...
*/
- ippAddInteger(request, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-pages-per-set", atoi(keyword) / finishings_copies);
+ ippAddInteger(request, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-pages-per-set", job_pages);
}
}
}
* Convert the PPD size name to the corresponding PWG keyword name.
*/
- if ((pwg_media = pwgMediaForPPD(ppd_size->name)) != NULL)
+ if ((pwg_media = pwgMediaForSize(PWG_FROM_POINTS(ppd_size->width), PWG_FROM_POINTS(ppd_size->length))) != NULL)
{
/*
* Standard name, do we have conflicts?
* Add localized text for PWG keyword to message catalog...
*/
- snprintf(msg_id, sizeof(msg_id), "output-bin.%s", pwg_name);
+ snprintf(msg_id, sizeof(msg_id), "output-bin.%s", pwg_keyword);
pwg_add_message(pc->strings, msg_id, choice->text);
}
}
f;
f = (_pwg_finishings_t *)cupsArrayNext(pc->finishings))
{
- DEBUG_printf(("_ppdCacheGetFinishingValues: Checking %d (%s)", f->value, ippEnumString("finishings", f->value)));
+ DEBUG_printf(("_ppdCacheGetFinishingValues: Checking %d (%s)", (int)f->value, ippEnumString("finishings", (int)f->value)));
for (i = f->num_options, option = f->options; i > 0; i --, option ++)
{
if (i == 0)
{
- DEBUG_printf(("_ppdCacheGetFinishingValues: Adding %d (%s)", f->value, ippEnumString("finishings", f->value)));
+ DEBUG_printf(("_ppdCacheGetFinishingValues: Adding %d (%s)", (int)f->value, ippEnumString("finishings", (int)f->value)));
- values[num_values ++] = f->value;
+ values[num_values ++] = (int)f->value;
if (num_values >= max_values)
break;
if (pc->charge_info_uri)
cupsFilePutConf(fp, "ChargeInfoURI", pc->charge_info_uri);
- cupsFilePrintf(fp, "AccountId %s\n", pc->account_id ? "true" : "false");
- cupsFilePrintf(fp, "AccountingUserId %s\n",
+ cupsFilePrintf(fp, "JobAccountId %s\n", pc->account_id ? "true" : "false");
+ cupsFilePrintf(fp, "JobAccountingUserId %s\n",
pc->accounting_user_id ? "true" : "false");
if (pc->password)
- cupsFilePutConf(fp, "Password", pc->password);
+ cupsFilePutConf(fp, "JobPassword", pc->password);
for (value = (char *)cupsArrayFirst(pc->mandatory);
value;
httpClose(http);
}
+ /*
+ * Accounting...
+ */
+
+ if (ippGetBoolean(ippFindAttribute(response, "job-account-id-supported", IPP_TAG_BOOLEAN), 0))
+ cupsFilePuts(fp, "*cupsJobAccountId: True\n");
+
+ if (ippGetBoolean(ippFindAttribute(response, "job-accounting-user-id-supported", IPP_TAG_BOOLEAN), 0))
+ cupsFilePuts(fp, "*cupsJobAccountingUserId: True\n");
+
/*
* Password/PIN printing...
*/
pattern[maxlen] = '\0';
- cupsFilePrintf(fp, "*cupsPassword: \"%s\"\n", pattern);
+ cupsFilePrintf(fp, "*cupsJobPassword: \"%s\"\n", pattern);
}
/*
cupsFilePuts(fp, "*cupsFilter2: \"application/vnd.cups-pdf application/pdf 10 -\"\n");
}
else
- cupsFilePuts(fp, "*cupsManualCopies: true\n");
+ cupsFilePuts(fp, "*cupsManualCopies: True\n");
if (is_apple)
cupsFilePuts(fp, "*cupsFilter2: \"image/urf image/urf 100 -\"\n");
if (is_pwg)
if ((attr = ippFindAttribute(ippGetCollection(defattr, 0), "media-source", IPP_TAG_ZERO)) != NULL)
pwg_ppdize_name(ippGetString(attr, 0, NULL), ppdname, sizeof(ppdname));
else
- strlcpy(ppdname, "Unknown", sizeof(ppdname));
+ ppdname[0] = '\0';
if ((attr = ippFindAttribute(response, "media-source-supported", IPP_TAG_ZERO)) != NULL && (count = ippGetCount(attr)) > 1)
{
+ int have_default = ppdname[0] != '\0';
+ /* Do we have a default InputSlot? */
static const char * const sources[] =
{ /* Standard "media-source" strings */
"auto",
"roll-10"
};
- cupsFilePrintf(fp, "*OpenUI *InputSlot: PickOne\n"
- "*OrderDependency: 10 AnySetup *InputSlot\n"
- "*DefaultInputSlot: %s\n", ppdname);
- for (i = 0, count = ippGetCount(attr); i < count; i ++)
+ cupsFilePuts(fp, "*OpenUI *InputSlot: PickOne\n"
+ "*OrderDependency: 10 AnySetup *InputSlot\n");
+ if (have_default)
+ cupsFilePrintf(fp, "*DefaultInputSlot: %s\n", ppdname);
+
+ for (i = 0; i < count; i ++)
{
keyword = ippGetString(attr, i, NULL);
pwg_ppdize_name(keyword, ppdname, sizeof(ppdname));
+ if (i == 0 && !have_default)
+ cupsFilePrintf(fp, "*DefaultInputSlot: %s\n", ppdname);
+
for (j = 0; j < (int)(sizeof(sources) / sizeof(sources[0])); j ++)
if (!strcmp(sources[j], keyword))
{
snprintf(msgid, sizeof(msgid), "media-source.%s", keyword);
+
+ if ((msgstr = _cupsLangString(lang, msgid)) == msgid || !strcmp(msgid, msgstr))
+ if ((msgstr = _cupsMessageLookup(strings, msgid)) == msgid)
+ msgstr = keyword;
+
cupsFilePrintf(fp, "*InputSlot %s: \"<</MediaPosition %d>>setpagedevice\"\n", ppdname, j);
- cupsFilePrintf(fp, "*%s.InputSlot %s/%s: \"\"\n", lang->language, ppdname, _cupsLangString(lang, msgid));
+ cupsFilePrintf(fp, "*%s.InputSlot %s/%s: \"\"\n", lang->language, ppdname, msgstr);
break;
}
}
int wrote_color = 0;
const char *default_color = NULL; /* Default */
+ cupsFilePrintf(fp, "*%% ColorModel from %s\n", ippGetName(attr));
+
for (i = 0, count = ippGetCount(attr); i < count; i ++)
{
keyword = ippGetString(attr, i, NULL);
PRINTF_COLOROPTION("RGB", _("Color"), CUPS_CSPACE_SRGB, 8)
default_color = "RGB";
+
+ // Apparently some printers only advertise color support, so make sure
+ // we also do grayscale for these printers...
+ if (!ippContainsString(attr, "sgray_8") && !ippContainsString(attr, "black_1") && !ippContainsString(attr, "black_8") && !ippContainsString(attr, "W8") && !ippContainsString(attr, "W8-16"))
+ PRINTF_COLOROPTION("Gray", _("GrayScale"), CUPS_CSPACE_SW, 8)
}
else if (!strcasecmp(keyword, "adobe-rgb_16") || !strcmp(keyword, "ADOBERGB48") || !strcmp(keyword, "ADOBERGB24-48"))
{
else
strlcpy(ppdname, "Unknown", sizeof(ppdname));
- if ((attr = ippFindAttribute(response, "output-bin-supported", IPP_TAG_ZERO)) != NULL && (count = ippGetCount(attr)) > 1)
+ if ((attr = ippFindAttribute(response, "output-bin-supported", IPP_TAG_ZERO)) != NULL && (count = ippGetCount(attr)) > 0)
{
ipp_attribute_t *trays = ippFindAttribute(response, "printer-output-tray", IPP_TAG_STRING);
/* printer-output-tray attribute, if any */
if ((attr = ippFindAttribute(response, "finishings-supported", IPP_TAG_ENUM)) != NULL)
{
int value; /* Enum value */
+ const char *ppd_keyword; /* PPD keyword for enum */
cups_array_t *names; /* Names we've added */
+ static const char * const base_keywords[] =
+ { /* Base STD 92 keywords */
+ NULL, /* none */
+ "SingleAuto", /* staple */
+ "SingleAuto", /* punch */
+ NULL, /* cover */
+ "BindAuto", /* bind */
+ "SaddleStitch", /* saddle-stitch */
+ "EdgeStitchAuto", /* edge-stitch */
+ "Auto", /* fold */
+ NULL, /* trim */
+ NULL, /* bale */
+ NULL, /* booklet-maker */
+ NULL, /* jog-offset */
+ NULL, /* coat */
+ NULL /* laminate */
+ };
count = ippGetCount(attr);
names = cupsArrayNew3((cups_array_func_t)strcmp, NULL, NULL, 0, (cups_acopy_func_t)strdup, (cups_afree_func_t)free);
if (i < count)
{
+ static const char * const staple_keywords[] =
+ { /* StapleLocation keywords */
+ "SinglePortrait",
+ "SingleRevLandscape",
+ "SingleLandscape",
+ "SingleRevPortrait",
+ "EdgeStitchPortrait",
+ "EdgeStitchLandscape",
+ "EdgeStitchRevPortrait",
+ "EdgeStitchRevLandscape",
+ "DualPortrait",
+ "DualLandscape",
+ "DualRevPortrait",
+ "DualRevLandscape",
+ "TriplePortrait",
+ "TripleLandscape",
+ "TripleRevPortrait",
+ "TripleRevLandscape"
+ };
+ static const char * const bind_keywords[] =
+ { /* StapleLocation binding keywords */
+ "BindPortrait",
+ "BindLandscape",
+ "BindRevPortrait",
+ "BindRevLandscape"
+ };
+
cupsArrayAdd(fin_options, "*StapleLocation");
cupsFilePuts(fp, "*OpenUI *StapleLocation: PickOne\n");
if ((msgstr = _cupsMessageLookup(strings, msgid)) == msgid)
msgstr = keyword;
- cupsFilePrintf(fp, "*StapleLocation %s: \"\"\n", keyword);
- cupsFilePrintf(fp, "*%s.StapleLocation %s/%s: \"\"\n", lang->language, keyword, msgstr);
- cupsFilePrintf(fp, "*cupsIPPFinishings %d/%s: \"*StapleLocation %s\"\n", value, keyword, keyword);
+ if (value >= IPP_FINISHINGS_NONE && value <= IPP_FINISHINGS_LAMINATE)
+ ppd_keyword = base_keywords[value - IPP_FINISHINGS_NONE];
+ else if (value >= IPP_FINISHINGS_STAPLE_TOP_LEFT && value <= IPP_FINISHINGS_STAPLE_TRIPLE_BOTTOM)
+ ppd_keyword = staple_keywords[value - IPP_FINISHINGS_STAPLE_TOP_LEFT];
+ else if (value >= IPP_FINISHINGS_BIND_LEFT && value <= IPP_FINISHINGS_BIND_BOTTOM)
+ ppd_keyword = bind_keywords[value - IPP_FINISHINGS_BIND_LEFT];
+ else
+ ppd_keyword = NULL;
+
+ if (!ppd_keyword)
+ continue;
+
+ cupsFilePrintf(fp, "*StapleLocation %s: \"\"\n", ppd_keyword);
+ cupsFilePrintf(fp, "*%s.StapleLocation %s/%s: \"\"\n", lang->language, ppd_keyword, msgstr);
+ cupsFilePrintf(fp, "*cupsIPPFinishings %d/%s: \"*StapleLocation %s\"\n", value, keyword, ppd_keyword);
}
cupsFilePuts(fp, "*CloseUI: *StapleLocation\n");
value = ippGetInteger(attr, i);
keyword = ippEnumString("finishings", value);
- if (!strncmp(keyword, "fold-", 5))
+ if (!strncmp(keyword, "cups-fold-", 10) || !strcmp(keyword, "fold") || !strncmp(keyword, "fold-", 5))
break;
}
if (i < count)
{
+ static const char * const fold_keywords[] =
+ { /* FoldType keywords */
+ "Accordion",
+ "DoubleGate",
+ "Gate",
+ "Half",
+ "HalfZ",
+ "LeftGate",
+ "Letter",
+ "Parallel",
+ "XFold",
+ "RightGate",
+ "ZFold",
+ "EngineeringZ"
+ };
+
cupsArrayAdd(fin_options, "*FoldType");
cupsFilePuts(fp, "*OpenUI *FoldType: PickOne\n");
value = ippGetInteger(attr, i);
keyword = ippEnumString("finishings", value);
- if (strncmp(keyword, "fold-", 5))
+ if (!strncmp(keyword, "cups-fold-", 10))
+ keyword += 5;
+ else if (strcmp(keyword, "fold") && strncmp(keyword, "fold-", 5))
continue;
if (cupsArrayFind(names, (char *)keyword))
if ((msgstr = _cupsMessageLookup(strings, msgid)) == msgid)
msgstr = keyword;
- cupsFilePrintf(fp, "*FoldType %s: \"\"\n", keyword);
- cupsFilePrintf(fp, "*%s.FoldType %s/%s: \"\"\n", lang->language, keyword, msgstr);
- cupsFilePrintf(fp, "*cupsIPPFinishings %d/%s: \"*FoldType %s\"\n", value, keyword, keyword);
+ if (value >= IPP_FINISHINGS_NONE && value <= IPP_FINISHINGS_LAMINATE)
+ ppd_keyword = base_keywords[value - IPP_FINISHINGS_NONE];
+ else if (value >= IPP_FINISHINGS_FOLD_ACCORDION && value <= IPP_FINISHINGS_FOLD_ENGINEERING_Z)
+ ppd_keyword = fold_keywords[value - IPP_FINISHINGS_FOLD_ACCORDION];
+ else if (value >= IPP_FINISHINGS_CUPS_FOLD_ACCORDION && value <= IPP_FINISHINGS_CUPS_FOLD_Z)
+ ppd_keyword = fold_keywords[value - IPP_FINISHINGS_CUPS_FOLD_ACCORDION];
+ else
+ ppd_keyword = NULL;
+
+ if (!ppd_keyword)
+ continue;
+
+ cupsFilePrintf(fp, "*FoldType %s: \"\"\n", ppd_keyword);
+ cupsFilePrintf(fp, "*%s.FoldType %s/%s: \"\"\n", lang->language, ppd_keyword, msgstr);
+ cupsFilePrintf(fp, "*cupsIPPFinishings %d/%s: \"*FoldType %s\"\n", value, keyword, ppd_keyword);
}
cupsFilePuts(fp, "*CloseUI: *FoldType\n");
value = ippGetInteger(attr, i);
keyword = ippEnumString("finishings", value);
- if (!strncmp(keyword, "punch-", 6))
+ if (!strncmp(keyword, "cups-punch-", 11) || !strncmp(keyword, "punch-", 6))
break;
}
if (i < count)
{
+ static const char * const punch_keywords[] =
+ { /* PunchMedia keywords */
+ "SinglePortrait",
+ "SingleRevLandscape",
+ "SingleLandscape",
+ "SingleRevPortrait",
+ "DualPortrait",
+ "DualLandscape",
+ "DualRevPortrait",
+ "DualRevLandscape",
+ "TriplePortrait",
+ "TripleLandscape",
+ "TripleRevPortrait",
+ "TripleRevLandscape",
+ "QuadPortrait",
+ "QuadLandscape",
+ "QuadRevPortrait",
+ "QuadRevLandscape",
+ "MultiplePortrait",
+ "MultipleLandscape",
+ "MultipleRevPortrait",
+ "MultipleRevLandscape"
+ };
+
cupsArrayAdd(fin_options, "*PunchMedia");
cupsFilePuts(fp, "*OpenUI *PunchMedia: PickOne\n");
value = ippGetInteger(attr, i);
keyword = ippEnumString("finishings", value);
- if (strncmp(keyword, "punch-", 6))
+ if (!strncmp(keyword, "cups-punch-", 11))
+ keyword += 5;
+ else if (strncmp(keyword, "punch-", 6))
continue;
if (cupsArrayFind(names, (char *)keyword))
if ((msgstr = _cupsMessageLookup(strings, msgid)) == msgid)
msgstr = keyword;
- cupsFilePrintf(fp, "*PunchMedia %s: \"\"\n", keyword);
- cupsFilePrintf(fp, "*%s.PunchMedia %s/%s: \"\"\n", lang->language, keyword, msgstr);
- cupsFilePrintf(fp, "*cupsIPPFinishings %d/%s: \"*PunchMedia %s\"\n", value, keyword, keyword);
+ if (value >= IPP_FINISHINGS_NONE && value <= IPP_FINISHINGS_LAMINATE)
+ ppd_keyword = base_keywords[value - IPP_FINISHINGS_NONE];
+ else if (value >= IPP_FINISHINGS_PUNCH_TOP_LEFT && value <= IPP_FINISHINGS_PUNCH_MULTIPLE_BOTTOM)
+ ppd_keyword = punch_keywords[value - IPP_FINISHINGS_PUNCH_TOP_LEFT];
+ else if (value >= IPP_FINISHINGS_CUPS_PUNCH_TOP_LEFT && value <= IPP_FINISHINGS_CUPS_PUNCH_QUAD_BOTTOM)
+ ppd_keyword = punch_keywords[value - IPP_FINISHINGS_CUPS_PUNCH_TOP_LEFT];
+ else
+ ppd_keyword = NULL;
+
+ if (!ppd_keyword)
+ continue;
+
+ cupsFilePrintf(fp, "*PunchMedia %s: \"\"\n", ppd_keyword);
+ cupsFilePrintf(fp, "*%s.PunchMedia %s/%s: \"\"\n", lang->language, ppd_keyword, msgstr);
+ cupsFilePrintf(fp, "*cupsIPPFinishings %d/%s: \"*PunchMedia %s\"\n", value, keyword, ppd_keyword);
}
cupsFilePuts(fp, "*CloseUI: *PunchMedia\n");
cupsFilePuts(fp, "*CloseUI: *Booklet\n");
}
+ /*
+ * CutMedia
+ */
+
+ for (i = 0; i < count; i ++)
+ {
+ value = ippGetInteger(attr, i);
+ keyword = ippEnumString("finishings", value);
+
+ if (!strcmp(keyword, "trim") || !strncmp(keyword, "trim-", 5))
+ break;
+ }
+
+ if (i < count)
+ {
+ static const char * const trim_keywords[] =
+ { /* CutMedia keywords */
+ "EndOfPage",
+ "EndOfDoc",
+ "EndOfSet",
+ "EndOfJob"
+ };
+
+ cupsArrayAdd(fin_options, "*CutMedia");
+
+ cupsFilePuts(fp, "*OpenUI *CutMedia: PickOne\n");
+ cupsFilePuts(fp, "*OrderDependency: 10 AnySetup *CutMedia\n");
+ cupsFilePrintf(fp, "*%s.Translation CutMedia/%s: \"\"\n", lang->language, _cupsLangString(lang, _("Cut")));
+ cupsFilePuts(fp, "*DefaultCutMedia: None\n");
+ cupsFilePuts(fp, "*CutMedia None: \"\"\n");
+ cupsFilePrintf(fp, "*%s.CutMedia None/%s: \"\"\n", lang->language, _cupsLangString(lang, _("None")));
+
+ for (i = 0; i < count; i ++)
+ {
+ value = ippGetInteger(attr, i);
+ keyword = ippEnumString("finishings", value);
+
+ if (strcmp(keyword, "trim") && strncmp(keyword, "trim-", 5))
+ continue;
+
+ if (cupsArrayFind(names, (char *)keyword))
+ continue; /* Already did this finishing template */
+
+ cupsArrayAdd(names, (char *)keyword);
+
+ snprintf(msgid, sizeof(msgid), "finishings.%d", value);
+ if ((msgstr = _cupsLangString(lang, msgid)) == msgid || !strcmp(msgid, msgstr))
+ if ((msgstr = _cupsMessageLookup(strings, msgid)) == msgid)
+ msgstr = keyword;
+
+ if (value == IPP_FINISHINGS_TRIM)
+ ppd_keyword = "Auto";
+ else
+ ppd_keyword = trim_keywords[value - IPP_FINISHINGS_TRIM_AFTER_PAGES];
+
+ cupsFilePrintf(fp, "*CutMedia %s: \"\"\n", ppd_keyword);
+ cupsFilePrintf(fp, "*%s.CutMedia %s/%s: \"\"\n", lang->language, ppd_keyword, msgstr);
+ cupsFilePrintf(fp, "*cupsIPPFinishings %d/%s: \"*CutMedia %s\"\n", value, keyword, ppd_keyword);
+ }
+
+ cupsFilePuts(fp, "*CloseUI: *CutMedia\n");
+ }
+
cupsArrayDelete(names);
}
if (!keyword || cupsArrayFind(templates, (void *)keyword))
continue;
- if (strncmp(keyword, "fold-", 5) && (strstr(keyword, "-bottom") || strstr(keyword, "-left") || strstr(keyword, "-right") || strstr(keyword, "-top")))
+ if (!strcmp(keyword, "none"))
continue;
cupsArrayAdd(templates, (void *)keyword);
{
char *ptr, /* Pointer into name buffer */
*end; /* End of name buffer */
+ int nodash = 1; /* Next char in IPP name cannot be a
+ dash (first char or after a dash) */
if (_cups_islower(*ppd))
const char *ppdptr; /* Pointer into PPD keyword */
for (ppdptr = ppd + 1; *ppdptr; ppdptr ++)
- if (_cups_isupper(*ppdptr) || strchr(dashchars, *ppdptr))
+ if (_cups_isupper(*ppdptr) || strchr(dashchars, *ppdptr) ||
+ (*ppdptr == '-' && *(ppdptr - 1) == '-') ||
+ (*ppdptr == '-' && *(ppdptr + 1) == '\0'))
break;
if (!*ppdptr)
for (ptr = name, end = name + namesize - 1; *ppd && ptr < end; ppd ++)
{
- if (_cups_isalnum(*ppd) || *ppd == '-')
+ if (_cups_isalnum(*ppd))
+ {
*ptr++ = (char)tolower(*ppd & 255);
- else if (strchr(dashchars, *ppd))
- *ptr++ = '-';
+ nodash = 0;
+ }
+ else if (*ppd == '-' || strchr(dashchars, *ppd))
+ {
+ if (nodash == 0)
+ {
+ *ptr++ = '-';
+ nodash = 1;
+ }
+ }
else
+ {
*ptr++ = *ppd;
+ nodash = 0;
+ }
- if (!_cups_isupper(*ppd) && _cups_isalnum(*ppd) &&
- _cups_isupper(ppd[1]) && ptr < end)
- *ptr++ = '-';
- else if (!isdigit(*ppd & 255) && isdigit(ppd[1] & 255))
- *ptr++ = '-';
+ if (nodash == 0)
+ {
+ if (!_cups_isupper(*ppd) && _cups_isalnum(*ppd) &&
+ _cups_isupper(ppd[1]) && ptr < end)
+ {
+ *ptr++ = '-';
+ nodash = 1;
+ }
+ else if (!isdigit(*ppd & 255) && isdigit(ppd[1] & 255))
+ {
+ *ptr++ = '-';
+ nodash = 1;
+ }
+ }
}
+ /* Remove trailing dashes */
+ while (ptr > name && *(ptr - 1) == '-')
+ ptr --;
+
*ptr = '\0';
}