spout.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  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. #include <u.h>
  10. #include <libc.h>
  11. #include <ctype.h>
  12. #include <bio.h>
  13. void spout(int, char*);
  14. Biobuf bout;
  15. void
  16. main(int argc, char *argv[])
  17. {
  18. int i, fd;
  19. Binit(&bout, 1, OWRITE);
  20. if(argc == 1)
  21. spout(0, "");
  22. else
  23. for(i=1; i<argc; i++){
  24. fd = open(argv[i], OREAD);
  25. if(fd < 0){
  26. fprint(2, "spell: can't open %s: %r\n", argv[i]);
  27. continue;
  28. }
  29. spout(fd, argv[i]);
  30. close(fd);
  31. }
  32. exits(nil);
  33. }
  34. Biobuf b;
  35. void
  36. spout(int fd, char *name)
  37. {
  38. char *s, *t, *w;
  39. Rune r;
  40. int inword, wordchar;
  41. int n, wn, wid, c, m;
  42. char buf[1024];
  43. Binit(&b, fd, OREAD);
  44. n = 0;
  45. wn = 0;
  46. while((s = Brdline(&b, '\n')) != nil){
  47. if(s[0] == '.')
  48. for(c=0; c<3 && *s>' '; c++){
  49. n++;
  50. s++;
  51. }
  52. inword = 0;
  53. w = s;
  54. t = s;
  55. do{
  56. c = *(uint8_t*)t;
  57. if(c < Runeself)
  58. wid = 1;
  59. else{
  60. wid = chartorune(&r, t);
  61. c = r;
  62. }
  63. wordchar = 0;
  64. if(isalpha(c))
  65. wordchar = 1;
  66. if(inword && !wordchar){
  67. if(c=='\'' && isalpha(t[1]))
  68. goto Continue;
  69. m = t-w;
  70. if(m > 1){
  71. memmove(buf, w, m);
  72. buf[m] = 0;
  73. Bprint(&bout, "%s:#%d,#%d:%s\n", name, wn, n, buf);
  74. }
  75. inword = 0;
  76. }else if(!inword && wordchar){
  77. wn = n;
  78. w = t;
  79. inword = 1;
  80. }
  81. if(c=='\\' && (isalpha(t[1]) || t[1]=='(')){
  82. switch(t[1]){
  83. case '(':
  84. m = 4;
  85. break;
  86. case 'f':
  87. if(t[2] == '(')
  88. m = 5;
  89. else
  90. m = 3;
  91. break;
  92. case 's':
  93. if(t[2] == '+' || t[2]=='-'){
  94. if(t[3] == '(')
  95. m = 6;
  96. else
  97. m = 4;
  98. }else{
  99. if(t[2] == '(')
  100. m = 5;
  101. else if(t[2]=='1' || t[2]=='2' || t[2]=='3')
  102. m = 4;
  103. else
  104. m = 3;
  105. }
  106. break;
  107. default:
  108. m = 2;
  109. }
  110. while(m-- > 0){
  111. if(*t == '\n')
  112. break;
  113. n++;
  114. t++;
  115. }
  116. continue;
  117. }
  118. Continue:
  119. n++;
  120. t += wid;
  121. }while(c != '\n');
  122. }
  123. Bterm(&b);
  124. }