WhitespaceRemover.Mod 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. MODULE WhitespaceRemover; (** AUTHOR "staubesv"; PURPOSE "Remove end-of-line whitespace"; *)
  2. IMPORT
  3. Commands, Options, Diagnostics, Files, Strings, Texts, TextUtilities;
  4. CONST
  5. LineFeed = 0AH;
  6. (** Removed all end-of-line whitespace from 'text' *)
  7. PROCEDURE RemoveFromText*(text : Texts.Text; VAR nofRemoved : LONGINT);
  8. VAR reader : Texts.TextReader; char : Texts.Char32; lastWhitespacePosition, nofWhitespaces : LONGINT;
  9. BEGIN
  10. ASSERT(text # NIL);
  11. nofRemoved := 0;
  12. text.AcquireWrite;
  13. NEW(reader, text);
  14. lastWhitespacePosition := -1; (* no whitespace so far *)
  15. reader.ReadCh(char);
  16. WHILE ~reader.eot DO
  17. IF (char = LineFeed) THEN
  18. IF (lastWhitespacePosition > 0) THEN (* remove the whitespace *)
  19. nofWhitespaces := reader.GetPosition() - 2 - lastWhitespacePosition + 1;
  20. text.Delete(lastWhitespacePosition, nofWhitespaces);
  21. nofRemoved := nofRemoved + nofWhitespaces;
  22. END;
  23. lastWhitespacePosition := -1;
  24. ELSIF TextUtilities.IsWhiteSpace(char,text.isUTF) THEN
  25. IF (lastWhitespacePosition < 0) THEN
  26. lastWhitespacePosition := reader.GetPosition()-1;
  27. END;
  28. ELSE
  29. lastWhitespacePosition := -1;
  30. END;
  31. reader.ReadCh(char);
  32. END;
  33. text.ReleaseWrite;
  34. END RemoveFromText;
  35. (** Write a warning to 'diagnostics' for each end-of-line whitespace in 'text' *)
  36. PROCEDURE CheckWhitespace*(text : Texts.Text; diagnostics : Diagnostics.Diagnostics);
  37. VAR
  38. reader : Texts.TextReader; char : Texts.Char32;
  39. lastCharWasWhitespace : BOOLEAN;
  40. lastWhitespacePosition : LONGINT;
  41. BEGIN
  42. ASSERT((text # NIL) & (diagnostics # NIL));
  43. text.AcquireRead;
  44. NEW(reader, text);
  45. reader.SetPosition(0);
  46. reader.SetDirection(1);
  47. lastCharWasWhitespace := FALSE; lastWhitespacePosition := 0;
  48. reader.ReadCh(char);
  49. WHILE ~reader.eot DO
  50. IF (char = LineFeed) THEN
  51. IF lastCharWasWhitespace THEN
  52. diagnostics.Warning("", lastWhitespacePosition, "Whitespace at end of line");
  53. lastCharWasWhitespace := FALSE;
  54. END;
  55. ELSIF TextUtilities.IsWhiteSpace(char, text.isUTF) THEN
  56. IF ~lastCharWasWhitespace THEN
  57. lastWhitespacePosition := reader.GetPosition()-1;
  58. END;
  59. lastCharWasWhitespace := TRUE;
  60. ELSE
  61. lastCharWasWhitespace := FALSE;
  62. END;
  63. reader.ReadCh(char);
  64. END;
  65. text.ReleaseRead;
  66. END CheckWhitespace;
  67. (** Removed all end-of-line whitespace from file named 'filename' *)
  68. PROCEDURE RemoveFromFile*(VAR filename : Files.FileName; VAR nofRemoved: LONGINT; VAR res : WORD);
  69. VAR file : Files.File; text : Texts.Text; format : LONGINT;
  70. BEGIN
  71. file := Files.Old(filename);
  72. IF (file # NIL) THEN
  73. file.GetName(filename);
  74. NEW(text);
  75. TextUtilities.LoadAuto(text, filename, format, res);
  76. IF (res = 0) THEN
  77. RemoveFromText(text, nofRemoved);
  78. CASE format OF
  79. |0: TextUtilities.StoreOberonText(text, filename, res);
  80. |1: TextUtilities.StoreText(text, filename, res);
  81. |2: TextUtilities.ExportUTF8(text, filename, res);
  82. ELSE
  83. res := -99; (* file format not known *)
  84. END;
  85. END;
  86. ELSE
  87. res := Files.FileNotFound;
  88. END;
  89. END RemoveFromFile;
  90. (** Remove end-of-line whitespace in the specified file(s) *)
  91. PROCEDURE Remove*(context : Commands.Context); (** [ "-v" | "--verbose" ] ( filename {" " filename} | filemask ) ~ *)
  92. VAR
  93. options : Options.Options;
  94. mask : Files.FileName;
  95. enum : Files.Enumerator;
  96. filename : Files.FileName;
  97. fileflags : SET;
  98. time, date, size : LONGINT;
  99. nofRemovedTotal: LONGINT; res : WORD;
  100. nofFiles, nofErrors : LONGINT;
  101. PROCEDURE RemoveFromThisFile(VAR filename : Files.FileName);
  102. VAR oldFilename : Files.FileName; nofRemoved : LONGINT;
  103. BEGIN
  104. nofRemoved := 0;
  105. IF options.GetFlag("verbose") THEN
  106. COPY(filename, oldFilename);
  107. context.out.String(filename); context.out.String(" ... "); context.out.Update;
  108. END;
  109. RemoveFromFile(filename, nofRemoved, res);
  110. IF (res = 0) THEN
  111. IF options.GetFlag("verbose") THEN
  112. IF (filename # oldFilename) THEN
  113. context.out.String(filename); context.out.String(": ");
  114. END;
  115. context.out.Int(nofRemoved, 0); context.out.String(" removed");
  116. context.out.Ln; context.out.Update;
  117. END;
  118. nofRemovedTotal := nofRemovedTotal + nofRemoved;
  119. INC(nofFiles);
  120. ELSE
  121. nofRemoved := 0;
  122. INC(nofErrors);
  123. context.error.String("Error in file "); context.error.String(filename); context.error.String(", res: ");
  124. context.error.Int(res, 0); context.error.Ln;
  125. context.error.Update;
  126. END;
  127. END RemoveFromThisFile;
  128. BEGIN
  129. NEW(options);
  130. options.Add("v", "verbose", Options.Flag);
  131. IF options.Parse(context.arg, context.error) THEN
  132. IF context.arg.GetString(mask) THEN
  133. nofRemovedTotal := 0; nofFiles := 0; nofErrors := 0;
  134. IF Strings.ContainsChar(mask, "?", FALSE) OR Strings.ContainsChar(mask, "*", FALSE) THEN
  135. IF options.GetFlag("verbose") THEN
  136. context.out.String("Removing end-of-line whitespace in "); context.out.String(mask); context.out.String("... ");
  137. context.out.Ln; context.out.Update;
  138. END;
  139. NEW(enum); enum.Open(mask, {});
  140. WHILE enum.GetEntry(filename, fileflags, time, date, size) DO
  141. IF ~(Files.Directory IN fileflags) THEN
  142. RemoveFromThisFile(filename);
  143. END;
  144. END;
  145. enum.Close;
  146. ELSE
  147. COPY(mask, filename);
  148. REPEAT
  149. RemoveFromThisFile(filename);
  150. filename := "";
  151. UNTIL ~context.arg.GetString(filename);
  152. END;
  153. IF options.GetFlag("verbose") THEN
  154. context.out.String("Removed "); context.out.Int(nofRemovedTotal, 0); context.out.String(" whitespaces in ");
  155. context.out.Int(nofFiles, 0); context.out.String(" files, ");
  156. context.out.Int(nofErrors, 0); context.out.String(" error(s)");
  157. context.out.Ln;
  158. END;
  159. ELSE
  160. context.out.String('Usage: Whitespace.Remove [ "-v" | "--verbose" ] ( filename {" " filename} | filemask ) ~'); context.out.Ln;
  161. END;
  162. END;
  163. END Remove;
  164. END WhitespaceRemover.
  165. WhitespaceRemover.Remove -v Usbdi.Mod Texts.Mod TextUtilities.Mod ~
  166. WhitespaceRemover.Remove -v WhitespaceRemover.Mod ~
  167. WhitespaceRemover.Remove *.Mod ~
  168. System.Free WhitespaceRemover ~