feisty meow concerns codebase  2.140
splitter.cpp
Go to the documentation of this file.
1 /*****************************************************************************\
2 * *
3 * Name : splitter *
4 * Author : Chris Koeritz *
5 * *
6 * Purpose: *
7 * *
8 * Takes text as input and splits the lines so that they will fit on a *
9 * standard 80 column terminal. *
10 * *
11 *******************************************************************************
12 * Copyright (c) 1993-$now By Author. This program is free software; you can *
13 * redistribute it and/or modify it under the terms of the GNU General Public *
14 * License as published by the Free Software Foundation; either version 2 of *
15 * the License or (at your option) any later version. This is online at: *
16 * http://www.fsf.org/copyleft/gpl.html *
17 * Please send any updates to: fred@gruntose.com *
18 \*****************************************************************************/
19 
21 #include <basis/astring.h>
22 #include <filesystem/byte_filer.h>
23 #include <filesystem/filename.h>
24 #include <loggers/console_logger.h>
25 #include <loggers/file_logger.h>
27 #include <structures/set.h>
29 
30 #include <stdio.h>
31 
32 using namespace application;
33 using namespace basis;
34 using namespace filesystem;
35 using namespace loggers;
36 using namespace structures;
37 using namespace textual;
38 
39 const int MAX_BUFFER = 1024;
40 
41 class splitter_app : public application_shell
42 {
43 public:
44  splitter_app() : application_shell() {}
45 
46  DEFINE_CLASS_NAME("splitter_app");
47 
48  virtual int execute();
49 
50  int print_instructions();
51 
52 private:
53 };
54 
56 
58 {
59  astring name = filename(_global_argv[0]).basename().raw();
60  log(a_sprintf("%s usage:", name.s()));
61  log(astring::empty_string());
62  log(a_sprintf("\
63 This program splits long lines in input files into a more reasonable size.\n\
64 Any filenames on the command line are split and sent to standard output.\n\
65 The following options change how the splitting is performed:\n\
66  --help or -?\tShow this help information.\n\
67  --mincol N\tMinimum column to use for output.\n\
68  --maxcol N\tMaximum column to use for output.\n\
69 "));
70  return -3;
71 }
72 
73 int splitter_app::execute()
74 {
75  command_line cmds(_global_argc, _global_argv); // parse the command line up.
76 
77  // retrieve any specific flags first.
78  astring temp;
79  int min_col = 0;
80  int min_indy = -1;
81 //hmmm: this whole thing is annoying. we need a better way to have a list of parms.
82  if (cmds.find("mincol", min_indy)) {
83  cmds.get_value("mincol", temp);
84  min_col = temp.convert(min_col);
85  }
86  int max_col = 78;
87  int max_indy = -1;
88  if (cmds.find("maxcol", max_indy)) {
89  cmds.get_value("maxcol", temp);
90  max_col = temp.convert(max_col);
91  }
92 //printf("got max_col=%d\n", max_col);
93  // look for help command.
94  int junk_index = 0;
95  if (cmds.find("help", junk_index, false)
96  || cmds.find('h', junk_index, false)
97  || cmds.find("?", junk_index, false)
98  || cmds.find('?', junk_index, false) ) {
100  return 0;
101  }
102 
103  // see if we found any flags that would make us skip some of the parameters.
104 //hmmm: automate this!
105  int skip_index = 0;
106  if ( (min_indy >= 0) || (max_indy >= 0) ) {
107  skip_index = basis::maximum(min_indy, max_indy);
108  skip_index += 2;
109  }
110 //printf("got a skip index of %d\n", skip_index);
111 
112  // gather extra input files.
113  string_set input_files;
114  for (int i = skip_index; i < cmds.entries(); i++) {
115  const command_parameter &curr = cmds.get(i);
116  if (curr.type() == command_parameter::VALUE) {
117 //log(astring("adding input file:") + curr.text());
118  input_files += curr.text();
119  }
120  }
121 
122  astring accumulator;
123  for (int q = 0; q < input_files.length(); q++) {
124  byte_filer current(input_files[q], "r");
125  if (!current.good()) continue;
126  while (!current.eof()) {
127  astring line_read;
128  int num_chars = current.getline(line_read, MAX_BUFFER);
129  if (!num_chars) continue;
130 //printf("line len=%d, cont=%s\n", line_read.length(), line_read.s());
131  accumulator += line_read;
132  }
133  }
134 
135  // now get from standard input if there weren't any files specified.
136  if (!input_files.length()) {
137  char input_line[MAX_BUFFER + 2];
138  while (!feof(stdin)) {
139  char *got = fgets(input_line, MAX_BUFFER, stdin);
140  if (!got) break;
141 //printf("line=%s\n", got);
142  accumulator += got;
143  }
144  }
145 //printf("splitting accum with %d chars...\n", accumulator.length());
146  astring chewed;
147  string_manipulation::split_lines(accumulator, chewed, min_col, max_col);
148 //printf("chewed string now has %d chars...\n", chewed.length());
149  printf("%s", chewed.s());
150  return 0;
151 }
152 
154 
155 HOOPLE_MAIN(splitter_app, )
156 
int print_instructions(bool good, const astring &program_name)
Definition: checker.cpp:45
The application_shell is a base object for console programs.
const basis::astring & text() const
observes the string contents.
parameter_types type() const
observes the type of the parameter.
Definition: command_line.h:69
a_sprintf is a specialization of astring that provides printf style support.
Definition: astring.h:440
int length() const
Returns the current reported length of the allocated C array.
Definition: array.h:115
Provides a dynamically resizable ASCII character string.
Definition: astring.h:35
const char * s() const
synonym for observe. the 's' stands for "string", if that helps.
Definition: astring.h:113
int convert(int default_value) const
Converts the string into a corresponding integer.
Definition: astring.cpp:757
Provides file managment services using the standard I/O support.
Definition: byte_filer.h:32
Provides operations commonly needed on file names.
Definition: filename.h:64
const basis::astring & raw() const
returns the astring that we're holding onto for the path.
Definition: filename.cpp:97
filename basename() const
returns the base of the filename; no directory.
Definition: filename.cpp:385
A simple object that wraps a templated set of strings.
Definition: set.h:168
#define DEFINE_CLASS_NAME(objname)
Defines the name of a class by providing a couple standard methods.
Definition: enhance_cpp.h:45
Provides macros that implement the 'main' program of an application.
#define HOOPLE_MAIN(obj_name, obj_args)
options that should work for most unix and linux apps.
Definition: hoople_main.h:61
Implements an application lock to ensure only one is running at once.
char ** _global_argv
The guards collection helps in testing preconditions and reporting errors.
Definition: array.h:30
type maximum(type a, type b)
minimum returns the lesser of two values.
Definition: functions.h:26
A platform independent way to obtain the timestamp of a file.
Definition: byte_filer.cpp:37
A logger that sends to the console screen using the standard output device.
None split_lines(str unsplit_line)
A dynamic container class that holds any kind of object via pointers.
Definition: amorph.h:55
const int MAX_BUFFER
Definition: splitter.cpp:39