Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

125 lines
2.7 KiB

  1. //***
  2. // SYNOPSIS
  3. // rot13 [-q] [-p:prefix] [-l:#] < file
  4. //
  5. // -p prefix only munge stuff between <prefix> and end-of-line
  6. // -q only munge stuff between quotes
  7. // -l # only munge stuff >= # chars long
  8. //
  9. // -q is good for registry dumps.
  10. // -p prefix is good for ???.
  11. // NOTES
  12. // NYI: -l #
  13. // NYI: ':' between arg and modifier
  14. #include <stdlib.h>
  15. #include <stdio.h>
  16. #define TRUE 1
  17. #define FALSE 0
  18. #define TEXT(x) x
  19. void rot13(FILE *fpIn, FILE *fpOut);
  20. char *PszPrefix;
  21. int FQuote;
  22. void usage()
  23. {
  24. fprintf(stderr, "usage: rot13 [-p prefix] [-q] < file");
  25. exit(2);
  26. }
  27. int _cdecl main(int argc, char **argv)
  28. {
  29. --argc; ++argv;
  30. for ( ; *argv != NULL; --argc, ++argv) {
  31. if (argv[0][0] != TEXT('-'))
  32. break;
  33. switch (argv[0][1]) {
  34. case TEXT('p'):
  35. --argc; ++argv;
  36. PszPrefix = *argv;
  37. break;
  38. case TEXT('q'):
  39. FQuote = TRUE;
  40. break;
  41. default:
  42. usage();
  43. break;
  44. }
  45. }
  46. rot13(stdin, stdout);
  47. return 0;
  48. }
  49. #define ROT13(i) (((i) + 13) % 26)
  50. #define ST_BEG 1
  51. #define ST_MID 2
  52. #define ST_END 3
  53. void rot13(FILE *fpIn, FILE *fpOut)
  54. {
  55. int fRot;
  56. int state;
  57. int fInQuote;
  58. char *pszPre;
  59. int ch;
  60. state = ST_BEG;
  61. fInQuote = FALSE;
  62. while ((ch = getc(fpIn)) != EOF) {
  63. fRot = !(PszPrefix || FQuote);
  64. if (PszPrefix) {
  65. switch (state) {
  66. case ST_BEG:
  67. if (ch == *PszPrefix) {
  68. pszPre = PszPrefix + 1;
  69. state = ST_MID;
  70. }
  71. break;
  72. case ST_MID:
  73. if (*pszPre == 0) {
  74. state = ST_END;
  75. goto Lend;
  76. }
  77. else if (*pszPre++ == ch)
  78. ;
  79. else
  80. state = ST_BEG;
  81. break;
  82. case ST_END:
  83. Lend:
  84. if (ch == TEXT('\n'))
  85. state = ST_BEG;
  86. break;
  87. }
  88. if (state == ST_END)
  89. fRot = TRUE;
  90. }
  91. if (FQuote) {
  92. // todo: <\">, <\'>
  93. if (ch == TEXT('"') || ch == TEXT('\''))
  94. fInQuote = !fInQuote;
  95. if (fInQuote)
  96. fRot = TRUE;
  97. }
  98. if (fRot) {
  99. if (TEXT('a') <= ch && ch <= TEXT('z'))
  100. ch = TEXT('a') + ROT13(ch - TEXT('a'));
  101. else if (TEXT('A') <= ch && ch <= TEXT('Z'))
  102. ch = TEXT('A') + ROT13(ch - TEXT('A'));
  103. else
  104. ;
  105. }
  106. putc(ch, fpOut);
  107. }
  108. return;
  109. }