Diff for /parser3/src/main/pa_common.C between versions 1.107 and 1.119

version 1.107, 2002/03/28 11:50:14 version 1.119, 2002/09/18 12:40:38
Line 3 Line 3
   
         Copyright(c) 2001, 2002 ArtLebedev Group (http://www.artlebedev.com)          Copyright(c) 2001, 2002 ArtLebedev Group (http://www.artlebedev.com)
         Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)          Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
   
         $Id$  
 */  */
   
   static const char* IDENT_COMMON_C="$Date$";
   
 #include "pa_common.h"  #include "pa_common.h"
 #include "pa_types.h"  
 #include "pa_exception.h"  #include "pa_exception.h"
 #include "pa_pool.h"  
 #include "pa_globals.h"  #include "pa_globals.h"
 #include "pa_value.h"  
 #include "pa_hash.h"  
 #include "pa_string.h"  
   
 #ifdef WIN32  #ifdef WIN32
 #       include <windows.h>  #       include <windows.h>
Line 124  bool file_read(Pool& pool, const String& Line 119  bool file_read(Pool& pool, const String&
                            bool fail_on_read_problem,                             bool fail_on_read_problem,
                            size_t offset, size_t limit) {                             size_t offset, size_t limit) {
         const char *fname=file_spec.cstr(String::UL_FILE_SPEC);          const char *fname=file_spec.cstr(String::UL_FILE_SPEC);
 //printf("file_read(%s)\n", fname);  
         int f;          int f;
     struct stat finfo;      struct stat finfo;
   
Line 137  bool file_read(Pool& pool, const String& Line 131  bool file_read(Pool& pool, const String&
         //   they delay update till open, so we would receive "!^test[" string          //   they delay update till open, so we would receive "!^test[" string
         //   if would do stat, next open.          //   if would do stat, next open.
     if((f=open(fname, O_RDONLY|(as_text?_O_TEXT:_O_BINARY)))>=0) {      if((f=open(fname, O_RDONLY|(as_text?_O_TEXT:_O_BINARY)))>=0) {
                 lock_shared_blocking(f);                                  if(lock_shared_blocking(f)!=0) {
                           Exception e("file.lock",
                                           &file_spec, 
                                           "shared lock failed: %s (%d), actual filename '%s'", 
                                                   strerror(errno), errno, fname);
                           unlock(f);
                           close(f);
                           if(fail_on_read_problem)
                                   throw e;
                           return false;
                   }
                 if(stat(fname, &finfo)!=0) {                  if(stat(fname, &finfo)!=0) {
                         Exception e("file.missing",                          Exception e("file.missing",
                                         &file_spec,                                           &file_spec, 
Line 193  bool file_read(Pool& pool, const String& Line 197  bool file_read(Pool& pool, const String&
                         ((char*&)data)[data_size]=0;                          ((char*&)data)[data_size]=0;
                 }                  }
                 return true;                  return true;
     }      } else {
         if(fail_on_read_problem)                  if(fail_on_read_problem)
                 throw Exception(errno==EACCES?"file.access":errno==ENOENT?"file.missing":0,                          throw Exception(errno==EACCES?"file.access":errno==ENOENT?"file.missing":0,
                         &file_spec,                                   &file_spec, 
                         "read failed: %s (%d), actual filename '%s'",                                   "read failed: %s (%d), actual filename '%s'", 
                                 strerror(errno), errno, fname);                                          strerror(errno), errno, fname);
     return false;                  return false;
           }
 }  }
   
 static void create_dir_for_file(const String& file_spec) {  static void create_dir_for_file(const String& file_spec) {
Line 216  bool file_write_action_under_lock( Line 221  bool file_write_action_under_lock(
                                 const char *action_name, void (*action)(int, void *), void *context,                                  const char *action_name, void (*action)(int, void *), void *context,
                                 bool as_text,                                  bool as_text,
                                 bool do_append,                                  bool do_append,
                                 bool do_block) {                                  bool do_block,
                                   bool fail_on_lock_problem) {
         const char *fname=file_spec.cstr(String::UL_FILE_SPEC);          const char *fname=file_spec.cstr(String::UL_FILE_SPEC);
         int f;          int f;
         if(access(fname, W_OK)!=0) // no          if(access(fname, W_OK)!=0) // no
Line 227  bool file_write_action_under_lock( Line 233  bool file_write_action_under_lock(
                 |(as_text?_O_TEXT:_O_BINARY)                  |(as_text?_O_TEXT:_O_BINARY)
                 |(do_append?O_APPEND:O_TRUNC), 0664))>=0) {                  |(do_append?O_APPEND:O_TRUNC), 0664))>=0) {
                 if((do_block?lock_exclusive_blocking(f):lock_exclusive_nonblocking(f))!=0) {                  if((do_block?lock_exclusive_blocking(f):lock_exclusive_nonblocking(f))!=0) {
                           Exception e("file.lock",
                                   &file_spec, 
                                   "shared lock failed: %s (%d), actual filename '%s'", 
                                   strerror(errno), errno, fname);
                         close(f);                          close(f);
                           if(fail_on_lock_problem)
                                   throw e;
                         return false;                          return false;
                 }                  }
   
Line 265  struct File_write_action_info { Line 277  struct File_write_action_info {
 #endif  #endif
 static void file_write_action(int f, void *context) {  static void file_write_action(int f, void *context) {
         File_write_action_info& info=*static_cast<File_write_action_info *>(context);          File_write_action_info& info=*static_cast<File_write_action_info *>(context);
         if(info.size)           if(info.size) {
                 write(f, info.data, info.size);                  int written=write(f, info.data, info.size);
                   if(written<0)
                           throw Exception(0,
                                   0,
                                   "write failed: %s (%d)",  strerror(errno), errno);
           }
 }  }
 void file_write(  void file_write(
                                 const String& file_spec,                                   const String& file_spec, 
Line 319  void file_move(const String& old_spec, c Line 336  void file_move(const String& old_spec, c
 }  }
   
   
   bool entry_exists(const char *fname, struct stat *afinfo) {
           struct stat lfinfo;
           bool result=stat(fname, &lfinfo)==0;
           if(afinfo)
                   *afinfo=lfinfo;
           return result;
   }
   
   bool entry_exists(const String& file_spec) {
           const char *fname=file_spec.cstr(String::UL_FILE_SPEC);
           return entry_exists(fname, 0);
   }
   
 static bool entry_readable(const String& file_spec, bool need_dir) {  static bool entry_readable(const String& file_spec, bool need_dir) {
     const char *fname=file_spec.cstr(String::UL_FILE_SPEC);      const char *fname=file_spec.cstr(String::UL_FILE_SPEC);
         struct stat finfo;          struct stat finfo;
         if(access(fname, R_OK)==0 && stat(fname, &finfo)==0) {          if(access(fname, R_OK)==0 && entry_exists(fname, &finfo)) {
                 bool is_dir=finfo.st_mode&S_IFDIR != 0;                  bool is_dir=(finfo.st_mode&S_IFDIR) != 0;
                 return is_dir==need_dir;                  return is_dir==need_dir;
         }          }
         return false;          return false;
Line 411  char *rsplit(char *string, char delim) { Line 441  char *rsplit(char *string, char delim) {
   
 /// @todo less stupid type detection  /// @todo less stupid type detection
 char *format(Pool& pool, double value, char *fmt) {  char *format(Pool& pool, double value, char *fmt) {
         char *result=(char *)pool.malloc(MAX_NUMBER, 4);          char local_buf[MAX_NUMBER];
           size_t size;
           
         if(fmt)          if(fmt)
                 if(strpbrk(fmt, "diouxX"))                  if(strpbrk(fmt, "diouxX"))
                         if(strpbrk(fmt, "ouxX"))                          if(strpbrk(fmt, "ouxX"))
                                 snprintf(result, MAX_NUMBER, fmt, (uint)value );                                  size=snprintf(local_buf, sizeof(local_buf), fmt, (uint)value);
                         else                          else
                                 snprintf(result, MAX_NUMBER, fmt, (int)value );                                  size=snprintf(local_buf, sizeof(local_buf), fmt, (int)value);
                 else                  else
                         snprintf(result, MAX_NUMBER, fmt, value);                          size=snprintf(local_buf, sizeof(local_buf), fmt, value);
         else          else
                 snprintf(result, MAX_NUMBER, "%d", (int)value);                  size=snprintf(local_buf, sizeof(local_buf), "%d", (int)value);
                   
         return result;          char *pool_buf=(char *)pool.malloc(size+1, 4);
           memcpy(pool_buf, local_buf, size+1);
           return pool_buf;
 }  }
   
 size_t stdout_write(const void *buf, size_t size) {  size_t stdout_write(const void *buf, size_t size) {
Line 480  char *unescape_chars(Pool& pool, const c Line 514  char *unescape_chars(Pool& pool, const c
         return s;          return s;
 }  }
   
 /// used by attributed_meaning_to_string / append_attribute_subattribute  
 struct Attributed_meaning_info {  
         String *header; // header line being constructed  
         String::Untaint_lang lang; // language in which to append to that line  
 };  
 static void append_attribute_subattribute(const Hash::Key& akey, Hash::Val *avalue,   
                                                                                   void *info) {  
         if(akey==VALUE_NAME)  
                 return;  
   
         Attributed_meaning_info& ami=*static_cast<Attributed_meaning_info *>(info);  
   
         // ...; charset=windows1251  
         *ami.header << "; ";  
         ami.header->append(akey, ami.lang);  
         *ami.header << "=";  
         ami.header->append(static_cast<Value *>(avalue)->as_string(), ami.lang);  
 }  
 const String& attributed_meaning_to_string(Value& meaning,   
                                                                                    String::Untaint_lang lang) {  
         String &result=*new(meaning.pool()) String(meaning.pool());  
         if(Hash *hash=meaning.get_hash(0)) {  
                 // $value(value) $subattribute(subattribute value)  
                 if(Value *value=static_cast<Value *>(hash->get(*value_name)))  
                         result.append(value->as_string(), lang, true);  
   
                 Attributed_meaning_info attributed_meaning_info={  
                         &result,  
                         lang  
                 };  
                 hash->for_each(append_attribute_subattribute, &attributed_meaning_info);  
         } else // result value  
                 result.append(meaning.as_string(), lang, true);  
   
         return result;  
 }  
   
 #ifdef WIN32  #ifdef WIN32
 void back_slashes_to_slashes(char *s) {  void back_slashes_to_slashes(char *s) {
         if(s)          if(s)

Removed from v.1.107  
changed lines
  Added in v.1.119


E-mail: