From 11ae14d738865c298f1f40035a052fca1caed177 Mon Sep 17 00:00:00 2001 From: Philip Allison Date: Sat, 3 May 2008 13:57:28 +0100 Subject: [PATCH] Tidy up image search & forking code Move extension-appending code into a separate function, so as not to clutter main() so much. Also, create a macro for the EINTR ignoring loops, to reduce duplication in the forking code. Signed-off-by: Philip Allison --- src/cteddy.cxx | 162 ++++++++++++++++++++++++--------------------------------- 1 file changed, 69 insertions(+), 93 deletions(-) diff --git a/src/cteddy.cxx b/src/cteddy.cxx index bb8dddd..82bb02f 100644 --- a/src/cteddy.cxx +++ b/src/cteddy.cxx @@ -125,6 +125,35 @@ void handle_key_press(GtkWidget *Window, GdkEventKey *theEvent) } +// Function for seeing whether or not a particular image file exists. +// If we find a file, copy the filename into image and return true, otherwise return false. +bool image_exists(std::string& image, const std::string& find_image) +{ + + // Set of image extensions to try appending when searching for an image + static char* extensions[16]; + extensions[0] = ".png"; extensions[1] = ".gif"; extensions[2] = ".jpg"; + extensions[3] = ".jpeg"; extensions[4] = ".pnm"; extensions[5] = ".xpm"; + extensions[6] = ".tif"; extensions[7] = ".tiff"; + extensions[8] = ".PNG"; extensions[9] = ".GIF"; extensions[10] = ".JPG"; + extensions[11] = ".JPEG"; extensions[12] = ".PNM"; extensions[13] = ".XPM"; + extensions[14] = ".TIF"; extensions[15] = ".TIFF"; + + struct stat s; + // Try unadulterated filename, then extensions in lower & upper case + for (size_t i = 0; i < 16; ++i) + { + std::string ximage(find_image); + if (i > 0) ximage.append(extensions[i - 1]); + if (stat(ximage.c_str(), &s) == 0) + { + image = ximage; + return true; + } + } + return false; +} + // Entry point int main (int argc, char* argv[]) { @@ -175,73 +204,36 @@ int main (int argc, char* argv[]) // Otherwise, search for it. if (image.find_last_of('/') == std::string::npos) { - // Append extensions one by one and search for the image - // XXX This code is really, REALLY quick and nasty - char* extensions[17]; + // Search for the image bool found = false; - extensions[0] = '\0'; - extensions[1] = ".png"; extensions[2] = ".gif"; extensions[3] = ".jpg"; - extensions[4] = ".jpeg"; extensions[5] = ".pnm"; extensions[6] = ".xpm"; - extensions[7] = ".tif"; extensions[8] = ".tiff"; - extensions[9] = ".PNG"; extensions[10] = ".GIF"; extensions[11] = ".JPG"; - extensions[12] = ".JPEG"; extensions[13] = ".PNM"; extensions[14] = ".XPM"; - extensions[15] = ".TIF"; extensions[16] = ".TIFF"; - for (size_t i = 0; i < 17; ++i) + std::string searchimage(PKGDATADIR "/"); + searchimage.append(image); + found = image_exists(image, searchimage); + // Try converting a leading x to a c and vice versa + if (!found && image.at(0) == 'x') + { + std::string ximage(PKGDATADIR "/c"); + ximage.append(image.substr(1)); + found = image_exists(image, ximage); + } + if (!found && image.at(0) == 'c') + { + std::string ximage(PKGDATADIR "/x"); + ximage.append(image.substr(1)); + found = image_exists(image, ximage); + } + // Try prepending c or x + if (!found) { - std::string searchimage(PKGDATADIR "/"); - searchimage.append(image); - if (i > 0) searchimage.append(extensions[i]); - struct stat s; - if (stat(searchimage.c_str(), &s) == 0) - { - image = searchimage; - found = true; - break; - } - // Try converting a leading x to a c and vice versa - if (image.at(0) == 'x') - { - std::string ximage(PKGDATADIR "/c"); - ximage.append(image.substr(1)); - if (i > 0) ximage.append(extensions[i]); - if (stat(ximage.c_str(), &s) == 0) - { - image = ximage; - found = true; - break; - } - } - if (image.at(0) == 'c') - { - std::string ximage(PKGDATADIR "/x"); - ximage.append(image.substr(1)); - if (i > 0) ximage.append(extensions[i]); - if (stat(ximage.c_str(), &s) == 0) - { - image = ximage; - found = true; - break; - } - } - // Try prepending c or x std::string ximage(PKGDATADIR "/c"); ximage.append(image); - if (i > 0) ximage.append(extensions[i]); - if (stat(ximage.c_str(), &s) == 0) - { - image = ximage; - found = true; - break; - } - ximage = PKGDATADIR "/x"; + found = image_exists(image, ximage); + } + if (!found) + { + std::string ximage(PKGDATADIR "/x"); ximage.append(image); - if (i > 0) ximage.append(extensions[i]); - if (stat(ximage.c_str(), &s) == 0) - { - image = ximage; - found = true; - break; - } + found = image_exists(image, ximage); } if (!found) @@ -326,9 +318,6 @@ int main (int argc, char* argv[]) // Clear the window's default background gdk_window_set_back_pixmap(window->window, NULL, false); - // Don't steal input focus when we start - g_object_set(G_OBJECT(window), "focus-on-map", false, NULL); - // Honour float & sticky options if (ontop) gtk_window_set_keep_above(GTK_WINDOW(window), true); @@ -348,37 +337,24 @@ int main (int argc, char* argv[]) } else if (p == 0) { + // Macro for performing a particular system call, + // trying again if it returns EINTR, displaying an error otherwise + #define __IGNORE_EINTR(fun, msg) \ + while(fun) \ + { \ + if (errno == EINTR) \ + continue; \ + std::cerr << msg << strerror(errno) << std::endl; \ + return 1; \ + } + // Close stdin - while (close(0) != 0) - { - if (errno == EINTR) - continue; - std::cerr << "Could not close stdin: " << strerror(errno) << std::endl; - return 1; - } + __IGNORE_EINTR(close(0) != 0, "Could not close stdin: "); // Redirect stdout & stderr to /dev/null int nullfd; - while ((nullfd = open("/dev/null", O_WRONLY)) < 0) - { - if (errno == EINTR) - continue; - std::cerr << "Cannot open /dev/null: " << strerror(errno) << std::endl; - return 1; - } - while (dup2(nullfd, 1) < 0) - { - if (errno == EINTR) - continue; - std::cerr << "Cannot redirect stdout to /dev/null: " << strerror(errno) << std::endl; - return 1; - } - while (dup2(nullfd, 2) < 0) - { - if (errno == EINTR) - continue; - std::cerr << "Cannot redirect stderr to /dev/null: " << strerror(errno) << std::endl; - return 1; - } + __IGNORE_EINTR((nullfd = open("/dev/null", O_WRONLY)) < 0, "Cannot open /dev/null: "); + __IGNORE_EINTR(dup2(nullfd, 1) < 0, "Cannot redirect stdout to /dev/null: "); + __IGNORE_EINTR(dup2(nullfd, 2) < 0, "Cannot redirect stderr to /dev/null: "); // Create new process session if (setsid() < 0) { -- 2.11.4.GIT