wc.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. /*
  10. * Count bytes within runes, if it fits in a uint64_t, and other things.
  11. */
  12. #include <u.h>
  13. #include <libc.h>
  14. #include <bio.h>
  15. /* flags, per-file counts, and total counts */
  16. static int pline, pword, prune, pbadr, pchar;
  17. static uint64_t nline, nword, nrune, nbadr, nchar;
  18. static uint64_t tnline, tnword, tnrune, tnbadr, tnchar;
  19. enum{Space, Word};
  20. static void
  21. wc(Biobuf *bin)
  22. {
  23. int where;
  24. int32_t r;
  25. nline = 0;
  26. nword = 0;
  27. nrune = 0;
  28. nbadr = 0;
  29. where = Space;
  30. while ((int32_t)(r = Bgetrune(bin)) >= 0) {
  31. nrune++;
  32. if(r == Runeerror) {
  33. nbadr++;
  34. continue;
  35. }
  36. if(r == '\n')
  37. nline++;
  38. if(where == Word){
  39. if(isspacerune(r))
  40. where = Space;
  41. }else
  42. if(isspacerune(r) == 0){
  43. where = Word;
  44. nword++;
  45. }
  46. }
  47. nchar = Boffset(bin);
  48. tnline += nline;
  49. tnword += nword;
  50. tnrune += nrune;
  51. tnbadr += nbadr;
  52. tnchar += nchar;
  53. }
  54. static void
  55. report(uint64_t nline, uint64_t nword, uint64_t nrune, uint64_t nbadr,
  56. uint64_t nchar, char *fname)
  57. {
  58. char line[1024], *s, *e;
  59. s = line;
  60. e = line + sizeof line;
  61. line[0] = 0;
  62. if(pline)
  63. s = seprint(s, e, " %7llud", nline);
  64. if(pword)
  65. s = seprint(s, e, " %7llud", nword);
  66. if(prune)
  67. s = seprint(s, e, " %7llud", nrune);
  68. if(pbadr)
  69. s = seprint(s, e, " %7llud", nbadr);
  70. if(pchar)
  71. s = seprint(s, e, " %7llud", nchar);
  72. if(fname != nil)
  73. seprint(s, e, " %s", fname);
  74. print("%s\n", line+1);
  75. }
  76. void
  77. main(int argc, char *argv[])
  78. {
  79. char *sts;
  80. Biobuf sin, *bin;
  81. int i;
  82. sts = nil;
  83. ARGBEGIN {
  84. case 'l': pline++; break;
  85. case 'w': pword++; break;
  86. case 'r': prune++; break;
  87. case 'b': pbadr++; break;
  88. case 'c': pchar++; break;
  89. default:
  90. fprint(2, "Usage: %s [-lwrbc] [file ...]\n", argv0);
  91. exits("usage");
  92. } ARGEND
  93. if(pline+pword+prune+pbadr+pchar == 0){
  94. pline = 1;
  95. pword = 1;
  96. pchar = 1;
  97. }
  98. if(argc == 0){
  99. Binit(&sin, 0, OREAD);
  100. wc(&sin);
  101. report(nline, nword, nrune, nbadr, nchar, nil);
  102. Bterm(&sin);
  103. }else{
  104. for(i = 0; i < argc; i++){
  105. bin = Bopen(argv[i], OREAD);
  106. if(bin == nil){
  107. perror(argv[i]);
  108. sts = "can't open";
  109. continue;
  110. }
  111. wc(bin);
  112. report(nline, nword, nrune, nbadr, nchar, argv[i]);
  113. Bterm(bin);
  114. }
  115. if(argc>1)
  116. report(tnline, tnword, tnrune, tnbadr, tnchar, "total");
  117. }
  118. exits(sts);
  119. }