1
0

wc.c 2.2 KB

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