PageRenderTime 46ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/contrib/util/language_translations/collectConstants.pl

https://github.com/drbowen/openemr
Perl | 422 lines | 257 code | 60 blank | 105 comment | 48 complexity | fc18675fed4f9e7eaaed579b1dd3bafb MD5 | raw file
  1. #!/usr/bin/perl
  2. #
  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.
  7. #
  8. # author Brady Miller
  9. # email brady@sparmy.com
  10. # date 03/25/09
  11. #
  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.
  18. #
  19. # Example commands:
  20. #
  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
  25. #
  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
  30. #
  31. #
  32. use strict;
  33. # simpleList is flag that is pertinent when compareFlag is not
  34. # used. If set (1), then just makes simple list. If not set (0)
  35. # then output is formatted into a tab delimited spreadsheet.
  36. my $simpleList = 1;
  37. # By turning this on, this will allow removal of old constants.
  38. # If off it will not allow script to be run without an old constants file
  39. # given. Constants in the removal file filter, however, will still
  40. # be removed. Note that if you give the constants file also, then
  41. # this flag will be over rided to be not set.
  42. my $removeFlag = 0;
  43. my $directoryIn; #name is set below
  44. my $comparisonFile; #name is set below
  45. my $addConstantsFile = "manuallyAddedConstants.txt";
  46. my $removeConstantsFile = "manuallyRemovedConstants.txt";
  47. my $pathFilterFile = "filterDirectories.txt";
  48. my $filenameOut = "constants.txt";
  49. my $logFile = "log.txt";
  50. my $compareFlag; #this is set below
  51. my @previousConstants; #will hold previous constants
  52. my @uniqueConstants; #will hold the unique constants
  53. my @filenames; #will hold all file name
  54. my @inputFile;
  55. my @addConstants; #holds constants from the add file
  56. my @removeConstants; #hold constants from the remove file
  57. my @pathFilters; #holds path to filter out
  58. my $headerLineOne = "\t1\t2\t3\t4\t5\t6";
  59. my $headerLineTwo = "\ten\tse\tes\tde\tdu\the";
  60. my $headerLineThree = "\tEnglish\tSwedish\tSpanish\tGerman\tDutch\tHebrew";
  61. # check for parameter to set isCompact flag
  62. if (@ARGV > 2) {
  63. die "\nERROR: Too many parameters. Follow instructions found in collectConstants.pl file.\n\n";
  64. }
  65. elsif (@ARGV == 0) {
  66. die "\nERROR: Need a parameter. Follow instructions found in collectConstants.pl file.\n\n";
  67. }
  68. elsif (@ARGV == 2) {
  69. $comparisonFile = $ARGV[1];
  70. $directoryIn = $ARGV[0];
  71. $compareFlag = 1;
  72. $removeFlag = 0;
  73. }
  74. elsif (@ARGV == 1 && !($removeFlag)) {
  75. 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";
  76. }
  77. elsif (@ARGV == 1) {
  78. $directoryIn = $ARGV[0];
  79. $compareFlag = 0;
  80. }
  81. else {
  82. die "\nERROR: Problem with parameters. Follow instructions found in collectConstants.pl file.\n\n";
  83. }
  84. # open log file and output file
  85. open(LOGFILE, ">$logFile") or die "unable to open log file";
  86. open(OUTPUTFILE, ">$filenameOut") or die "unable to open output file";
  87. # if comparing, then open comparison file and store in array
  88. if ($compareFlag) {
  89. open(MYINPUTFILE, "<$comparisonFile") or die "unable to open file";
  90. @previousConstants = <MYINPUTFILE>;
  91. close(MYINPUTFILE);
  92. # chomp it
  93. foreach my $var (@previousConstants) {
  94. chomp($var);
  95. }
  96. }
  97. # place filter files into array and process them
  98. open(ADDFILE, "<$addConstantsFile") or die "unable to open file";
  99. @addConstants = <ADDFILE>;
  100. close(ADDFILE);
  101. for my $var (@addConstants) {
  102. chomp($var);
  103. }
  104. open(REMOVEFILE, "<$removeConstantsFile") or die "unable to open file";
  105. @removeConstants = <REMOVEFILE>;
  106. close(REMOVEFILE);
  107. for my $var (@removeConstants) {
  108. chomp($var);
  109. }
  110. # place path filter file into array and process them
  111. open(PATHFILTERFILE, "<$pathFilterFile") or die "unable to open file";
  112. @pathFilters = <PATHFILTERFILE>;
  113. close(PATHFILTERFILE);
  114. for my $var (@pathFilters) {
  115. chomp($var);
  116. }
  117. # create filenames array
  118. recurse($directoryIn);
  119. # step thru each file to find constants
  120. foreach my $var (@filenames) {
  121. # skip graphical files
  122. if (($var =~ /.png$/) || ($var =~ /.jpg$/) || ($var =~ /.jpeg$/) || ($var =~ /.pdf$/)) {
  123. print LOGFILE "SKIPPING FILE: ".$var."\n";
  124. next;
  125. }
  126. print LOGFILE $var." prepping.\n";
  127. open(MYINPUTFILE2, "<$var") or die "unable to open file";
  128. @inputFile = <MYINPUTFILE2>;
  129. close(MYINPUTFILE2);
  130. # remove newlines
  131. foreach my $tempLine (@inputFile) {
  132. chomp($tempLine);
  133. }
  134. my $fileString = join(" ", @inputFile);
  135. # print LOGFILE $fileString;
  136. my $traditionalXL = 0; #flag
  137. my $smartyXL = 0; #flag
  138. if ($fileString =~ /xl[at]?\s*\(/i) {
  139. # line contains a traditional xl(function)
  140. $traditionalXL = 1;
  141. }
  142. if ($fileString =~ /\{\s*xl\s*t\s*=\s*/i) {
  143. # line contains a smarty xl function
  144. $smartyXL = 1;
  145. }
  146. # Report files with both smarty and traditional xl functions on same page
  147. if ($smartyXL && $traditionalXL) {
  148. print LOGFILE "WARNING: Found traditional and smarty xl functions on same page: $var\n";
  149. }
  150. # break apart each xl function statement if exist
  151. my @xlInstances;
  152. if ($smartyXL) {
  153. @xlInstances = split(/\{\s*xl\s*t\s*=\s*/i, $fileString);
  154. }
  155. elsif ($traditionalXL) {
  156. @xlInstances = split(/xl[at]?\s*\(+/i, $fileString);
  157. }
  158. else {
  159. # no xl functions to parse on this page
  160. next;
  161. }
  162. # drop the first element
  163. shift(@xlInstances);
  164. my $sizeArray = @xlInstances;
  165. if ($sizeArray > 0) {
  166. foreach my $var2 (@xlInstances) {
  167. # remove spaces from front of $var2
  168. my $editvar2 = $var2;
  169. $editvar2 =~ s/^\s+//;
  170. # collect delimiter, ' or "
  171. my $de = substr($editvar2,0,1);
  172. # skip if blank
  173. if ($de eq "") {
  174. next;
  175. }
  176. # skip if ) (special case from howto files)
  177. if ($de eq ")") {
  178. print LOGFILE "MESSAGE: Special case character ) skipped\n";
  179. print LOGFILE $editvar2."\n";
  180. next;
  181. }
  182. # skip $. Raally rare usage of xl() function.
  183. # There are about 25 lines of this in entire codebase
  184. # and likely just several contants. Can put in manually
  185. # if require.
  186. if ($de eq "\$") {
  187. print LOGFILE "MESSAGE: Special case character \$ skipped\n";
  188. print LOGFILE $editvar2."\n";
  189. next;
  190. }
  191. # skip if starts with d of date(), since
  192. # this is used in calendar frequently
  193. # for translation of variables returned
  194. # by the date function.
  195. if ($de eq "d") {
  196. print LOGFILE "MESSAGE: Special case character 'd' skipped\n";
  197. print LOGFILE $editvar2."\n";
  198. next;
  199. }
  200. print LOGFILE "$de"."\n";
  201. # remove delimiter from string
  202. $editvar2 = substr($editvar2,1);
  203. # remove the evil ^M characters (report file)
  204. if ($editvar2 =~ /\r/) {
  205. print LOGFILE "WARNING: File contains dos end lines: $var\n";
  206. }
  207. $editvar2 =~ s/\r//g;
  208. # hide instances of \$de
  209. $editvar2 =~ s/\\$de/__-_-__/g;
  210. # collect the constant
  211. my @tempStringArr = split(/$de/,$editvar2);
  212. my $tempString = @tempStringArr[0];
  213. # revert hidden instances of \$de
  214. $tempString =~ s/__-_-__/\\$de/g;
  215. # check to see if unique etc.
  216. if (!(withinArray($tempString,@uniqueConstants))) {
  217. # Have a unique hit
  218. push(@uniqueConstants,$tempString);
  219. }
  220. }
  221. }
  222. print LOGFILE $var." checked.\n";
  223. }
  224. # sort the constants
  225. my @sorted = sortConstants(@uniqueConstants);
  226. my @uniqueConstants = @sorted;
  227. # send to log constants that were auto added
  228. print LOGFILE "\nAUTO ADDED CONSTANTS BELOW: ----\n";
  229. foreach my $var (@uniqueConstants) {
  230. if (!(withinArray($var, @previousConstants))) {
  231. print LOGFILE $var."\n";
  232. }
  233. }
  234. print LOGFILE "--------------------------------\n\n";
  235. # run thru add filter
  236. foreach my $var (@addConstants) {
  237. if (withinArray($var, @uniqueConstants)) {
  238. print LOGFILE "NOT MANUALLY ADDED, ALREADY EXIST: ".$var."\n";
  239. next;
  240. }
  241. else {
  242. print LOGFILE "MANUALLY ADDED: ".$var."\n";
  243. push (@uniqueConstants,$var);
  244. }
  245. }
  246. # add previous constants if the remove flag is not set
  247. if (!($removeFlag)) {
  248. foreach my $var (@previousConstants) {
  249. if (withinArray($var,@uniqueConstants)) {
  250. next;
  251. }
  252. else {
  253. print LOGFILE "KEEPING: ".$var."\n";
  254. push(@uniqueConstants, $var);
  255. }
  256. }
  257. }
  258. else {
  259. print LOGFILE "WARNING: NOT INCLUDING PREVIOUS CONSTANTS.\n";
  260. }
  261. # run thru removal filter
  262. my @constants;
  263. foreach my $var (@uniqueConstants) {
  264. if (withinArray($var, @removeConstants)) {
  265. print LOGFILE "REMOVED: ".$var."\n";
  266. next;
  267. }
  268. else {
  269. push(@constants,$var);
  270. }
  271. }
  272. # re-sort the constants
  273. my @sorted = sortConstants(@constants);
  274. # send output
  275. if ($simpleList) {
  276. # output simple list
  277. foreach my $var (@sorted) {
  278. print OUTPUTFILE $var."\n";
  279. }
  280. }
  281. else {
  282. # output tab delimited table
  283. print OUTPUTFILE $headerLineOne."\n";
  284. print OUTPUTFILE $headerLineTwo."\n";
  285. print OUTPUTFILE $headerLineThree."\n";
  286. my $counter = 1;
  287. foreach my $var (@sorted) {
  288. print OUTPUTFILE $counter."\t".$var."\n";
  289. $counter += 1;
  290. }
  291. }
  292. #
  293. # function to collect list of filename
  294. # param - directory
  295. # globals - @filenames @pathFilters LOGFILE
  296. # return - nothing
  297. #
  298. sub recurse($) {
  299. my($path) = @_;
  300. ## append a trailing / if it's not there
  301. $path .= '/' if($path !~ /\/$/);
  302. ## loop through the files contained in the directory
  303. for my $eachFile (glob($path.'*')) {
  304. ## if the file is a directory
  305. if( -d $eachFile) {
  306. # skip if in path filter array
  307. my $skipFileFlag = 0;
  308. foreach my $var (@pathFilters) {
  309. if ( $eachFile =~ /$var/ ) {
  310. $skipFileFlag = 1;
  311. }
  312. }
  313. if ($skipFileFlag) {
  314. print LOGFILE "SKIPPING DIRECTORY: ".$eachFile."\n";
  315. next;
  316. }
  317. ## pass the directory to the routine ( recursion )
  318. recurse($eachFile);
  319. } else {
  320. ## print the file ... tabbed for readability
  321. push(@filenames,$eachFile);
  322. }
  323. }
  324. }
  325. # function to sort constant list
  326. # param - @arr
  327. # return - @arr
  328. #
  329. sub sortConstants {
  330. my(@arr) = @_;
  331. my @first;
  332. my @last;
  333. foreach my $var (@arr) {
  334. if ($var =~ /^[a-z]/i) {
  335. push (@first,$var);
  336. }
  337. else {
  338. push (@last,$var);
  339. }
  340. }
  341. my @sortFirst = sort { lc($a) cmp lc($b) } @first;
  342. my @sortLast = sort { lc($a) cmp lc($b) } @last;
  343. push (@sortFirst, @sortLast);
  344. my @sorted_arr = @sortFirst;
  345. return @sorted_arr;
  346. }
  347. #
  348. # function to return whether a variable is in an array
  349. # param - $variable @arr
  350. # return - 1(true) or 0(false) integer
  351. #
  352. sub withinArray {
  353. my($variable,@arr) = @_;
  354. my $isMatch = 0;
  355. foreach my $tempVar (@arr) {
  356. if ($tempVar eq $variable) {
  357. $isMatch = 1;
  358. last;
  359. }
  360. }
  361. return $isMatch;
  362. }