drop support for php 7.4 (#5740)
[openemr.git] / contrib / util / language_translations / collectConstants.pl
blobbab9efc0eb2fbfddf1e53d47875c7dd4422d82b2
1 #!/usr/bin/perl
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 2 of the License, or
6 # (at your option) any later version.
8 # author Brady Miller
9 # email brady.g.miller@gmail.com
10 # date 03/25/09
12 # This is a perl script that will collect unique constants within
13 # OpenEMR source code.
14 # It effectively finds all xl("constants","") within OpenEMR.
15 # It will filter out constants found in manuallyRemovedConstants.txt
16 # It will add constants found in (ensure not repeated) manuallyAddedConstants.txt
17 # It can also compare to a previous list to find new constants.
19 # Example commands:
21 # -Below command will find all unique constants, filter through the
22 # add/remove files, sort, and dump into file constants.txt. Note this
23 # will remove old constants so the below remove flag must be set:
24 # ./collectConstants /var/www/openemr
26 # -Below command will find all unique constants, ensure none are deleted from the
27 # previous listings of constants,
28 # filter through the add/remove files, sort, and dump to file constants.txt:
29 # ./collectConstants /var/www/openemr previousConstants.txt
33 use strict;
35 # simpleList is flag that is pertinent when compareFlag is not
36 # used. If set (1), then just makes simple list. If not set (0)
37 # then output is formatted into a tab delimited spreadsheet.
38 my $simpleList = 1;
39 # By turning this on, this will allow removal of old constants.
40 # If off it will not allow script to be run without an old constants file
41 # given. Constants in the removal file filter, however, will still
42 # be removed. Note that if you give the constants file also, then
43 # this flag will be over rided to be not set.
44 my $removeFlag = 0;
45 my $directoryIn; #name is set below
46 my $comparisonFile; #name is set below
47 my $addConstantsFile = "manuallyAddedConstants.txt";
48 my $removeConstantsFile = "manuallyRemovedConstants.txt";
49 my $pathFilterFile = "filterDirectories.txt";
50 my $filenameOut = "constants.txt";
51 my $logFile = "log.txt";
52 my $compareFlag; #this is set below
53 my @previousConstants; #will hold previous constants
54 my @uniqueConstants; #will hold the unique constants
55 my @filenames; #will hold all file name
56 my @inputFile;
57 my @addConstants; #holds constants from the add file
58 my @removeConstants; #hold constants from the remove file
59 my @pathFilters; #holds path to filter out
61 my $headerLineOne = "\t1\t2\t3\t4\t5\t6";
62 my $headerLineTwo = "\ten\tse\tes\tde\tdu\the";
63 my $headerLineThree = "\tEnglish\tSwedish\tSpanish\tGerman\tDutch\tHebrew";
65 # check for parameter to set isCompact flag
66 if (@ARGV > 2) {
67 die "\nERROR: Too many parameters. Follow instructions found in collectConstants.pl file.\n\n";
69 elsif (@ARGV == 0) {
70 die "\nERROR: Need a parameter. Follow instructions found in collectConstants.pl file.\n\n";
72 elsif (@ARGV == 2) {
73 $comparisonFile = $ARGV[1];
74 $directoryIn = $ARGV[0];
75 $compareFlag = 1;
76 $removeFlag = 0;
78 elsif (@ARGV == 1 && !($removeFlag)) {
79 die "\nERROR: Need to include a previous listing of constants to avoid deleting old constants. To override this see instructions found in collectConstants.pl file.\n\n";
81 elsif (@ARGV == 1) {
82 $directoryIn = $ARGV[0];
83 $compareFlag = 0;
85 else {
86 die "\nERROR: Problem with parameters. Follow instructions found in collectConstants.pl file.\n\n";
89 # open log file and output file
90 open(LOGFILE, ">$logFile") or die "unable to open log file";
91 open(OUTPUTFILE, ">$filenameOut") or die "unable to open output file";
93 # if comparing, then open comparison file and store in array
94 if ($compareFlag) {
95 open(MYINPUTFILE, "<$comparisonFile") or die "unable to open file";
96 @previousConstants = <MYINPUTFILE>;
97 close(MYINPUTFILE);
99 # chomp it
100 foreach my $var (@previousConstants) {
101 chomp($var);
105 # place filter files into array and process them
106 open(ADDFILE, "<$addConstantsFile") or die "unable to open file";
107 @addConstants = <ADDFILE>;
108 close(ADDFILE);
109 for my $var (@addConstants) {
110 chomp($var);
112 open(REMOVEFILE, "<$removeConstantsFile") or die "unable to open file";
113 @removeConstants = <REMOVEFILE>;
114 close(REMOVEFILE);
115 for my $var (@removeConstants) {
116 chomp($var);
119 # place path filter file into array and process them
120 open(PATHFILTERFILE, "<$pathFilterFile") or die "unable to open file";
121 @pathFilters = <PATHFILTERFILE>;
122 close(PATHFILTERFILE);
123 for my $var (@pathFilters) {
124 chomp($var);
127 # create filenames array
128 recurse($directoryIn);
130 # step thru each file to find constants
131 foreach my $var (@filenames) {
133 # skip graphical files
134 if (($var =~ /.png$/) || ($var =~ /.jpg$/) || ($var =~ /.jpeg$/) || ($var =~ /.pdf$/)) {
135 print LOGFILE "SKIPPING FILE: ".$var."\n";
136 next;
139 print LOGFILE $var." prepping.\n";
141 open(MYINPUTFILE2, "<$var") or die "unable to open file";
142 @inputFile = <MYINPUTFILE2>;
143 close(MYINPUTFILE2);
145 # remove newlines
146 foreach my $tempLine (@inputFile) {
147 chomp($tempLine);
150 my $fileString = join(" ", @inputFile);
151 # print LOGFILE $fileString;
153 my $traditionalXL = 0; #flag
154 my $smartyXL = 0; #flag
157 if ($fileString =~ /xl[astj]?\s*\(/i) {
158 # line contains a traditional xl(function)
159 $traditionalXL = 1;
162 if ($fileString =~ /\{\s*xl[atj]?\s*t\s*=\s*/i) {
163 # line contains a smarty xl function
164 $smartyXL = 1;
167 # Report files with both smarty and traditional xl functions on same page
168 if ($smartyXL && $traditionalXL) {
169 print LOGFILE "WARNING: Found traditional and smarty xl functions on same page: $var\n";
172 # break apart each xl function statement if exist
173 my @xlInstances;
174 if ($smartyXL) {
175 @xlInstances = split(/\{\s*xl[atj]?\s*t\s*=\s*/i, $fileString);
177 elsif ($traditionalXL) {
178 @xlInstances = split(/xl[astj]?\s*\(+/i, $fileString);
180 else {
181 # no xl functions to parse on this page
182 next;
185 # drop the first element
186 shift(@xlInstances);
188 my $sizeArray = @xlInstances;
189 if ($sizeArray > 0) {
190 foreach my $var2 (@xlInstances) {
191 # remove spaces from front of $var2
192 my $editvar2 = $var2;
193 $editvar2 =~ s/^\s+//;
195 # collect delimiter, ' or "
196 my $de = substr($editvar2,0,1);
198 # skip if blank
199 if ($de eq "") {
200 next;
203 # skip if ) (special case from howto files)
204 if ($de eq ")") {
205 print LOGFILE "MESSAGE: Special case character ) skipped\n";
206 print LOGFILE $editvar2."\n";
207 next;
210 # skip $. Raally rare usage of xl() function.
211 # There are about 25 lines of this in entire codebase
212 # and likely just several contants. Can put in manually
213 # if require.
214 if ($de eq "\$") {
215 print LOGFILE "MESSAGE: Special case character \$ skipped\n";
216 print LOGFILE $editvar2."\n";
217 next;
220 # skip \. Another rare usage of xl() function.
221 # Can put in manually if require.
222 if ($de eq "\\") {
223 print LOGFILE "MESSAGE: Special case character \\ skipped\n";
224 print LOGFILE $editvar2."\n";
225 next;
228 # skip if starts with d of date(), since
229 # this is used in calendar frequently
230 # for translation of variables returned
231 # by the date function.
232 if ($de eq "d") {
233 print LOGFILE "MESSAGE: Special case character 'd' skipped\n";
234 print LOGFILE $editvar2."\n";
235 next;
238 # Skip line with the js_xl function
239 if ($de eq "m") {
240 print LOGFILE "MESSAGE: Special case character 'm' skipped. Done to skip the function js_xl() line.\n";
241 print LOGFILE $editvar2."\n";
242 next;
245 print LOGFILE "$de"."\n";
247 # remove delimiter from string
248 $editvar2 = substr($editvar2,1);
250 # remove the evil ^M characters (report file)
251 if ($editvar2 =~ /\r/) {
252 print LOGFILE "WARNING: File contains dos end lines: $var\n";
254 $editvar2 =~ s/\r//g;
256 # hide instances of \$de
257 $editvar2 =~ s/\\$de/__-_-__/g;
259 # collect the constant
260 my @tempStringArr = split(/$de/,$editvar2);
261 my $tempString = @tempStringArr[0];
263 # revert hidden instances of \$de
264 $tempString =~ s/__-_-__/\\$de/g;
266 # check to see if unique etc.
267 if (!(withinArray($tempString,@uniqueConstants))) {
268 # Have a unique hit
269 push(@uniqueConstants,$tempString);
274 print LOGFILE $var." checked.\n";
277 # sort the constants
278 my @sorted = sortConstants(@uniqueConstants);
279 my @uniqueConstants = @sorted;
281 # send to log constants that were auto added
282 print LOGFILE "\nAUTO ADDED CONSTANTS BELOW: ----\n";
283 foreach my $var (@uniqueConstants) {
284 if (!(withinArray($var, @previousConstants))) {
285 print LOGFILE $var."\n";
288 print LOGFILE "--------------------------------\n\n";
290 # run thru add filter
291 foreach my $var (@addConstants) {
292 if (withinArray($var, @uniqueConstants)) {
293 print LOGFILE "NOT MANUALLY ADDED, ALREADY EXIST: ".$var."\n";
294 next;
296 else {
297 print LOGFILE "MANUALLY ADDED: ".$var."\n";
298 push (@uniqueConstants,$var);
302 # add previous constants if the remove flag is not set
303 if (!($removeFlag)) {
304 foreach my $var (@previousConstants) {
305 if (withinArray($var,@uniqueConstants)) {
306 next;
308 else {
309 print LOGFILE "KEEPING: ".$var."\n";
310 push(@uniqueConstants, $var);
314 else {
315 print LOGFILE "WARNING: NOT INCLUDING PREVIOUS CONSTANTS.\n";
318 # run thru removal filter
319 my @constants;
320 foreach my $var (@uniqueConstants) {
321 if (withinArray($var, @removeConstants)) {
322 print LOGFILE "REMOVED: ".$var."\n";
323 next;
325 else {
326 push(@constants,$var);
330 # re-sort the constants
331 my @sorted = sortConstants(@constants);
333 # send output
334 if ($simpleList) {
335 # output simple list
336 foreach my $var (@sorted) {
337 print OUTPUTFILE $var."\n";
340 else {
341 # output tab delimited table
342 print OUTPUTFILE $headerLineOne."\n";
343 print OUTPUTFILE $headerLineTwo."\n";
344 print OUTPUTFILE $headerLineThree."\n";
345 my $counter = 1;
346 foreach my $var (@sorted) {
347 print OUTPUTFILE $counter."\t".$var."\n";
348 $counter += 1;
355 # function to collect list of filename
356 # param - directory
357 # globals - @filenames @pathFilters LOGFILE
358 # return - nothing
360 sub recurse($) {
361 my($path) = @_;
363 ## append a trailing / if it's not there
364 $path .= '/' if($path !~ /\/$/);
366 ## loop through the files contained in the directory
367 for my $eachFile (glob($path.'*')) {
369 ## if the file is a directory
370 if( -d $eachFile) {
372 # skip if in path filter array
373 my $skipFileFlag = 0;
374 foreach my $var (@pathFilters) {
375 if ( $eachFile =~ /$var/ ) {
376 $skipFileFlag = 1;
379 if ($skipFileFlag) {
380 print LOGFILE "SKIPPING DIRECTORY: ".$eachFile."\n";
381 next;
384 ## pass the directory to the routine ( recursion )
385 recurse($eachFile);
386 } else {
387 ## print the file ... tabbed for readability
388 push(@filenames,$eachFile);
394 # function to sort constant list
395 # param - @arr
396 # return - @arr
398 sub sortConstants {
399 my(@arr) = @_;
400 my @first;
401 my @last;
403 foreach my $var (@arr) {
404 if ($var =~ /^[a-z]/i) {
405 push (@first,$var);
407 else {
408 push (@last,$var);
412 my @sortFirst = sort { lc($a) cmp lc($b) } @first;
413 my @sortLast = sort { lc($a) cmp lc($b) } @last;
415 push (@sortFirst, @sortLast);
416 my @sorted_arr = @sortFirst;
418 return @sorted_arr;
423 # function to return whether a variable is in an array
424 # param - $variable @arr
425 # return - 1(true) or 0(false) integer
427 sub withinArray {
428 my($variable,@arr) = @_;
429 my $isMatch = 0;
430 foreach my $tempVar (@arr) {
431 if ($tempVar eq $variable) {
432 $isMatch = 1;
433 last;
436 return $isMatch;