! This TECO macro written by Pete Siemsen of Midcom (Orange, Ca.) to ! ! run under VAX/VMS V2.3 running TECO V36, 9-Mar-1982 ! ! ! ! This TECO macro changes one string to another in a set of files. It prompts! ! the user for a file specification (wildcards ok) and two strings: the old ! ! one and the new one. It then goes through the file(s), making the change. ! ! It is designed to be a convenient tool for users who are familiar with ! ! the SEARCH program on most VAXes. CHANGE prompts for input and displays its! ! output very like the SEARCH program. Note that the strings prompted for by ! ! this macro can be delimited: if the first character of the string is an ! ! , then only an will terminate the string, else both and ! ! will terminate the string. ! ! ! ! The general way this macro works is to build a hideous TECO command string ! ! in q-register B, then execute the command string. We need to build the ! ! string because we have to create an FN command, at least, to make the ! ! changes. ! ! ! ! Since much of the following TECO code is put into a q-register ! ! for later execution, confusion would be rampant without some comment ! ! scheme to keep things in order for the reader. Therefore, the lines of ! ! code that are executed 1 'level' down have a comment at the front of the ! ! line that says says 'level1'. This provides the reader (who's in TECO) ! ! with a quick way to look at only the command line being built. ! ! ! ! The following Q-registers are used: ! ! ! ! QA number ascii value of text character from the terminal ! ! ! ! QW number 0 if we haven't output the file specification of ! ! the file in which the string was found, 1 if we ! ! already have. This guy lets us output file specs ! ! only for those files which contain the string ! ! ! ! QX number 0 if no changes have been made, else > 0 ! ! This is only used to tell us if we should output ! ! the "No matches." string when we're done. ! ! ! ! QZ number 0 if we haven't changed a string in the file, 1 if ! ! we have. This guy tells us whether to close and kill ! ! the output file (when no changes were made in the ! ! file) or to close the output file normally (when ! ! changes have been made). ! ! ! ! QB text This is the biggee. It holds the TECO command string ! ! we are building. It is used twice, once to build and ! ! execute the EN command that presets the TECO ! ! wildcard lookup buffer, and once to build and ! ! execute the command string that does all the work. ! ! We could build just one string and execute it, but ! ! then the user wouldn't know that he's misspelled his ! ! file specification until after he's typed in the ! ! old and new strings. ! ! ! ! QE text holds an EB command so we can execute it ! ED#2ED ! make Y command work like it should ! Filename(s):  ! prompt for a file specification ! ! read the wildcard file specification from the terminal and use it ! ! in a TECO EN command to preset the wildcard lookup file specification ! ^UBen ! put EN in q-register B ! ! Do an EI$ to throw away extraneous input in the type-ahead buffer. See ! ! page 117-118 of the PDP-11 TECO User's Guide for an explanation of why ! ! this is necessary. ! EI < UA ! get a character from the terminal ! QA-127"E ! if it's a delete ! 8 ! send a backspace to the terminal ! 32 ! send a space to the terminal ! 8 ! send a backspace to the terminal ! HK ! clear the edit buffer ! GB ! get contents of q-register B ! B,Z-1XB ! copy back all but last character ! HK ! clear the edit buffer ! | ! else (it's not a delete) ! QA-27"E ! if it's an escape ! 1310 ! output ! 1; ! get out of the loop ! | ! else (it's not a delete or escape) ! QA-13"E ! if it's a ! 0,32ET ! set "read with no wait" !  ! get the line feed that follows ! 0,32ET ! set "read with wait" ! 1; ! and get out of the loop ! | ! else (not , , or ) ! QA:^UB ! append it to q-register B ! ' ! endif ! ' ! endif ! ' ! endif ! > 27:^UB ! append an escape to q-register B ! 27:^UB ! append an escape to q-register B ! MB ! execute the command in q-register B ! @^UB\ ! insert a string into q-register B ! ! level1 ! 0UX ! zero the 'strings changed' flag ! ! level1 ! < ! loop through all files ! ! level1 ! HK ! clear the edit buffer ! ! level1 ! :EN"S ! try to get a file specification ! ! level1 ! IEB ! start building an EB command ! ! level1 ! G* ! fill in the file specification ! ! level1 ! 27I ! put in the first terminating ! ! level1 ! 27I ! put in the second terminating ! ! level1 ! HXE ! load the EB command into q-reg E ! ! level1 ! ME ! the EB command opens the file ! ! level1 ! Y ! get the first page of input ! ! level1 ! 0UW ! zero the 'display filespec?' flag ! ! level1 ! 0UZ ! zero the 'save output file?' flag ! ! level1 ! < ! loop for all changes in this file ! ! level1 ! :FN ! make the actual change ! \ Search string:  ! prompt for the search string ! UA QA-27"E ! if it's an ! 1UE ! set 'escape terminator only' flag ! | ! else (first character not ) ! 0UE ! clear 'escape terminator only' flag ! ON1 ! jump into the loop ! ' ! endif ! < UA ! get a character from the terminal ! !N1! QA-127"E ! if it's a delete ! 8 ! send a backspace to the terminal ! 32 ! send a space to the terminal ! 8 ! send a backspace to the terminal ! HK ! clear the edit buffer ! GB ! get contents of q-register B ! B,Z-1XB ! copy back all but last character ! HK ! clear the edit buffer ! | ! else (it's not a delete) ! QA-27"E ! if it's an escape ! 1310 ! output ! 1; ! get out of the loop ! | ! else (it's not a delete or escape) ! QA-13"E ! if it's a ! QE"E ! if carriage returns terminate ! 0,32ET ! set "read with no wait" !  ! get the line feed that follows ! 0,32ET ! set "read with wait" ! 1; ! and get out of the loop ! | QA:^UB :^UB ' | ! else (not , , or ) ! QA:^UB ! append it to q-register B ! ' ! endif ! ' ! endif ! ' ! endif ! > 27:^UB New string to replace search string:  UA QA-27"E ! if it's an ! 1UE ! set 'escape terminator only' flag ! | ! else (first character not ) ! 0UE ! clear 'escape terminator only' flag ! ON2 ! jump into the loop ! ' ! endif ! < UA ! get a character from the terminal ! !N2! QA-127"E ! if it's a delete ! 8 ! send a backspace to the terminal ! 32 ! send a space to the terminal ! 8 ! send a backspace to the terminal ! HK ! clear the edit buffer ! GB ! get contents of q-register B ! B,Z-1XB ! copy back all but last character ! HK ! clear the edit buffer ! | ! else (it's not a delete) ! QA-27"E ! if it's an escape ! 1310 ! output ! 1; ! get out of the loop ! | ! else (it's not a delete or escape) ! QA-13"E ! if it's a ! QE"E ! if carriage returns terminate ! 0,32ET ! set "read with no wait" !  ! get the line feed that follows ! 0,32ET ! set "read with wait" ! 1; ! and get out of the loop ! | QA:^UB :^UB ' | ! else (not , , or ) ! QA:^UB ! append it to q-register B ! ' ! endif ! ' ! endif ! ' ! endif ! > @:^UB\ ! level1 !  ! terminate the :FN command ! ! level1 ! "S ! if a string was found ! ! level1 ! QW"E ! if haven't displayed file spec yet ! ! level1 ! 1UX ! make the 'any found?' flag true ! ! level1 ! 13 ! display a ! ! level1 ! 10 ! display a ! ! level1 ! :G* ! display the file specification ! ! level1 ! 13 ! display a ! ! level1 ! 10 ! display a ! ! level1 ! 10 ! display a ! ! level1 ! 1UW ! make 'display filespec?' flag false ! ! level1 ! ' ! endif ! ! level1 ! V ! view the changed line ! ! level1 ! 1UZ ! make the 'any found?' flag true ! ! level1 ! | ! else (search string not in file) ! ! level1 ! 1; ! terminate this loop ! ! level1 ! ' ! endif ! ! level1 ! > ! end of loop over the file ! ! level1 ! QZ"N ! if a string was found in this file ! ! level1 ! EC ! close and save the output file ! ! level1 ! | ! else (search string not in file) ! ! level1 ! EK ! close and delete the output file ! ! level1 ! ' ! endif ! ! level1 ! | ! else (no more files) ! ! level1 ! 1; ! terminate this loop ! ! level1 ! ' ! endif ! ! level1 ! > ! end of loop over all files ! ! level1 ! QX"E ! if didn't match the search string ! ! level1 ! No matches. ! tell the user ! ! level1 ! ' ! endif ! ! level1 ! ex ! and we are finally done ! \ 27:^UB MB