home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / UNIFLEX / UNIFLEX / UniFLEX_Std.Utils1.tar.Z / UniFLEX_Std.Utils1.tar / utils1 / find < prev    next >
Text File  |  1981-09-01  |  13KB  |  627 lines

  1.  nam Find - find string in file(s)
  2.  opt pag
  3.  pag
  4. ***  Find - find string in file(s)
  5.  spc 4
  6. ***  Program call.
  7. *
  8. *    find <file name(s)> <target string>
  9.  spc 4
  10. **   macro definitions.
  11.  spc 2
  12.  spc 4
  13. **   Local Macro Definitions.
  14.  spc 2
  15. **   msg - define message
  16. *
  17. * tag msg "text"[,terminator]
  18. *
  19. * defines "tag" concatencated with "l" to be length of message
  20.  spc 2
  21. msg macro
  22.  fcc "&1"
  23.  ifnc &2,""
  24.  fcb &2
  25.  endif
  26. &0l equ *-&0
  27.  endm
  28.  spc 2
  29. **   Messag - Write message.
  30. *
  31. *    messag file-descriptor,message-address[,message-length]
  32. *
  33. *    if "message-length" is not specified, the symbol for
  34. *    "message-address", concatenated with an "l", is used.
  35.  spc 2
  36. messag macro
  37.  ldd #&1
  38.  ifnc &3,""
  39.  sys write,&2,&3
  40.  else
  41.  sys write,&2,&2l
  42.  endif
  43.  endm
  44.  spc 4
  45. **   Symbol definitions
  46.  spc 2
  47.  lib sysdef
  48.  lib syserrors
  49. OWNERR equ 255 "own" error
  50.  
  51. INPUT equ 0 keyboard input file descriptor
  52. OUTPUT equ 1 display output file descriptor
  53. ERROUT equ 2 standard error output
  54. BUFSIZ equ 256 terminal i/o buffer size
  55. FBFSIZ equ 2048 file buffer size
  56. CRGRET equ $d carriage return
  57.  spc 4
  58. **   Variable definitions.
  59.  spc 2
  60.  org 0
  61.  
  62. ra rmb 2 restart address
  63. trmin rmb 11 keyboard i/o block
  64. trmout rmb 11 display i/o block
  65. filin rmb 11 file i/o block
  66. sa rmb 2 string address
  67. oc rmb 2 occurrence count
  68. fp rmb 2 file pointer
  69. ll rmb 2 line buffer limiting address
  70. ln rmb 2 line number
  71.  
  72. VARLEN rmb 0 length of variables
  73.  sttl Main program.
  74.  pag
  75. **   Main program.
  76.  
  77.  org 0
  78.  
  79. find leay 0,s remember argument address
  80.  ldd #VARLEN
  81.  
  82. find0 pshs a clear stack
  83.  decb
  84.  bne find0
  85.  leau 0,s set variable pointer
  86.  jsr prs preset
  87.  
  88. find1 jsr onf open next file
  89.  beq find3 if no more file names
  90. find2 jsr llb load line buffer
  91.  bvs find1 if end of file
  92.  jsr sfo search for occurrence
  93.  bra find2 loop through file
  94.  
  95. find3 clra terminate normally
  96.  clrb
  97.  sys term
  98.  spc 4
  99. **   abort - error exit
  100.  spc 2
  101. abort ldd #OWNERR
  102.  sys term
  103.  sttl Subroutines.
  104.  pag
  105. **   Subroutines.
  106.  spc 4
  107. **   ccf - close current file.
  108.  spc 2
  109. ccf ldd filin+5,u get descriptor
  110.  beq ccf1 if no file open
  111.  sys close close file
  112.  jsr poc print occurrence count
  113. ccf1 rts return
  114.  
  115. *
  116. * decst
  117. *
  118. * Convert the number in D into an ascii string
  119. * representing a decimal number.  The string
  120. * is pointed at by X (X should be set on entry!)
  121. * Also on exit, D has the length of the string.
  122. * The second entry point, 'decstn' will not print
  123. * leading spaces for leading zeroes, but will
  124. * suppress all leading zero info.  All strings
  125. * start with a space.
  126. *
  127.  
  128. decst pshs x save user pointer
  129.  clr 0,-s set suppression flag
  130.  bra decst2
  131. *
  132. decstn pshs x save user pointer
  133.  clr 0,-s
  134.  inc 0,s set for no fielding
  135. decst2 pshs a
  136.  lda #$20 setup leading space
  137.  sta 0,x+ save in buffer
  138.  puls a
  139.  clr 0,-s set up bookkeeping
  140.  clr 0,-s
  141.  ldy #conlst point to constants
  142. decst4 cmpd 0,y compare number to constant
  143.  blo decst5
  144.  subd 0,y do subtraction of constant
  145.  inc 1,s bump digits counter
  146.  bra decst4
  147. decst5 pshs a save number
  148.  tst 2,s zero digit?
  149.  bne decst6
  150.  tst 1,s any numbers output yet?
  151.  bne decst6
  152.  tst 3,s doing suppression?
  153.  bne decst8
  154.  lda #$20 set up space
  155.  bra decst7
  156. decst6 lda 2,s get digit count
  157.  inc 1,s set 'got one' flag
  158.  ora #$30 make ascii
  159. decst7 sta 0,x+ save in buffer
  160. decst8 puls a reset number
  161.  clr 1,s clear out digit
  162.  leay 2,y bump constant ptr
  163.  cmpy #conend end of list?
  164.  bne decst4
  165.  leas 3,s clean up stack
  166.  orb #$30 make last digit
  167.  stb 0,x+ save in buffer
  168.  clr 0,x null terminate string
  169.  tfr x,d
  170.  subd 0,s calculate string length
  171.  puls x,pc return
  172.  
  173. * constants for convert
  174.  
  175. conlst fdb 10000
  176.  fdb 1000
  177.  fdb 100
  178.  fdb 10
  179. conend equ * end of list
  180.  spc 4
  181. **   fob - flush output buffer.
  182. *
  183. *    entry (x)=i/o block pointer
  184.  spc 2
  185. fob pshs a,b,y
  186.  ldd 3,x save buffer size
  187.  pshs d
  188.  subd 9,x determine number of characters
  189.  beq fob1 if empty
  190.  std 3,x set character count to write
  191.  ldd 5,x (d)=file descriptor number
  192.  sys indx dump buffer
  193.  bec fob0 if no error
  194.  cmpd #EINTR check error number
  195.  bne fob2 if not "interrupted system call"
  196. fob0 ldd 1,x update character pointer
  197.  std 7,x
  198. fob1 puls d
  199.  std 3,x restore buffer size
  200.  std 9,x reset available space counter
  201.  puls a,b,y,pc return
  202.  
  203. fob2 leas 4,s remove (a), (b), and saved (d)
  204.  orcc #1 set carry, error encountered
  205.  puls y,pc return, cs
  206.  spc 4
  207. **   getchr - get next character from terminal.
  208. *
  209. *    entry "trmin"=i/o block address for terminal input
  210. *
  211. *    exit  cc if no error, and
  212. *          vc if not end of file, and
  213. *          (a)=character
  214. *     
  215. *          Message sent through device "ERROUT" if error detected.
  216.  spc 2
  217. getchr pshs x save (x)
  218.  leax trmin,u (x)=i/o block address
  219.  jsr gnc get character
  220.  bes getch1 if error detected
  221.  puls x,pc return
  222.  
  223. getch1 messag ERROUT,getca "Input error"
  224.  jmp abort
  225.  
  226. getca msg "Input Error",CRGRET
  227.  spc 4
  228. **   gnc - get next character.
  229. *
  230. *    entry (x)=i/o block pointer.
  231. *
  232. *    exit  cs if error detected, and
  233. *          (d)=error response
  234. *
  235. *          cc if no error, and
  236. *          vs if end of file
  237. *
  238. *          cc, vc if no end of file, and
  239. *          (a)=character
  240. *
  241. *    All registers not returning a response are preserved.
  242.  spc 2
  243. gnc pshs b,y
  244.  ldd 9,x get remaining character count
  245.  bne gnc1 if characters left in buffer
  246. gnc0 ldd 5,x (d)=file descriptor number
  247.  sys indx reload buffer
  248.  bes gnc3 if error
  249.  std 9,x save character count
  250.  beq gnc2 if end of file
  251.  ldd 1,x reset character pointer
  252.  std 7,x
  253.  ldd 9,x (d)=character count
  254. gnc1 subd #1 count character
  255.  std 9,x
  256.  ldy 7,x get character
  257.  lda 0,y+
  258.  sty 7,x update character pointer
  259.  clrb clear carry, overflow
  260.  puls b,y,pc return
  261.  
  262. gnc2 orcc #2 set overflow for end of file
  263.  puls b,y,pc return
  264.  
  265. gnc3 cmpd #EINTR check error
  266.  beq gnc0 if interrupted call, re-issue
  267.  orcc #1 set carry
  268.  leas 1,s remove (b)
  269.  puls y,pc return
  270.  spc 4
  271. **   llb - load line buffer.
  272. *
  273. *    exit  vs if end of file
  274.  spc 2
  275. llb ldy #lbuf preset buffer address
  276.  
  277. llb1 leax filin,u get character
  278.  jsr gnc
  279.  lbes llb2 if error detected
  280.  bvs llbxit if end of file
  281.  sta 0,y+ store character
  282.  cmpa #CRGRET check character
  283.  bne llb1 if not end of file
  284.  clr 0,-y store string terminator
  285.  sty ll,u
  286.  ldx ln,u advance line number
  287.  leax 1,x
  288.  stx ln,u
  289. llbxit rts return
  290.  
  291. llb2 jsr pem print error message
  292.  jmp abort
  293.  spc 4
  294. **   onf - open next file.
  295. *    exit  eq set if no more names
  296.  spc 2
  297. onf jsr ccf close current file
  298.  ldx fp,u skip current file name
  299. onf1 lda 0,x+
  300.  bne onf1
  301.  stx fp,u update pointer
  302.  cmpx sa,u check address
  303.  beq onfxit if end of file names
  304.  ldy #0
  305.  lda #open
  306.  pshs a,x,y build function block
  307.  leax 0,s
  308.  sys indx
  309.  leas 5,s
  310.  bes onf2 if error during open
  311.  leax filin,u
  312.  std 5,x save descriptor
  313.  ldd 1,x reset i/o block
  314.  std 7,x
  315.  clra
  316.  clrb
  317.  std 9,x
  318.  std ln,u clear line number
  319.  std oc,u clear occurrence count
  320.  ldd #FBFSIZ
  321.  std 3,x
  322. onfxit rts return
  323.  
  324. onf2 pshs d
  325.  messag OUTPUT,onfa
  326.  puls d
  327.  sys term
  328.  
  329. onfa msg "Error opening data file",CRGRET
  330.  spc 4
  331. **   pcrlf - start new line
  332.  spc 2
  333. pcrlf lda #CRGRET output carriage return
  334.  jmp putchr
  335.  spc 4
  336. **   pem - print error message
  337. *
  338. *    entry (d)=UniFLEX error code
  339. *    exit  message printed with leading and trailing
  340. *          carriage returns.
  341.  spc 2
  342. pem bsr per get message address
  343.  pshs x save message address
  344.  jsr pcrlf start new line
  345.  jsr pstrng print message
  346.  jsr pcrlf terminate line
  347.  puls x restore message address
  348.  cmpx #fatal check address
  349.  lbeq abort if fatal error
  350.  rts return
  351.  spc 4
  352. **   per - process error response.
  353. *    entry (d)=UniFLEX error code
  354. *    exit  (x)=error message address
  355.  spc 2
  356. per leax <pera-2,pcr (x)=message address table
  357.  lslb multiply error code by 2
  358.  rola
  359.  ldx d,x (x)=message address
  360.  cmpd #peral check message number
  361.  bls per1 if legitimate message
  362.  ldx #nomsg "Unknown error"
  363. per1 rts return
  364.  spc 2
  365. **   Error message index table.
  366.  
  367. pera fdb eio
  368.  fdb fatal
  369.  fdb fatal
  370.  fdb fatal
  371.  fdb edful
  372.  fdb etmfl
  373.  fdb ebadf
  374.  fdb enofl
  375.  fdb emsdr
  376.  fdb eprm
  377.  fdb eflx
  378.  fdb ebarg
  379.  fdb eseek
  380.  fdb exdev
  381.  fdb fatal
  382.  fdb fatal
  383.  fdb fatal
  384.  fdb ebdev
  385.  fdb eargc
  386.  fdb eisdr
  387.  fdb fatal
  388.  fdb fatal
  389.  fdb fatal
  390.  fdb enchd
  391.  fdb etmts
  392.  fdb fatal
  393.  fdb eintr
  394.  fdb fatal
  395.  fdb fatal
  396.  fdb fatal
  397. peral equ *-pera length of address table
  398.  spc 2
  399. **   Error messages.
  400.  
  401. eio fcc 'I/O error',0
  402. edful fcc 'Disk is full',0
  403. etmfl fcc 'Too many files are open',0
  404. ebadf fcc 'File structure error',0
  405. enofl fcc 'File does not exist',0
  406. emsdr fcc 'Directory does not exist',0
  407. eprm fcc 'Access permission fault',0
  408. eflx fcc 'File already exists',0
  409. ebarg fcc 'Bad argument',0
  410. eseek fcc 'Seek error',0
  411. exdev fcc 'Crossed devices',0
  412. ebdev fcc 'Bad device specified',0
  413. eargc fcc 'Too many arguments specified',0
  414. eisdr fcc 'File is actually a directory',0
  415. enchd fcc 'No child task exists',0
  416. etmts fcc 'Too many tasks are active',0
  417. eintr fcc 'Interrupted system call',0
  418. nomsg fcc 'Unknown error',0
  419. fatal fcc 'Unexpected error, program aborted',0
  420.  spc 4
  421. **   pnc - put next character.
  422. *
  423. *    entry (a)=character
  424. *          (x)=i/o block pointer
  425. *
  426. *    exit  cc if no error, and
  427. *          (a)=character
  428. *          cs if error, and
  429. *          (d)=error code
  430.  spc 2
  431. pnc pshs a,b,y
  432.  ldd 9,x get remaining room count
  433.  bne pnc1 if room left in buffer
  434.  ldd 5,x get file descriptor number
  435.  sys indx dump buffer
  436.  bec pnc0 if no error
  437.  cmpd #EINTR check error
  438.  bne pnc3 if not interrupted call
  439. pnc0 ldd 1,x update character pointer
  440.  std 7,x
  441.  ldd 3,x (d)=new remaining size
  442. pnc1 subd #1 count character
  443.  std 9,x update remaining count
  444.  ldy 7,x store character
  445.  puls a
  446.  sta 0,y+
  447.  sty 7,x update character address
  448. pnc2 puls b,y,pc return
  449.  
  450. pnc3 leas 2,s remove character and (b)
  451.  orcc #1 set carry, error detected
  452.  puls y,pc return, cs, (d)=error code
  453.  spc 4
  454. **   poc - print occurrence count.
  455.  spc 2
  456. poc ldx #poca preset "No"
  457.  ldd oc,u get count
  458.  beq poc1 if none found
  459.  ldx #nbuf
  460.  jsr decstn convert string
  461.  clr d,x terminate string
  462.  ldx #nbuf
  463. poc1 jsr pstrng print string
  464.  ldx #pocb "occurrence"
  465.  jsr pstrng
  466.  ldd oc,u
  467.  cmpd #1
  468.  bls poc2 if 0 or 1 occurrence
  469.  lda #'s form plural
  470.  jsr putchr
  471. poc2 ldx #pocc "found in file "
  472.  jsr pstrng
  473.  ldx fp,u print file name
  474.  jsr pstrng
  475.  jsr pcrlf terminate line
  476.  jsr pcrlf skip a line
  477.  rts return
  478.  
  479. poca fcc "No",0
  480. pocb fcc " occurrence",0
  481. pocc fcc " found in file ",0
  482.  spc 4
  483. **   prs - preset
  484. *
  485. *     entry (y)=address of arguments
  486. *     exit  (sa)=address of string
  487. *           (fp)=address of program name
  488.  spc 2
  489. prs
  490.  ldd 0,y get argument count
  491.  cmpd #2
  492.  bls prsisf if insufficient arguments
  493.  lslb multiply count by 2
  494.  rola
  495.  ldd d,y get address of string
  496.  std sa,u
  497.  ldd 2,y preset file point to program name
  498.  std fp,u
  499.  
  500. *    Initialize buffered i/o blocks.
  501.  
  502.  leax trmin,u (x)=block address
  503.  lda #read
  504.  sta 0,x store i/o function code
  505.  ldy #ibuf
  506.  sty 1,x store buffer fwa
  507.  sty 7,x store first character address
  508.  ldd #INPUT
  509.  std 5,x store descriptor
  510.  ldd #BUFSIZ
  511.  std 3,x store buffer size
  512.  clr 9,x clear character count
  513.  clr 10,x
  514.  
  515.  leax trmout,u (x)=block address
  516.  ldd #OUTPUT
  517.  std 5,x store descriptor
  518.  lda #write
  519.  sta 0,x store i/o function code
  520.  ldy #obuf
  521.  sty 1,x store buffer fwa
  522.  sty 7,x store first character address
  523.  ldd #BUFSIZ
  524.  std 3,x store buffer size
  525.  std 9,x set available space count
  526.  
  527.  leax filin,u (x)=block address
  528.  lda #read
  529.  sta 0,x store i/o function code
  530.  ldy #sbuf
  531.  sty 1,x store buffer fwa
  532.  sty 7,x store first character address
  533.  ldd #INPUT
  534.  std 5,x store descriptor
  535.  ldd #FBFSIZ
  536.  std 3,x store buffer size
  537.  clr 9,x clear character count
  538.  clr 10,x
  539.  rts return
  540.  
  541. prsisf messag ERROUT,prsa
  542.  jmp abort abort program
  543.  
  544. prsa msg "Insufficient arguments",CRGRET
  545.  spc 4
  546. **   pstrng - print string
  547. *    entry (x)=address of string
  548.  spc 2
  549. pstrn1 jsr putchr output character
  550.  
  551. pstrng lda 0,x+ get character
  552.  bne pstrn1 if not end of string
  553.  rts return
  554.  spc 4
  555. **   putchr - send character to terminal.
  556. *
  557. *    entry (a)=character
  558. *          "trmout"=i/o block for terminal
  559. *
  560. *    exit  message sent through "ERROUT" if
  561. *          error detected.
  562.  spc 2
  563. putchr pshs x save (x)
  564.  leax trmout,u (x)=i/o block address
  565.  jsr pnc put character
  566.  bes putch2 if error
  567.  cmpa #CRGRET check character
  568.  bne putch1 if not end of line
  569.  jsr fob flush output buffer
  570. putch1 puls x,pc return
  571.  
  572. putch2 messag ERROUT,putca "Output error"
  573.  jmp abort
  574.  
  575. putca msg "Output Error",CRGRET
  576.  spc 4
  577. **   sfo - search for occurrence.
  578.  spc 2
  579. sfo ldx #lbuf
  580.  
  581. sfo1 cmpx ll,u check address
  582.  beq sfoxit if end of string
  583.  
  584. sfo2 ldy sa,u (y)=string address
  585.  stx ra,u save restart address
  586. sfo4 lda 0,y+ get string character
  587.  beq sfofnd if end of string, match
  588.  cmpa 0,x+ check character
  589.  bne sfo6 if no match
  590.  cmpx ll,u check address
  591.  blo sfo4 if not at end of line
  592.  lda 0,y check next string character
  593.  beq sfofnd if end of string
  594. sfo6 ldx ra,u set restart address
  595.  leax 1,x
  596.  bra sfo1
  597.  
  598. sfoxit rts return
  599.  
  600. sfofnd ldx oc,u count occurrence
  601.  leax 1,x
  602.  stx oc,u
  603.  ldx fp,u print file name
  604.  jsr pstrng
  605.  ldx #nbuf print line number
  606.  ldd ln,u
  607.  jsr decst
  608.  clr d,x
  609.  ldx #nbuf
  610.  jsr pstrng
  611.  lda #'= print "="
  612.  jsr putchr
  613.  ldx #lbuf print line
  614.  jsr pstrng
  615.  jmp pcrlf terminate line, return
  616.  sttl Buffers
  617.  pag
  618. **   Buffers.
  619.  spc 2
  620. ibuf rmb BUFSIZ keyboard input buffer
  621. obuf rmb BUFSIZ display output buffer
  622. sbuf rmb FBFSIZ file buffer
  623. nbuf rmb 10 number conversion buffer
  624. lbuf rmb 0 line buffer
  625.  
  626.  end find
  627.