home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 2 / DATAFILE_PDCD2.iso / utilities3 / gnu_sed_rx / c / sed < prev    next >
Text File  |  1994-02-25  |  42KB  |  1,909 lines

  1. /*  GNU SED, a batch stream editor.
  2.     Copyright (C) 1989, 1990, 1991 Free Software Foundation, Inc.
  3.  
  4.     This program is free software; you can redistribute it and/or modify
  5.     it under the terms of the GNU General Public License as published by
  6.     the Free Software Foundation; either version 2, or (at your option)
  7.     any later version.
  8.  
  9.     This program is distributed in the hope that it will be useful,
  10.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.     GNU General Public License for more details.
  13.  
  14.     You should have received a copy of the GNU General Public License
  15.     along with this program; if not, write to the Free Software
  16.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  17.  
  18. #include "config.h"
  19.  
  20. #ifdef __STDC__
  21. #define VOID void
  22. #else
  23. #define VOID char
  24. #endif
  25.  
  26.  
  27. #define _GNU_SOURCE
  28. #include <ctype.h>
  29. #ifndef isblank
  30. #define isblank(c) ((c) == ' ' || (c) == '\t')
  31. #endif
  32. #include <stdio.h>
  33. /*#include <sys/types.h>*/
  34. #include "rx.h"
  35. #include "getopt.h"
  36. #if defined(STDC_HEADERS)
  37. #include <stdlib.h>
  38. #endif
  39. #if HAVE_STRING_H || defined(STDC_HEADERS)
  40. #include <string.h>
  41. #ifndef bzero
  42. #define bzero(s, n)    memset ((s), 0, (n))
  43. #endif
  44. #if !defined(STDC_HEADERS)
  45. #include <memory.h>
  46. #endif
  47. #else
  48. #include <strings.h>
  49. #endif
  50.  
  51. #ifdef RX_MEMDBUG
  52. #include <malloc.h>
  53. #endif
  54.  
  55. #ifndef HAVE_BCOPY
  56. #ifdef HAVE_MEMCPY
  57. #define bcopy(FROM,TO,LEN)  memcpy(TO,FROM,LEN)
  58. #else
  59. void
  60. bcopy (from, to, len)
  61.      char *from;
  62.      char *to;
  63.      int len;
  64. {
  65.   if (from < to)
  66.     {
  67.       from += len - 1;
  68.       to += len - 1;
  69.       while (len--)
  70.     *to-- = *from--;
  71.     }
  72.   else
  73.     while (len--)
  74.       *to++ = *from++;
  75. }
  76.  
  77. #endif
  78. #endif
  79.  
  80. char *version_string = "GNU sed version 2.03";
  81.  
  82. /* Struct vector is used to describe a chunk of a compiled sed program.  
  83.  * There is one vector for the main program, and one for each { } pair,
  84.  * and one for the entire program.  For {} blocks, RETURN_[VI] tells where
  85.  * to continue execution after this VECTOR.
  86.  */
  87.  
  88. struct vector
  89. {
  90.   struct sed_cmd *v;
  91.   int v_length;
  92.   int v_allocated;
  93.   struct vector *return_v;
  94.   int return_i;
  95. };
  96.  
  97.  
  98. /* Goto structure is used to hold both GOTO's and labels.  There are two
  99.  * separate lists, one of goto's, called 'jumps', and one of labels, called
  100.  * 'labels'.
  101.  * the V element points to the descriptor for the program-chunk in which the
  102.  * goto was encountered.
  103.  * the v_index element counts which element of the vector actually IS the
  104.  * goto/label.  The first element of the vector is zero.
  105.  * the NAME element is the null-terminated name of the label.
  106.  * next is the next goto/label in the list. 
  107.  */
  108.  
  109. struct sed_label
  110. {
  111.   struct vector *v;
  112.   int v_index;
  113.   char *name;
  114.   struct sed_label *next;
  115. };
  116.  
  117. /* ADDR_TYPE is zero for a null address,
  118.  *  one if addr_number is valid, or
  119.  * two if addr_regex is valid,
  120.  * three, if the address is '$'
  121.  * Other values are undefined.
  122.  */
  123.  
  124. enum addr_types
  125. {
  126.   addr_is_null = 0,
  127.   addr_is_num = 1,
  128.   addr_is_regex = 2,
  129.   addr_is_last = 3
  130. };
  131.  
  132. struct addr
  133. {
  134.   int addr_type;
  135.   struct re_pattern_buffer *addr_regex;
  136.   int addr_number;
  137. };
  138.  
  139.  
  140. /* Aflags:  If the low order bit is set, a1 has been
  141.  * matched; apply this command until a2 matches.
  142.  * If the next bit is set, apply this command to all
  143.  * lines that DON'T match the address(es).
  144.  */
  145.  
  146. #define A1_MATCHED_BIT    01
  147. #define ADDR_BANG_BIT    02
  148.  
  149. struct sed_cmd
  150. {
  151.   struct addr a1, a2;
  152.   int aflags;
  153.   
  154.   char cmd;
  155.   
  156.   union
  157.     {
  158.       /* This structure is used for a, i, and c commands */
  159.       struct
  160.     {
  161.       char *text;
  162.       int text_len;
  163.     }
  164.       cmd_txt;
  165.       
  166.       /* This is used for b and t commands */
  167.       struct sed_cmd *label;
  168.       
  169.       /* This for r and w commands */
  170.       FILE *io_file;
  171.       
  172.       /* This for the hairy s command */
  173.       /* For the flags var:
  174.      low order bit means the 'g' option was given,
  175.      next bit means the 'p' option was given,
  176.      and the next bit means a 'w' option was given,
  177.      and wio_file contains the file to write to. */
  178.       
  179. #define S_GLOBAL_BIT    01
  180. #define S_PRINT_BIT    02
  181. #define S_WRITE_BIT    04
  182. #define S_NUM_BIT    010
  183.       
  184.       struct
  185.     {
  186.       struct re_pattern_buffer *regx;
  187.       char *replacement;
  188.       int replace_length;
  189.       int flags;
  190.       int numb;
  191.       FILE *wio_file;
  192.     }
  193.       cmd_regex;
  194.       
  195.       /* This for the y command */
  196.       unsigned char *translate;
  197.       
  198.       /* For { */
  199.       struct vector *sub;
  200.       
  201.       /* for t and b */
  202.       struct sed_label *jump;
  203.     } x;
  204. };
  205.  
  206. /* Sed operates a line at a time. */
  207. struct line
  208. {
  209.   char *text;            /* Pointer to line allocated by malloc. */
  210.   int length;            /* Length of text. */
  211.   int alloc;            /* Allocated space for text. */
  212. };
  213.  
  214. /* This structure holds information about files opend by the 'r', 'w',
  215.    and 's///w' commands.  In paticular, it holds the FILE pointer to
  216.    use, the file's name, a flag that is non-zero if the file is being
  217.    read instead of written. */
  218.  
  219. #define NUM_FPS    32
  220. struct
  221.   {
  222.     FILE *phile;
  223.     char *name;
  224.     int readit;
  225.   }
  226.  
  227. file_ptrs[NUM_FPS];
  228.  
  229.  
  230. #if defined(__STDC__)
  231. # define P_(s) s
  232. #else
  233. # define P_(s) ()
  234. #endif
  235.  
  236. void close_files ();
  237. void panic P_ ((char *str,...));
  238. char *__fp_name P_ ((FILE * fp));
  239. FILE *ck_fopen P_ ((char *name, char *mode));
  240. void ck_fwrite P_ ((char *ptr, int size, int nmemb, FILE * stream));
  241. void ck_fclose P_ ((FILE * stream));
  242. VOID *ck_malloc P_ ((int size));
  243. VOID *ck_realloc P_ ((VOID * ptr, int size));
  244. char *ck_strdup P_ ((char *str));
  245. VOID *init_buffer P_ ((void));
  246. void flush_buffer P_ ((VOID * bb));
  247. int size_buffer P_ ((VOID * b));
  248. void add_buffer P_ ((VOID * bb, char *p, int n));
  249. void add1_buffer P_ ((VOID * bb, int ch));
  250. char *get_buffer P_ ((VOID * bb));
  251.  
  252. void compile_string P_ ((char *str));
  253. void compile_file P_ ((char *str));
  254. struct vector *compile_program P_ ((struct vector * vector, int));
  255. void bad_prog P_ ((char *why));
  256. int inchar P_ ((void));
  257. void savchar P_ ((int ch));
  258. int compile_address P_ ((struct addr * addr));
  259. char * last_regex_string = 0;
  260. void buffer_regex  P_ ((int slash));
  261. void compile_regex P_ ((void));
  262. struct sed_label *setup_jump P_ ((struct sed_label * list, struct sed_cmd * cmd, struct vector * vec));
  263. FILE *compile_filename P_ ((int readit));
  264. void read_file P_ ((char *name));
  265. void execute_program P_ ((struct vector * vec));
  266. int match_address P_ ((struct addr * addr));
  267. int read_pattern_space P_ ((void));
  268. void append_pattern_space P_ ((void));
  269. void line_copy P_ ((struct line * from, struct line * to));
  270. void line_append P_ ((struct line * from, struct line * to));
  271. void str_append P_ ((struct line * to, char *string, int length));
  272. void usage P_ ((int));
  273.  
  274. extern char *myname;
  275.  
  276. /* If set, don't write out the line unless explictly told to */
  277. int no_default_output = 0;
  278.  
  279. /* Current input line # */
  280. int input_line_number = 0;
  281.  
  282. /* Are we on the last input file? */
  283. int last_input_file = 0;
  284.  
  285. /* Have we hit EOF on the last input file?  This is used to decide if we
  286.    have hit the '$' address yet. */
  287. int input_EOF = 0;
  288.  
  289. /* non-zero if a quit command has been executed. */
  290. int quit_cmd = 0;
  291.  
  292. /* Have we done any replacements lately?  This is used by the 't' command. */
  293. int replaced = 0;
  294.  
  295. /* How many '{'s are we executing at the moment */
  296. int program_depth = 0;
  297.  
  298. /* The complete compiled SED program that we are going to run */
  299. struct vector *the_program = 0;
  300.  
  301. /* information about labels and jumps-to-labels.  This is used to do
  302.    the required backpatching after we have compiled all the scripts. */
  303. struct sed_label *jumps = 0;
  304. struct sed_label *labels = 0;
  305.  
  306. /* The 'current' input line. */
  307. struct line line;
  308.  
  309. /* An input line that's been stored by later use by the program */
  310. struct line hold;
  311.  
  312. /* A 'line' to append to the current line when it comes time to write it out */
  313. struct line append;
  314.  
  315.  
  316. /* When we're reading a script command from a string, 'prog_start' and
  317.    'prog_end' point to the beginning and end of the string.  This
  318.    would allow us to compile script strings that contain nulls, except
  319.    that script strings are only read from the command line, which is
  320.    null-terminated */
  321. unsigned char *prog_start;
  322. unsigned char *prog_end;
  323.  
  324. /* When we're reading a script command from a string, 'prog_cur' points