From 880fec09182a500b7e19b5b1c73189040cf3421a Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Thu, 20 Nov 2014 12:13:02 -0600 Subject: Greatly increase database generation speed from compressed PPDs where possible --- tdeprint/cups/CMakeLists.txt | 4 +- tdeprint/cups/Makefile.am | 4 +- tdeprint/cups/make_driver_db_cups.c | 274 -------------------------- tdeprint/cups/make_driver_db_cups.cpp | 351 ++++++++++++++++++++++++++++++++++ 4 files changed, 355 insertions(+), 278 deletions(-) delete mode 100644 tdeprint/cups/make_driver_db_cups.c create mode 100644 tdeprint/cups/make_driver_db_cups.cpp (limited to 'tdeprint/cups') diff --git a/tdeprint/cups/CMakeLists.txt b/tdeprint/cups/CMakeLists.txt index aa882ca7e..6e2751c41 100644 --- a/tdeprint/cups/CMakeLists.txt +++ b/tdeprint/cups/CMakeLists.txt @@ -72,12 +72,12 @@ tde_add_kpart( ${target} AUTOMOC set( target make_driver_db_cups ) set( ${target}_SRCS - make_driver_db_cups.c + make_driver_db_cups.cpp ) tde_add_executable( ${target} SOURCES ${${target}_SRCS} - LINK driverparse-static tdefakes-shared ${ZLIB_LIBRARIES} ${DL_LIBRARIES} + LINK driverparse-static tdefakes-shared ${ZLIB_LIBRARIES} ${DL_LIBRARIES} ${TQT_LIBRARIES} DESTINATION ${BIN_INSTALL_DIR} ) diff --git a/tdeprint/cups/Makefile.am b/tdeprint/cups/Makefile.am index 8932dbdcb..789a32093 100644 --- a/tdeprint/cups/Makefile.am +++ b/tdeprint/cups/Makefile.am @@ -26,8 +26,8 @@ noinst_HEADERS = cupsinfos.h ipprequest.h kmcupsjobmanager.h kmcupsmanager.h kmc kmwother.h ippreportdlg.h kptagspage.h bin_PROGRAMS = make_driver_db_cups cupsdoprint -make_driver_db_cups_SOURCES = make_driver_db_cups.c -make_driver_db_cups_LDADD = ../libdriverparse.a $(top_builddir)/tdecore/libtdefakes.la $(LIBDL) $(LIBZ) +make_driver_db_cups_SOURCES = make_driver_db_cups.cpp +make_driver_db_cups_LDADD = ../libdriverparse.a $(top_builddir)/tdecore/libtdefakes.la $(LIBDL) $(LIBZ) $(LIB_QT) make_driver_db_cups_LDFLAGS = $(all_libraries) cupsdoprint_SOURCES = cupsdoprint.c diff --git a/tdeprint/cups/make_driver_db_cups.c b/tdeprint/cups/make_driver_db_cups.c deleted file mode 100644 index 0a0160275..000000000 --- a/tdeprint/cups/make_driver_db_cups.c +++ /dev/null @@ -1,274 +0,0 @@ -/* - * This file is part of the KDE libraries - * Copyright (c) 2001 Michael Goffioul - * Copyright (c) 2014 Timothy Pearson - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License version 2 as published by the Free Software Foundation. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - **/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "driverparse.h" - -#define PROCESS_PPD_FILE_CONTENTS \ - memset(value,0,256); \ - c1 = strchr(line,':'); \ - if (c1) \ - { \ - c2 = strchr(c1,'"'); \ - if (c2) \ - { \ - c2++; \ - c1 = strchr(c2,'"'); \ - if (c1) strlcpy(value,c2,c1-c2+1); \ - } \ - else \ - { \ - c1++; \ - while (*c1 && isspace(*c1)) \ - c1++; \ - if (!*c1) \ - continue; \ - c2 = line+strlen(line)-1; /* point to \n */ \ - while (*c2 && isspace(*c2)) \ - c2--; \ - strlcpy(value,c1,c2-c1+2); \ - } \ - } \ - count++; \ - if (strncmp(line,"*Manufacturer:",14) == 0) fprintf(output_file,"MANUFACTURER=%s\n",value); \ - else if (strncmp(line,"*ShortNickName:",15) == 0) fprintf(output_file,"MODEL=%s\n",value); \ - else if (strncmp(line,"*ModelName:",11) == 0) fprintf(output_file,"MODELNAME=%s\n",value); \ - else if (strncmp(line,"*NickName:",10) == 0) strncat(desc,value,255-strlen(desc)); \ - else if (strncmp(line,"*pnpManufacturer:",17) == 0) fprintf(output_file,"PNPMANUFACTURER=%s\n",value); \ - else if (strncmp(line,"*pnpModel:",10) == 0) fprintf(output_file,"PNPMODEL=%s\n",value); \ - else if (strncmp(line,"*LanguageVersion:",17) == 0) strncat(langver,value,63-strlen(langver)); \ - else count--; \ - /* Either we got everything we needed, or we encountered an "OpenUI" directive \ - * and it's reasonable to assume that there's no needed info further in the file, \ - * just stop here */ \ - if (count >= 7 || strncmp(line, "*OpenUI", 7) == 0) \ - { \ - if (strlen(langver) > 0) \ - { \ - strncat(desc, " [", 255-strlen(desc)); \ - strncat(desc, langver, 255-strlen(desc)); \ - strncat(desc, "]", 255-strlen(desc)); \ - } \ - if (strlen(desc) > 0) \ - fprintf(output_file, "DESCRIPTION=%s\n", desc); \ - break; \ - } - -void initPpd(const char *dirname) -{ - struct stat stat_res; - if (stat(dirname, &stat_res) == -1) { - fprintf(stderr, "Can't open drivers directory : %s\n", dirname); - return; - } - - if (S_ISDIR(stat_res.st_mode)) { - DIR *dir = opendir(dirname); - struct dirent *entry; - char buffer[4096] = {0}; - char drFile[256]; - int len = strlen(dirname); - - if (dir == NULL) - { - fprintf(stderr, "Can't open drivers directory : %s\n", dirname); - return; - } - while ((entry=readdir(dir)) != NULL) - { - if (strcmp(entry->d_name,".") == 0 || strcmp(entry->d_name,"..") == 0) - { - continue; - } - if (len+strlen(entry->d_name)+1 < 4096) - { - struct stat st; - - strcpy(buffer,dirname); - strcat(buffer,"/"); - strcat(buffer,entry->d_name); - if (stat(buffer,&st) == 0) - { - if (S_ISDIR(st.st_mode)) - { - initPpd(buffer); - } - else if (S_ISREG(st.st_mode)) - { - char *c = strrchr(buffer,'.'); - snprintf(drFile, 255, "ppd:%s", buffer); - if (c && strncmp(c,".ppd",4) == 0) - { - addFile(drFile, ""); - } - else if (c && strncmp(c, ".gz", 3) == 0) - { /* keep also compressed driver files */ - while (c != buffer) - { - if (*(--c) == '.') break; - } - if (*c == '.' && strncmp(c, ".ppd",4) == 0) - { - addFile(drFile, ""); - } - } - } - } - } - } - closedir(dir); - } - else if (access(dirname, X_OK) != -1) { - char *filename; - int n = strlen(dirname)+strlen(" list"); - filename = (char*)malloc(n*sizeof(char)+1); - memset(filename,0,n); - strcat(filename, dirname); - strcat(filename, " list"); - - FILE* file = popen(filename, "r"); - if (file) { - char * line = NULL; - size_t len = 0; - ssize_t read; - while ((read = getline(&line, &len, file)) != -1) { - char * pos1 = strstr(line, "\""); - if (pos1 >= 0) { - char * pos2 = strstr(pos1 + 1, "\""); - if (pos2 >= 0) { - *pos2 = 0; - char * pos3 = strstr(pos1 + 1, ":"); - if (pos3 >= 0) { - char *ppduri; - int n2 = strlen("compressed-ppd:")+strlen(pos3+1); - ppduri = (char*)malloc(n2*sizeof(char)+1); - memset(ppduri,0,n2); - strcat(ppduri, "compressed-ppd:"); - strcat(ppduri, pos3+1); - addFile(ppduri, dirname); - free(ppduri); - ppduri = NULL; - } - } - } - } - if (line) { - free(line); - } - - pclose(file); - } - else { - fprintf(stderr, "Can't execute compressed driver handler : %s\n", dirname); - } - - free(filename); - filename = NULL; - } - else { - fprintf(stderr, "Can't open drivers directory : %s\n", dirname); - return; - } -} - -int parsePpdFile(const char *filename, const char *origin, FILE *output_file) -{ - gzFile ppd_file; - char line[4096], value[256], langver[64] = {0}, desc[256] = {0}; - char *c1, *c2; - int count = 0; - - ppd_file = gzopen(filename,"r"); - if (ppd_file == NULL) - { - fprintf(stderr, "Can't open driver file : %s\n", filename); - return 0; - } - fprintf(output_file,"FILE=ppd:%s\n",filename); - - while (gzgets(ppd_file,line,4095) != Z_NULL) - { - PROCESS_PPD_FILE_CONTENTS - } - fprintf(output_file,"\n"); - - gzclose(ppd_file); - return 1; -} - -int parseCompressedPpdFile(const char *ppdfilename, const char *origin, FILE *output_file) -{ - char value[256], langver[64] = {0}, desc[256] = {0}; - char *c1, *c2; - int count = 0; - - char *filename; - int n = strlen(origin)+strlen(" cat ")+strlen(ppdfilename); - filename = (char*)malloc(n*sizeof(char)+1); - memset(filename,0,n); - strcat(filename, origin); - strcat(filename, " cat "); - strcat(filename, ppdfilename); - - FILE* file = popen(filename, "r"); - if (file) { - char * line = NULL; - size_t len = 0; - ssize_t read; - - fprintf(output_file,"FILE=compressed-ppd:%s:%s\n", origin, ppdfilename); - - while ((read = getline(&line, &len, file)) != -1) { - PROCESS_PPD_FILE_CONTENTS - } - if (line) { - free(line); - } - - pclose(file); - } - else { - fprintf(stderr, "Can't open driver file : %s\n", ppdfilename); - return 0; - } - - free(filename); - filename = NULL; - - return 1; -} - -int main(int argc, char *argv[]) -{ - registerHandler("ppd:", initPpd, parsePpdFile); - registerHandler("compressed-ppd:", initPpd, parseCompressedPpdFile); - initFoomatic(); - return execute(argc, argv); -} diff --git a/tdeprint/cups/make_driver_db_cups.cpp b/tdeprint/cups/make_driver_db_cups.cpp new file mode 100644 index 000000000..021c77b95 --- /dev/null +++ b/tdeprint/cups/make_driver_db_cups.cpp @@ -0,0 +1,351 @@ +/* + * This file is part of the KDE libraries + * Copyright (c) 2001 Michael Goffioul + * Copyright (c) 2014 Timothy Pearson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License version 2 as published by the Free Software Foundation. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + **/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +extern "C" { + #include "driverparse.h" +} + +#define PROCESS_PPD_FILE_CONTENTS \ + memset(value,0,256); \ + c1 = strchr(line,':'); \ + if (c1) \ + { \ + c2 = strchr(c1,'"'); \ + if (c2) \ + { \ + c2++; \ + c1 = strchr(c2,'"'); \ + if (c1) strlcpy(value,c2,c1-c2+1); \ + } \ + else \ + { \ + c1++; \ + while (*c1 && isspace(*c1)) \ + c1++; \ + if (!*c1) \ + continue; \ + c2 = line+strlen(line)-1; /* point to \n */ \ + while (*c2 && isspace(*c2)) \ + c2--; \ + strlcpy(value,c1,c2-c1+2); \ + } \ + } \ + count++; \ + if (strncmp(line,"*Manufacturer:",14) == 0) fprintf(output_file,"MANUFACTURER=%s\n",value); \ + else if (strncmp(line,"*ShortNickName:",15) == 0) fprintf(output_file,"MODEL=%s\n",value); \ + else if (strncmp(line,"*ModelName:",11) == 0) fprintf(output_file,"MODELNAME=%s\n",value); \ + else if (strncmp(line,"*NickName:",10) == 0) strncat(desc,value,255-strlen(desc)); \ + else if (strncmp(line,"*pnpManufacturer:",17) == 0) fprintf(output_file,"PNPMANUFACTURER=%s\n",value); \ + else if (strncmp(line,"*pnpModel:",10) == 0) fprintf(output_file,"PNPMODEL=%s\n",value); \ + else if (strncmp(line,"*LanguageVersion:",17) == 0) strncat(langver,value,63-strlen(langver)); \ + else count--; \ + /* Either we got everything we needed, or we encountered an "OpenUI" directive \ + * and it's reasonable to assume that there's no needed info further in the file, \ + * just stop here */ \ + if (count >= 7 || strncmp(line, "*OpenUI", 7) == 0) \ + { \ + if (strlen(langver) > 0) \ + { \ + strncat(desc, " [", 255-strlen(desc)); \ + strncat(desc, langver, 255-strlen(desc)); \ + strncat(desc, "]", 255-strlen(desc)); \ + } \ + if (strlen(desc) > 0) \ + fprintf(output_file, "DESCRIPTION=%s\n", desc); \ + break; \ + } + +void initPpd(const char *dirname) +{ + struct stat stat_res; + if (stat(dirname, &stat_res) == -1) { + fprintf(stderr, "Can't open drivers directory : %s\n", dirname); + return; + } + + if (S_ISDIR(stat_res.st_mode)) { + DIR *dir = opendir(dirname); + struct dirent *entry; + char buffer[4096] = {0}; + char drFile[256]; + int len = strlen(dirname); + + if (dir == NULL) + { + fprintf(stderr, "Can't open drivers directory : %s\n", dirname); + return; + } + while ((entry=readdir(dir)) != NULL) + { + if (strcmp(entry->d_name,".") == 0 || strcmp(entry->d_name,"..") == 0) + { + continue; + } + if (len+strlen(entry->d_name)+1 < 4096) + { + struct stat st; + + strcpy(buffer,dirname); + strcat(buffer,"/"); + strcat(buffer,entry->d_name); + if (stat(buffer,&st) == 0) + { + if (S_ISDIR(st.st_mode)) + { + initPpd(buffer); + } + else if (S_ISREG(st.st_mode)) + { + char *c = strrchr(buffer,'.'); + snprintf(drFile, 255, "ppd:%s", buffer); + if (c && strncmp(c,".ppd",4) == 0) + { + addFile(drFile, "", ""); + } + else if (c && strncmp(c, ".gz", 3) == 0) + { /* keep also compressed driver files */ + while (c != buffer) + { + if (*(--c) == '.') break; + } + if (*c == '.' && strncmp(c, ".ppd",4) == 0) + { + addFile(drFile, "", ""); + } + } + } + } + } + } + closedir(dir); + } + else if (access(dirname, X_OK) != -1) { + char *filename; + int n = strlen(dirname)+strlen(" list"); + filename = (char*)malloc(n*sizeof(char)+1); + memset(filename,0,n); + strcat(filename, dirname); + strcat(filename, " list"); + + FILE* file = popen(filename, "r"); + if (file) { + char * line = NULL; + size_t len = 0; + ssize_t read; + while ((read = getline(&line, &len, file)) != -1) { + char * pos1 = strstr(line, "\""); + if (pos1 != NULL) { + char * pos2 = strstr(pos1 + 1, "\""); + if (pos2 != NULL) { + *pos2 = 0; + char * pos3 = strstr(pos1 + 1, ":"); + if (pos3 != NULL) { + char *ppduri; + int n2 = strlen("compressed-ppd:")+strlen(pos3+1); + ppduri = (char*)malloc(n2*sizeof(char)+1); + memset(ppduri,0,n2); + strcat(ppduri, "compressed-ppd:"); + strcat(ppduri, pos3+1); + addFile(ppduri, dirname, pos2+1); + free(ppduri); + ppduri = NULL; + } + } + } + } + if (line) { + free(line); + } + + pclose(file); + } + else { + fprintf(stderr, "Can't execute compressed driver handler : %s\n", dirname); + } + + free(filename); + filename = NULL; + } + else { + fprintf(stderr, "Can't open drivers directory : %s\n", dirname); + return; + } +} + +int parsePpdFile(const char *filename, const char *origin, const char *metadata, FILE *output_file) +{ + gzFile ppd_file; + char line[4096], value[256], langver[64] = {0}, desc[256] = {0}; + char *c1, *c2; + int count = 0; + + ppd_file = gzopen(filename,"r"); + if (ppd_file == NULL) + { + fprintf(stderr, "Can't open driver file : %s\n", filename); + return 0; + } + fprintf(output_file,"FILE=ppd:%s\n",filename); + + while (gzgets(ppd_file,line,4095) != Z_NULL) + { + PROCESS_PPD_FILE_CONTENTS + } + fprintf(output_file,"\n"); + + gzclose(ppd_file); + return 1; +} + +int parseCompressedPpdFile(const char *ppdfilename, const char *origin, const char *metadata, FILE *output_file) +{ + char value[256], langver[64] = {0}, desc[256] = {0}; + char *c1, *c2; + int count = 0; + + bool useFallbackExtractionMethod = false; + + if (strlen(metadata) > 0) { + TQString metadataProcessed(metadata); + metadataProcessed = metadataProcessed.stripWhiteSpace(); + TQStringList metadataList = TQStringList::split(" ", metadataProcessed, TRUE); + TQLocale ppdLanguage(metadataList[0]); + TQString languageVersion = TQLocale::languageToString(ppdLanguage.language()); + metadataList = TQStringList::split("\" \"", metadataProcessed, TRUE); + TQString description = metadataList[1]; + + int pos = metadataProcessed.find("MFG:"); + if (pos < 0) { + pos = metadataProcessed.find("MANUFACTURER:"); + } + if (pos >= 0) { + TQString manufacturer; + TQString model; + TQString modelName; + TQString pnpManufacturer; + TQString pnpModel; + TQString driver; + TQStringList metadataList = TQStringList::split(";", metadataProcessed.mid(pos), TRUE); + for (TQStringList::Iterator it = metadataList.begin(); it != metadataList.end(); ++it) { + TQStringList kvPair = TQStringList::split(":", *it, TRUE); + if ((kvPair[0].upper() == "MFG") || (kvPair[0].upper() == "MANUFACTURER")) { + manufacturer = kvPair[1]; + } + else if ((kvPair[0].upper() == "MDL") ||(kvPair[0].upper() == "MODEL")) { + modelName = kvPair[1]; + } +// else if (kvPair[0].upper() == "PNPMANUFACTURER") { +// pnpManufacturer = kvPair[1]; +// } +// else if (kvPair[0].upper() == "PNPMODEL") { +// pnpModel = kvPair[1]; +// } + else if ((kvPair[0].upper() == "DRV") || (kvPair[0].upper() == "DRIVER")) { + driver = kvPair[1]; + } + } + + TQStringList driverList = TQStringList::split(",", driver, TRUE); + driver = driverList[0]; + if (driver.startsWith("D")) { + driver = driver.mid(1); + } + model = manufacturer + " " + modelName + " " + driver; + description = description + " [" + languageVersion + "]"; + + fprintf(output_file,"FILE=compressed-ppd:%s:%s\n", origin, ppdfilename); + + fprintf(output_file,"MANUFACTURER=%s\n",manufacturer.ascii()); + fprintf(output_file,"MODELNAME=%s\n",modelName.ascii()); + fprintf(output_file,"MODEL=%s\n",model.ascii()); + if (pnpManufacturer.length() > 0) { + fprintf(output_file,"PNPMANUFACTURER=%s\n",pnpManufacturer.ascii()); + } + if (pnpModel.length() > 0) { + fprintf(output_file,"PNPMODEL=%s\n",pnpModel.ascii()); + } + if (description.length() > 0) { + fprintf(output_file,"DESCRIPTION=%s\n",description.ascii()); + } + } + else { + useFallbackExtractionMethod = true; + } + } + + if (useFallbackExtractionMethod) { + char *filename; + int n = strlen(origin)+strlen(" cat ")+strlen(ppdfilename); + filename = (char*)malloc(n*sizeof(char)+1); + memset(filename,0,n); + strcat(filename, origin); + strcat(filename, " cat "); + strcat(filename, ppdfilename); + + FILE* file = popen(filename, "r"); + if (file) { + char * line = NULL; + size_t len = 0; + ssize_t read; + + fprintf(output_file,"FILE=compressed-ppd:%s:%s\n", origin, ppdfilename); + + while ((read = getline(&line, &len, file)) != -1) { + PROCESS_PPD_FILE_CONTENTS + } + if (line) { + free(line); + } + + pclose(file); + } + else { + fprintf(stderr, "Can't open driver file : %s\n", ppdfilename); + return 0; + } + + free(filename); + filename = NULL; + } + + return 1; +} + +int main(int argc, char *argv[]) +{ + registerHandler("ppd:", initPpd, parsePpdFile); + registerHandler("compressed-ppd:", initPpd, parseCompressedPpdFile); + initFoomatic(); + return execute(argc, argv); +} -- cgit v1.2.1