1/* open-po - search for .po file along search path list and open for reading 2 Copyright (C) 1995-1996, 2000-2003, 2005-2006 Free Software Foundation, Inc. 3 Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, April 1995. 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 2, or (at your option) 8 any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program; if not, write to the Free Software Foundation, 17 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 18 19#ifdef HAVE_CONFIG_H 20# include <config.h> 21#endif 22 23/* Specification. */ 24#include "open-catalog.h" 25 26#include <errno.h> 27#include <stdbool.h> 28#include <stdio.h> 29#include <stdlib.h> 30#include <string.h> 31 32#include "dir-list.h" 33#include "pathname.h" 34#include "xalloc.h" 35#include "xvasprintf.h" 36#include "po-xerror.h" 37#include "gettext.h" 38 39#define _(str) gettext (str) 40 41/* This macro is used to determine the number of elements in an erray. */ 42#define SIZEOF(a) (sizeof(a)/sizeof(a[0])) 43 44static FILE * 45try_open_catalog_file (const char *input_name, char **real_file_name_p) 46{ 47 static const char *extension[] = { "", ".po", ".pot", }; 48 char *file_name; 49 FILE *ret_val; 50 int j; 51 size_t k; 52 const char *dir; 53 54 if (strcmp (input_name, "-") == 0 || strcmp (input_name, "/dev/stdin") == 0) 55 { 56 *real_file_name_p = xstrdup (_("<stdin>")); 57 return stdin; 58 } 59 60 /* We have a real name for the input file. If the name is absolute, 61 try the various extensions, but ignore the directory search list. */ 62 if (IS_ABSOLUTE_PATH (input_name)) 63 { 64 for (k = 0; k < SIZEOF (extension); ++k) 65 { 66 file_name = concatenated_pathname ("", input_name, extension[k]); 67 68 ret_val = fopen (file_name, "r"); 69 if (ret_val != NULL || errno != ENOENT) 70 { 71 /* We found the file. */ 72 *real_file_name_p = file_name; 73 return ret_val; 74 } 75 76 free (file_name); 77 } 78 } 79 else 80 { 81 /* For relative file names, look through the directory search list, 82 trying the various extensions. If no directory search list is 83 specified, the current directory is used. */ 84 for (j = 0; (dir = dir_list_nth (j)) != NULL; ++j) 85 for (k = 0; k < SIZEOF (extension); ++k) 86 { 87 file_name = concatenated_pathname (dir, input_name, extension[k]); 88 89 ret_val = fopen (file_name, "r"); 90 if (ret_val != NULL || errno != ENOENT) 91 { 92 *real_file_name_p = file_name; 93 return ret_val; 94 } 95 96 free (file_name); 97 } 98 } 99 100 /* File does not exist. */ 101 *real_file_name_p = xstrdup (input_name); 102 errno = ENOENT; 103 return NULL; 104} 105 106/* Open the input file with the name INPUT_NAME. The ending .po is added 107 if necessary. If INPUT_NAME is not an absolute file name and the file is 108 not found, the list of directories in "dir-list.h" is searched. The 109 file's pathname is returned in *REAL_FILE_NAME_P, for error message 110 purposes. */ 111FILE * 112open_catalog_file (const char *input_name, char **real_file_name_p, 113 bool exit_on_error) 114{ 115 FILE *fp = try_open_catalog_file (input_name, real_file_name_p); 116 117 if (fp == NULL && exit_on_error) 118 { 119 const char *errno_description = strerror (errno); 120 po_xerror (PO_SEVERITY_FATAL_ERROR, NULL, NULL, 0, 0, false, 121 xasprintf ("%s: %s", 122 xasprintf (_("error while opening \"%s\" for reading"), 123 *real_file_name_p), 124 errno_description)); 125 } 126 127 return fp; 128} 129