Crombie Tools
CmsswParse.h
Go to the documentation of this file.
1 #ifndef CMSSW_PARSE_H
2 #define CMSSW_PARSE_H
3 
4 #include <ctime>
5 #include <string.h>
6 #include <assert.h>
7 #include <stdio.h>
8 #include <sys/stat.h>
9 
10 void print_usage(const char* first_arg) {
11 
12  printf("\nUsage: %s INPUTS [INPUTS ...] OUTPUT\n\n", first_arg);
13  printf("INPUTS Must be valid panda files.\n");
14  printf("OUTPUT Is the name of the output file that is used in monojet analysis\n");
15  printf(" The file must not exist prior to running %s\n\n", first_arg);
16 
17 }
18 
19 /**
20  This function checks that the input files exist, and that the output file does not exist.
21  A missing input file leads to exit code 2.
22  An existing output file leads to exit code 3.
23  */
24 
25 int check_files_then_send(int argc, char** argv, int (*desired_main)(int, char**)) {
26 
27  // Check input files
28 
29  struct stat buffer;
30 
31  for (int i_file = 1; i_file < argc; i_file++) {
32  int stat_code = stat(argv[i_file], &buffer);
33 
34  if (stat_code != 0 && i_file != (argc - 1)) {
35  print_usage(argv[0]);
36  printf("Could not find file located at %s\n", argv[i_file]);
37  printf("Please try again.\n");
38  return 2;
39  }
40  else if (stat_code == 0 && i_file == (argc - 1)) {
41  print_usage(argv[0]);
42  printf("File %s already exists.\n", argv[i_file]);
43  printf("Please select a different file to write to.\n");
44  return 3;
45  }
46  }
47 
48  time_t start_time = time(NULL);
49  auto exit_code = desired_main(argc, argv);
50  printf("\nFinished %i files in %li seconds.\n\n", argc - 2, time(nullptr) - start_time);
51 
52  return exit_code;
53 
54 }
55 
56 /**
57  This function takes the argc and argv you get from a command line input,
58  and checks for CMSSW-style inputFiles and outputFile parameters.
59  It only does this if argv[1] is a fake python file name
60  (which cmsRun would usually use, for example).
61 
62  After parsing and adjusting the input into something that actually matches the
63  print_usage message above, this function calls the desired_main function.
64  */
65 
66 int parse_then_send(int argc, char** argv, int (*desired_main)(int, char**)) {
67 
68  // Check arguments
69 
70  const char* dummyinput = "inputFiles";
71  const char* dummyoutput = "outputFile";
72 
73  if (argc < 3) {
74  print_usage(argv[0]);
75  printf("Alternatively, you can use this goofy cmsRun-style syntax:\n\n");
76  printf(" %s fake.py %s=INPUTS,INPUTS[,INPUTS...] %s=OUTPUT\n\n",
77  argv[0], dummyinput, dummyoutput);
78  printf("Be sure to put some fake python file name there,\n");
79  printf("if that's what you want. Otherwise I won't parse.\n\n");
80  return 1;
81  }
82 
83  if (strcmp(argv[1] + strlen(argv[1]) - 3, ".py") == 0) {
84  printf("Detected fake python file %s at the beginning.\n", argv[1]);
85  printf("Parsing inputs for CMSSW style.\n\n");
86 
87  // Check that the input format matches what we expect for CMSSW style
88  assert(argc == 4);
89  assert(argv[2][strlen(dummyinput)] == '=');
90  assert(argv[3][strlen(dummyoutput)] == '=');
91 
92  int parsed_argc = 1;
93  const int MAX_ARGS = 2048;
94  char* parsed_argv[MAX_ARGS];
95  parsed_argv[0] = argv[0];
96 
97  // Place null characters in the proper places in the input
98  int num_chars = strlen(argv[2]);
99  bool just_found_sep = true;
100  for (int i_char = strlen(dummyinput) + 1; i_char < num_chars; i_char++) {
101  if (just_found_sep) {
102  parsed_argv[parsed_argc++] = argv[2] + i_char;
103  just_found_sep = false;
104  assert(parsed_argc < MAX_ARGS); // Will add one more arg at the end, so equal is no good
105  }
106 
107  if (argv[2][i_char] == ',') {
108  argv[2][i_char] = '\0'; // Null character to end last string
109  just_found_sep = true; // Be prepared to add next
110  }
111  }
112 
113  // Set the output file
114  parsed_argv[parsed_argc++] = argv[3] + strlen(dummyoutput) + 1;
115 
116  return check_files_then_send(parsed_argc, parsed_argv, desired_main);
117  }
118 
119  // Otherwise, check arguments
120 
121  return check_files_then_send(argc, argv, desired_main);
122 
123 }
124 
125 #endif