home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 3 / 3954 < prev    next >
Encoding:
Internet Message Format  |  1991-09-04  |  8.3 KB

  1. Path: wupost!zaphod.mps.ohio-state.edu!casbah.acns.nwu.edu!ucsd!ucsbcsl!dschub!sbanet!nixbbs!root
  2. From: root@nixbbs.UUCP (Donald Burr)
  3. Newsgroups: alt.sources
  4. Subject: A shellscript to make variables unique within 8 chars
  5. Message-ID: <1991Sep3.033418.4227@nixbbs.UUCP>
  6. Date: 3 Sep 91 03:34:18 GMT
  7. Reply-To: root@nixbbs.UUCP (Donald Burr)
  8. Distribution: alt
  9. Organization: NixBBS Public Access UNIX, Carpinteria, CA
  10. Lines: 277
  11.  
  12.  
  13. A lot of C compilers, especially those on older UNIX boxes, ignore anything
  14. after 8 characters, in variable and function declarations.  This is very
  15. annoying, especially if you're trying to compile more modern software
  16. (virtually anything from GNU, a lot of the stuff that comes over the net,
  17. etc.)
  18.  
  19. Until now, people have had to laboriously go through each and every code
  20. file, change all references of a particular variable or function to be
  21. unique within 8 characters, and recompile.  Frequently, this would take a
  22. long amount of time, and would be prone to error.
  23.  
  24. Now, there is a solution.  (Well, sort of.)  Here is a shell script that
  25. will do this process for function definitions only.  It's up to you to
  26. fix variable names.  But it takes some of the work out.  Plus, it leaves
  27. a record of what changes it made, so you can reverse engineer them if you
  28. must.
  29.  
  30. This runs under the Bourne Shell, and requires the system programs 'ctags'
  31. and 'sed', usually present on anything that calls itself Unix.  If you are
  32. on a BSD machine, you will (may) need to change two things.  First, delete
  33. the line that reads ": use /bin/sh", and replace it with "#!/bin/sh".
  34. Second , look through all the "echo" lines.  Currently they are of the
  35. form:
  36.  
  37. echo "stuff\c"
  38.  
  39. This form of echo suppresses the newline character at the end of the echo,
  40. so when the cursor is displayed, it is displayed after "stuff"; this creates
  41. a prompt.  On some systems, instead of doing "echo 'stuff\c'", you use
  42. a line of the following:
  43.  
  44. echo -n "stuff"
  45.  
  46. If this is true on your system, you will need to change all the echo state-
  47. ments.
  48.  
  49. Anyways, hope you enjoy this.  I am not the author, but I can get in touch
  50. with him.  If you have any comments, questions, bug fixes, etc. I would be
  51. happy to pass them along to the author.  Just mail them to me.
  52.  
  53. Enjoy.
  54.  
  55. BTW, don't forget, there's a .signature at the end of this article...
  56.  
  57. : use /bin/sh
  58. # Name: unique_nms
  59. #
  60. # Usage: unique_nms [ -y ] [ -v ] [ tagfilename ]
  61. #
  62. # Description: from the set of C source files in the current directory
  63. # (i.e., *.c and *.h), detects function names that aren't unique within
  64. # their first seven characters, and rewrites each reference to such
  65. # functions (including their definitions) with a unique prefix.
  66. #
  67. # If a tagfilename is specified, then the specified tagfilename is
  68. # taken to be a file created by 'ctags', representing the contents of
  69. # the C source files in the current directory, and up to date.  If no
  70. # tagfilename is specified, "tags" is assumed to be the tagfilename.
  71. # The script prompts for whether to restrict the edit to the files
  72. # specifically mentioned in the tagfile, regardless of whether a
  73. # tagfilename is specified on the command line.
  74. #
  75. # If the "-y" (for "yes" or "affirmative") switch is present, no
  76. # prompting will occur; the responses to all ordinary prompts will be
  77. # assumed to be "yes".
  78. #
  79. # If the "-v" (for "void") switch is present, then if a tags file must
  80. # be built, it will be built from copies of the specified source files
  81. # with references to the "void" type removed.  This is for versions of
  82. # 'ctags' that don't know about the "void" data type.  The implementation
  83. # is crude, requiring a physical copy of each source file so as not to
  84. # disturb the original.  The Tandy 6000 requires this switch for any
  85. # source fileset that contains "void" functions.
  86. #
  87. # Notes: this script generates a 'sed' scriptfile called "sedfile$$"
  88. # where "$$" is the current process number.  This file can be referred
  89. # to to keep track of changes made in the original source files; it's
  90. # pretty easy to reverse the changes made by this script with simple
  91. # massaging of the sedfile and re-running 'sed'.
  92. #
  93. # Copyright: this script was written by Fred Buck, who hereby releases
  94. # it into the public domain and expressly waives all copyright or
  95. # similar rights with respect to it.  This script is public property.
  96. # However, liability is disclaimed for any consequences of use of
  97. # this script.
  98.  
  99. trap "rm -f TEMP$$ *@ tags$$ /tmp/tag$$; exit 1" 1 2 15
  100.  
  101. # affirmative mode?
  102. if [ $# -gt 0 -a "$1" = "-y" ]
  103. then
  104.     AFFIRM="yes"
  105.     shift
  106. else
  107.     AFFIRM="no"
  108. fi
  109.  
  110. # anti-void mode?
  111. if [ $# -gt 0 -a "$1" = "-v" ]
  112. then
  113.     VOID="yes"
  114.     shift
  115. else
  116.     VOID="no"
  117. fi
  118.  
  119.  
  120. # usage section
  121. case $# in
  122. 0)
  123.     TAGFILE="tags"                ;;
  124. 1)    if [ ! -r $1 ]
  125.     then
  126.         echo "$0: can't open $1"
  127.         exit 1
  128.     else
  129.         TAGFILE="$1"
  130.     fi                    ;;
  131. *)    echo "usage: $0 [ -y ] [ -v ] [ tagfilename ]"
  132.     exit 1                    ;;
  133. esac
  134.  
  135. # check for readability of specified tags file
  136. if [ ! -r "$TAGFILE" ]
  137. then
  138.     if [ "$AFFIRM" = "no" ]
  139.     then
  140.         echo "'tags' file doesn't exist; generate it? \c"
  141.         read yesno
  142.         case $yesno in
  143.             [Yy]*)                    ;;
  144.             *)    echo "can't work without a tags file"
  145.             exit 1                    ;;
  146.         esac
  147.     fi
  148.     echo "calling 'ctags'....."
  149.     if [ "$VOID" = "no" ]
  150.     then
  151.         ctags *.c *.h
  152.     else
  153.         for SFILE in *.c *.h
  154.         do
  155.             0<$SFILE sed \
  156.                 -e 's/^void//'\
  157.                 -e 's/^static void/static/'\
  158.             1>$SFILE@
  159.         done
  160.         ctags *.c@ *.h@
  161.         mv tags tags$$
  162.         TAGFILE=/tmp/tag$$
  163.         0<tags$$ sed 's/@//' 1>$TAGFILE
  164.         rm tags$$
  165.     fi
  166. else
  167.     echo "The tags file is stamped as follows:"
  168.     echo
  169.     ls -l ./$TAGFILE
  170.     echo
  171.     if [ "$AFFIRM" = "no" ]
  172.     then
  173.         echo "Use it? \c"
  174.         read yesno
  175.         case $yesno in
  176.         [Yy]*)        echo "OK."                ;;
  177.         *)        echo "can't work without a tags file"
  178.                 exit 1                    ;;
  179.         esac
  180.     fi
  181. fi
  182.  
  183. # get to work
  184.  
  185.                 # first, find names ambiguous in 1st 7 chars;
  186.                 # and build a sed scriptfile to disambiguate 'em
  187.                 # (scriptfile will be sedfile$$).  This logic
  188.                 # will accommodate up to about seventeen
  189.                 # thousand ambiguous function names, with
  190.                 # gradually increasing probability that
  191.                 # some "[A-Z][A-Z][A-Z]_*" names may become
  192.                 # ambiguous.
  193. echo "Building edit scriptfile for ambiguous function names....."
  194. 0<$TAGFILE awk '
  195.     BEGIN {
  196.         a = "ABCDEFGFHIJKLMNOPQRSTUVWXYZ"
  197.         i1 = 1
  198.         i2 = 0
  199.         i3 = 0
  200.         l1 = 1
  201.         l2 = 0
  202.         l3 = 0
  203.     }
  204.     { if (substr($1,1,7) == prevsub) {
  205.         prefix = substr(a,i3,l3) substr(a,i2,l2) substr(a,i1,l1)
  206.         printf "s/^%s(/%s_&/\n", $1, prefix
  207.         printf "s/\\([^_]\\)\\(%s(\\)/\\1%s_\\2/g\n", $1, prefix
  208.         printf "s/\\([, \t]\\)\\(%s[^A-Za-z0-9_]\\)/\\1%s_\\2/g\n", \
  209.             $1, prefix
  210.         ++i1
  211.         if (i1 > 26) {
  212.             i1 = 1
  213.             ++i2
  214.             l2 = 1
  215.         }
  216.         if (i2 > 26) {
  217.             i2 = 1
  218.             ++i3
  219.             l3 = 1
  220.         }
  221.         if (i3 > 26) exit(1)
  222.       }
  223.     }
  224.     { prevsub = substr($1,1,7)
  225.     }'                1>sedfile$$
  226.  
  227.     if [ $? -gt 0 ]
  228.     then
  229.         echo "Fatal error: 'awk' failure" 1>&2
  230.         exit 1
  231.     fi
  232.  
  233.                 # if the sedfile is empty, bail out
  234. if [ ! -s sedfile$$ ]
  235. then
  236.     echo "All names in '$TAGFILE' are unique within the first 7 characters."
  237.     rm -f sedfile$$ /tmp/tag$$
  238.     exit 0
  239. fi
  240.  
  241.                 # let the user look over the sedfile first
  242. if [ "$AFFIRM" = "no" ]
  243. then
  244.     echo "Sed command file contains:"
  245.     /bin/more sedfile$$
  246.     echo " -- go ahead with edit? \c"
  247.     read yesno
  248.     case $yesno in
  249.         [Yy]*) echo ;;
  250.         *)     exit 1 ;;
  251.     esac
  252.     echo "Restrict edit to files mentioned in '$TAGFILE'? \c"
  253.     read yesno
  254.     case $yesno in
  255.         [Yy]*) TARGETS=`0<$TAGFILE awk '{ print $2 }' | sort -u` ;;
  256.         *)     TARGETS=`echo *.c *.h`                 ;;
  257.     esac
  258. else
  259.     echo "Restricting edit to files mentioned in '$TAGFILE'."
  260.     TARGETS=`0<$TAGFILE awk '{ print $2 }' | sort -u`
  261. fi
  262. echo "About to edit: $TARGETS" | tr '\012' ' '
  263. echo
  264.  
  265.                 # finally, run the 'sed' commandfile on
  266.                 # the files mentioned in $TAGFILE
  267. for FILE in $TARGETS
  268. do
  269.     echo "Editing $FILE:"
  270.     0<$FILE sed -f sedfile$$ 1>TEMP$$
  271.     if [ $? -eq 0 ]
  272.     then
  273.         mv TEMP$$ $FILE
  274.         echo "    $FILE successfully edited"
  275.     else
  276.         echo "  Can't edit $FILE!"
  277.     fi
  278. done
  279. rm -f TEMP$$
  280.  
  281. +--------------------------------------------+--------------------------------+
  282. : Donald Burr, System Administrator          : INTERNET: root@nixbbs.UUCP,    :
  283. : NixBBS Public Access UNIX, Carpinteria, CA :      72540.3071@compuserve.COM :
  284. :                                            : COMPUSERVE: 72540,3071         :
  285. : UUCP: uunet!nixbbs!root, nixbbs!root       : AMERICA ONLINE: DonaldBurr     :
  286. +--------------------------------------------+--------------------------------+
  287. :               Don't like my postings?  Call 1-800-dev-null.                 :
  288. +-----------------------------------------------------------------------------+
  289.