home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / perl / os2perl / suffix.c < prev    next >
C/C++ Source or Header  |  1991-04-12  |  4KB  |  148 lines

  1. /*
  2.  * Suffix appending for in-place editing under MS-DOS and OS/2.
  3.  *
  4.  * Here are the rules:
  5.  *
  6.  * Style 0:  Append the suffix exactly as standard perl would do it.
  7.  *           If the filesystem groks it, use it.  (HPFS will always
  8.  *           grok it.  FAT will rarely accept it.)
  9.  *
  10.  * Style 1:  The suffix begins with a '.'.  The extension is replaced.
  11.  *           If the name matches the original name, use the fallback method.
  12.  *
  13.  * Style 2:  The suffix is a single character, not a '.'.  Try to add the
  14.  *           suffix to the following places, using the first one that works.
  15.  *               [1] Append to extension.
  16.  *               [2] Append to filename,
  17.  *               [3] Replace end of extension,
  18.  *               [4] Replace end of filename.
  19.  *           If the name matches the original name, use the fallback method.
  20.  *
  21.  * Style 3:  Any other case:  Ignore the suffix completely and use the
  22.  *           fallback method.
  23.  *
  24.  * Fallback method:  Change the extension to ".$$$".  If that matches the
  25.  *           original name, then change the extension to ".~~~".
  26.  *
  27.  * If filename is more than 1000 characters long, we die a horrible
  28.  * death.  Sorry.
  29.  *
  30.  * The filename restriction is a cheat so that we can use buf[] to store
  31.  * assorted temporary goo.
  32.  *
  33.  * Examples, assuming style 0 failed.
  34.  *
  35.  * suffix = ".bak" (style 1)
  36.  *                foo.bar => foo.bak
  37.  *                foo.bak => foo.$$$    (fallback)
  38.  *                foo.$$$ => foo.~~~    (fallback)
  39.  *                makefile => makefile.bak
  40.  *
  41.  * suffix = "~" (style 2)
  42.  *                foo.c => foo.c~
  43.  *                foo.c~ => foo.c~~
  44.  *                foo.c~~ => foo~.c~~
  45.  *                foo~.c~~ => foo~~.c~~
  46.  *                foo~~~~~.c~~ => foo~~~~~.$$$ (fallback)
  47.  *
  48.  *                foo.pas => foo~.pas
  49.  *                makefile => makefile.~
  50.  *                longname.fil => longname.fi~
  51.  *                longname.fi~ => longnam~.fi~
  52.  *                longnam~.fi~ => longnam~.$$$
  53.  *
  54.  */
  55.  
  56. #include "EXTERN.h"
  57. #include "perl.h"
  58. #ifdef OS2
  59. #define INCL_DOSFILEMGR
  60. #define INCL_DOSERRORS
  61. #include <os2.h>
  62. #endif /* OS2 */
  63.  
  64. static char suffix1[] = ".$$$";
  65. static char suffix2[] = ".~~~";
  66.  
  67. #define ext (&buf[1000])
  68.  
  69. add_suffix(str,suffix)
  70. register STR *str;
  71. register char *suffix;
  72. {
  73.     int baselen;
  74.     int extlen;
  75.     char *s, *t, *p;
  76.     STRLEN slen;
  77.  
  78.     if (!(str->str_pok)) (void)str_2ptr(str);
  79.     if (str->str_cur > 1000)
  80.         fatal("Cannot do inplace edit on long filename (%d characters)", str->str_cur);
  81.  
  82. #ifdef OS2
  83.     /* Style 0 */
  84.     slen = str->str_cur;
  85.     str_cat(str, suffix);
  86.     if (valid_filename(str->str_ptr)) return;
  87.  
  88.     /* Fooey, style 0 failed.  Fix str before continuing. */
  89.     str->str_ptr[str->str_cur = slen] = '\0';
  90. #endif /* OS2 */
  91.  
  92.     slen = strlen(suffix);
  93.     t = buf; baselen = 0; s = str->str_ptr;
  94.     while ( (*t = *s) && *s != '.') {
  95.     baselen++;
  96.     if (*s == '\\' || *s == '/') baselen = 0;
  97.      s++; t++;
  98.     }
  99.     p = t;
  100.  
  101.     t = ext; extlen = 0;
  102.     while (*t++ = *s++) extlen++;
  103.     if (extlen == 0) { ext[0] = '.'; ext[1] = 0; extlen++; }
  104.  
  105.     if (*suffix == '.') {        /* Style 1 */
  106.         if (strEQ(ext, suffix)) goto fallback;
  107.     strcpy(p, suffix);
  108.     } else if (suffix[1] == '\0') {  /* Style 2 */
  109.         if (extlen < 4) {
  110.         ext[extlen] = *suffix;
  111.         ext[++extlen] = '\0';
  112.         } else if (baselen < 8) {
  113.            *p++ = *suffix;
  114.     } else if (ext[3] != *suffix) {
  115.         ext[3] = *suffix;
  116.     } else if (buf[7] != *suffix) {
  117.         buf[7] = *suffix;
  118.     } else goto fallback;
  119.     strcpy(p, ext);
  120.     } else { /* Style 3:  Panic */
  121. fallback:
  122.     (void)bcopy(strEQ(ext, suffix1) ? suffix2 : suffix1, p, 4+1);
  123.     }
  124.     str_set(str, buf);
  125. }
  126.  
  127. #ifdef OS2
  128. int
  129. valid_filename(s)
  130. char *s;
  131. {
  132.     HFILE hf;
  133.     USHORT usAction;
  134.  
  135.     switch(DosOpen(s, &hf, &usAction, 0L, 0, FILE_OPEN,
  136.     OPEN_ACCESS_READONLY | OPEN_SHARE_DENYNONE, 0L)) {
  137.     case ERROR_INVALID_NAME:
  138.     case ERROR_FILENAME_EXCED_RANGE:
  139.     return 0;
  140.     case NO_ERROR:
  141.     DosClose(hf);
  142.     /*FALLTHROUGH*/
  143.     default:
  144.     return 1;
  145.     }
  146. }
  147. #endif /* OS2 */
  148.