home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 9 Archive / 09-Archive.zip / PAX20.ZIP / REPLACE.C < prev    next >
C/C++ Source or Header  |  1990-11-12  |  7KB  |  318 lines

  1. /* $Source: /u/mark/src/pax/RCS/replace.c,v $
  2.  *
  3.  * $Revision: 2.0.0.3 $
  4.  *
  5.  * replace.c - regular expression pattern replacement functions
  6.  *
  7.  * DESCRIPTION
  8.  *
  9.  *    These routines provide for regular expression file name replacement
  10.  *    as required by pax.
  11.  *
  12.  * AUTHORS
  13.  *
  14.  *    Mark H. Colburn, Open Systems Architects, Inc.  (mark@minnetech.mn.org)
  15.  *
  16.  * COPYRIGHT
  17.  *
  18.  *    Copyright (c) 1989 Mark H. Colburn.  All rights reserved.
  19.  *
  20.  *    Redistribution and use in source and binary forms are permitted
  21.  *    provided that the above copyright notice and this paragraph are
  22.  *    duplicated in all such forms and that any documentation,
  23.  *    advertising materials, and other materials related to such
  24.  *    distribution and use acknowledge that the software was developed
  25.  *    by Mark H. Colburn.
  26.  *
  27.  *    THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  28.  *    IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  29.  *    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  30.  *
  31.  * $Log:    replace.c,v $
  32.  * Revision 2.0.0.3  89/10/13  02:35:54  mark
  33.  * Beta Test Freeze
  34.  *
  35.  */
  36.  
  37. #ifndef lint
  38. static char        *ident = "$Id: replace.c,v 2.0.0.3 89/10/13 02:35:54 mark Exp Locker: mark $";
  39. static char        *copyright = "Copyright (c) 1989 Mark H. Colburn.\nAll rights reserved.\n";
  40. #endif                /* not lint */
  41.  
  42. /* Headers */
  43.  
  44. #include "pax.h"
  45.  
  46.  
  47. /* add_replstr - add a replacement string to the replacement string list
  48.  *
  49.  * DESCRIPTION
  50.  *
  51.  *    Add_replstr adds a replacement string to the replacement string
  52.  *    list which is applied each time a file is about to be processed.
  53.  *
  54.  * PARAMETERS
  55.  *
  56.  *    char    *pattern    - A regular expression which is to be parsed
  57.  */
  58.  
  59. #ifdef __STDC__
  60.  
  61. void
  62. add_replstr(char *pattern)
  63.  
  64. #else
  65.  
  66. void
  67. add_replstr(pattern)
  68.     char               *pattern;
  69.  
  70. #endif
  71. {
  72.     char               *p;
  73.     char                sep;
  74.     Replstr            *rptr;
  75.     int                 len;
  76.  
  77.     DBUG_ENTER("add_replstr");
  78.     if ((len = strlen(pattern)) < 4) {
  79.     warn("Replacement string not added",
  80.          "Malformed substitution syntax");
  81.     DBUG_VOID_RETURN;
  82.     }
  83.     if ((rptr = (Replstr *) malloc(sizeof(Replstr))) == (Replstr *) NULL) {
  84.     warn("Replacement string not added", "No space");
  85.     DBUG_VOID_RETURN;
  86.     }
  87.     /* First character is the delimeter... */
  88.     sep = *pattern;
  89.  
  90.     /* Get trailing g and/or p */
  91.     p = pattern + len - 1;
  92.     while (*p != sep) {
  93.     if (*p == 'g') {
  94.         rptr->global = 1;
  95.     } else if (*p == 'p') {
  96.         rptr->print = 1;
  97.     } else {
  98.         warn(p, "Invalid RE modifier");
  99.     }
  100.     p--;
  101.     }
  102.  
  103.     if (*p != sep) {
  104.     warn("Replacement string not added", "Bad delimeters");
  105.     free(rptr);
  106.     DBUG_VOID_RETURN;
  107.     }
  108.     /* strip off leading and trailing delimeter */
  109.     *p = '\0';
  110.     pattern++;
  111.  
  112.     /* find the separating '/' in the pattern */
  113.     p = pattern;
  114.     while (*p) {
  115.     if (*p == sep) {
  116.         break;
  117.     }
  118.     if (*p == '\\' && *(p + 1) != '\0') {
  119.         p++;
  120.     }
  121.     p++;
  122.     }
  123.     if (*p != sep) {
  124.     warn("Replacement string not added", "Bad delimeters");
  125.     free(rptr);
  126.     DBUG_VOID_RETURN;
  127.     }
  128.     *p++ = '\0';
  129.  
  130.     /*
  131.      * Now pattern points to 'old' and p points to 'new' and both are '\0'
  132.      * terminated
  133.      */
  134.     if ((rptr->comp = regcomp(pattern)) == (regexp *) NULL) {
  135.     warn("Replacement string not added", "Invalid RE");
  136.     free(rptr);
  137.     DBUG_VOID_RETURN;
  138.     }
  139.     rptr->replace = p;
  140.     rptr->next = (Replstr *) NULL;
  141.     if (rplhead == (Replstr *) NULL) {
  142.     rplhead = rptr;
  143.     rpltail = rptr;
  144.     } else {
  145.     rpltail->next = rptr;
  146.     rpltail = rptr;
  147.     }
  148.     DBUG_VOID_RETURN;
  149. }
  150.  
  151.  
  152.  
  153. /* rpl_name - possibly replace a name with a regular expression
  154.  *
  155.  * DESCRIPTION
  156.  *
  157.  *    The string name is searched for in the list of regular expression
  158.  *    substituions.  If the string matches any of the regular expressions
  159.  *    then the string is modified as specified by the user.
  160.  *
  161.  * PARAMETERS
  162.  *
  163.  *    char    *name    - name to search for and possibly modify
  164.  */
  165.  
  166. #ifdef __STDC__
  167.  
  168. void
  169. rpl_name(char *name)
  170.  
  171. #else
  172.  
  173. void
  174. rpl_name(name)
  175.     char               *name;
  176.  
  177. #endif
  178. {
  179.     int                 found = 0;
  180.     int                 ret;
  181.     Replstr            *rptr;
  182.     char                buff[PATH_MAX + 1];
  183.     char                buff1[PATH_MAX + 1];
  184.     char                buff2[PATH_MAX + 1];
  185.     char               *p;
  186.     char               *b;
  187.  
  188.     DBUG_ENTER("rpl_name");
  189.     strcpy(buff, name);
  190.     for (rptr = rplhead; !found && rptr != (Replstr *) NULL; rptr = rptr->next) {
  191.     do {
  192.         if ((ret = regexec(rptr->comp, buff)) != 0) {
  193.         p = buff;
  194.         b = buff1;
  195.         while (p < rptr->comp->startp[0]) {
  196.             *b++ = *p++;
  197.         }
  198.         p = rptr->replace;
  199.         while (*p) {
  200.             *b++ = *p++;
  201.         }
  202.         strcpy(b, rptr->comp->endp[0]);
  203.         found = 1;
  204.         regsub(rptr->comp, buff1, buff2);
  205.         strcpy(buff, buff2);
  206.         }
  207.     } while (ret && rptr->global);
  208.     if (found) {
  209.         if (rptr->print) {
  210.         fprintf(stderr, "%s >> %s\n", name, buff);
  211.         }
  212.         strcpy(name, buff);
  213.     }
  214.     }
  215.     DBUG_VOID_RETURN;
  216. }
  217.  
  218.  
  219. /* get_disposition - get a file disposition
  220.  *
  221.  * DESCRIPTION
  222.  *
  223.  *    Get a file disposition from the user.  If the user enters 'y'
  224.  *    the the file is processed, anything else and the file is ignored.
  225.  *    If the user enters EOF, then the PAX exits with a non-zero return
  226.  *    status.
  227.  *
  228.  * PARAMETERS
  229.  *
  230.  *    char    *mode    - string signifying the action to be taken on file
  231.  *    char    *name    - the name of the file
  232.  *
  233.  * RETURNS
  234.  *
  235.  *    Returns 1 if the file should be processed, 0 if it should not.
  236.  */
  237.  
  238. #ifdef __STDC__
  239.  
  240. int
  241. get_disposition(char *mode, char *name)
  242.  
  243. #else
  244.  
  245. int
  246. get_disposition(mode, name)
  247.     char               *mode;
  248.     char               *name;
  249.  
  250. #endif
  251. {
  252.     char                ans[2];
  253.     char                buf[PATH_MAX + 10];
  254.  
  255.     DBUG_ENTER("get_disposition");
  256.     if (f_disposition) {
  257.     sprintf(buf, "%s %s? ", mode, name);
  258.     if (nextask(buf, ans, sizeof(ans)) == -1 || ans[0] == 'q') {
  259.         exit(0);
  260.     }
  261.     if (strlen(ans) == 0 || ans[0] != 'y') {
  262.         DBUG_RETURN(1);
  263.     }
  264.     }
  265.     DBUG_RETURN(0);
  266. }
  267.  
  268.  
  269. /* get_newname - prompt the user for a new filename
  270.  *
  271.  * DESCRIPTION
  272.  *
  273.  *    The user is prompted with the name of the file which is currently
  274.  *    being processed.  The user may choose to rename the file by
  275.  *    entering the new file name after the prompt; the user may press
  276.  *    carriage-return/newline, which will skip the file or the user may
  277.  *    type an 'EOF' character, which will cause the program to stop.
  278.  *
  279.  * PARAMETERS
  280.  *
  281.  *    char    *name        - filename, possibly modified by user
  282.  *    int    size        - size of allowable new filename
  283.  *
  284.  * RETURNS
  285.  *
  286.  *    Returns 0 if successfull, or -1 if an error occurred.
  287.  *
  288.  */
  289.  
  290. #ifdef __STDC__
  291.  
  292. int
  293. get_newname(char *name, int size)
  294.  
  295. #else
  296.  
  297. int
  298. get_newname(name, size)
  299.     char               *name;
  300.     int                 size;
  301.  
  302. #endif
  303. {
  304.     char                buf[PATH_MAX + 10];
  305.  
  306.     DBUG_ENTER("get_newname");
  307.     if (f_interactive) {
  308.     sprintf(buf, "rename %s? ", name);
  309.     if (nextask(buf, name, size) == -1) {
  310.         exit(0);
  311.     }
  312.     if (strlen(name) == 0) {
  313.         DBUG_RETURN(1);
  314.     }
  315.     }
  316.     DBUG_RETURN(0);
  317. }
  318.