home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / std_unix / pax / 2 / replace.c < prev    next >
C/C++ Source or Header  |  1989-01-07  |  6KB  |  306 lines

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