home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1999 March B / SCO_CASTOR4RRT.iso / cmds / root.3 / usr / lib / crash / addstruct / addstruct~
Text File  |  1998-08-19  |  8KB  |  327 lines

  1. #ident    "@(#)crash:i386at/cmd/crash/addstruct    1.1.1.1"
  2.  
  3. #if 0    /* begin addstruct shell script within offstruct C source */
  4. : #
  5. : #    Copyright (C) 1996-1997 The Santa Cruz Operation, Inc.
  6. : #        All Rights Reserved.
  7. : #    The information in this file is provided for the exclusive use of
  8. : #    the licensees of The Santa Cruz Operation, Inc.  Such users have the
  9. : #    right to use, modify, and incorporate this code into other products
  10. : #    for purposes authorized by the license agreement provided they include
  11. : #    this notice and the associated copyright notice with any such product.
  12. : #    The information in this file is provided "AS IS" without warranty.
  13. : #
  14. : #    addstruct: script to generate structure offset tables for crash(1M)
  15. : #    through its "addstruct" command (or the script can be run manually).
  16. : #
  17. : #    addstruct needs cc, and ld for .so, to be installed on the system;
  18. : #    it works with temporary files tmpstruct* in the current directory.
  19. : #
  20. : #    addstruct may fail on some header files: the header file may need
  21. : #    preparatory editing, or the "offstruct" source at the end of this
  22. : #    script may need more sophistication.
  23. : #
  24.  
  25. if [ $# -lt 2 ]
  26. then    echo \
  27.     "usage: sh $0 structname \"hdrfile[s]\" [ outfile ] [ ccline ]" >&2
  28.     exit 2
  29. fi
  30.  
  31. crashlib=/usr/lib/crash
  32.  
  33. structname=$1
  34. shift
  35. hdrfiles=$1
  36. shift
  37.  
  38. if [ $# -gt 0 ]
  39. then    outfile=$1
  40.     shift
  41.     case "$outfile" in
  42.     *.c)    ;; # generate source for editing or linking with others
  43.     *.h)    ;; # generate source for editing or inclusion in others
  44.     *.o)    ;; # generate object for static linking into /etc/crash
  45.     *.so)    ;; # generate shared object for dynlink from /usr/lib/crash
  46.     *)    echo "addstruct: outfile $outfile must be .c or .h or .o or .so" >&2
  47.         exit 2
  48.         ;;
  49.     esac
  50. else    outfile=$crashlib/${structname}offs.so
  51. fi
  52.  
  53. if [ $# -gt 0 ]
  54. then    cc=$1
  55.     shift
  56. else    cc=cc
  57. fi
  58. if [ $# -gt 0 ]
  59. then    ccargs=$*
  60. else    ccargs="-Xa -D_KERNEL -DBUG386B1 -DMERGE386 -DV86MODE -DEVGA -DCLIENT_DELAY_DELETE -DIAPX386 -D_M_I386 -DM_I386 -DM_UNIX -D_INKERNEL -D_NO_PROTOTYPE -D_SVID3"
  61. : #    -D_M_I386 through -D_SVID3 are for OpenServer not UnixWare header files
  62. fi
  63.  
  64. rm -f tmpstruct.c tmpstruct.i tmpstruct.o tmpstruct
  65. touch tmpstruct.c && rm -f tmpstruct.c        || exit 1
  66. if [ -f "$outfile" ]    # validate permission in advance
  67. then    touch "$outfile"            || exit 1
  68. else    touch "$outfile" && rm -f "$outfile"    || exit 1
  69. fi
  70.  
  71. outofdate=testit
  72. if [ -f ./addstruct ]
  73. then    addstruct=./addstruct
  74.     offstruct=./offstruct
  75. else    addstruct=$crashlib/addstruct
  76.     offstruct=$crashlib/offstruct
  77.     if   [ -w $crashlib ]
  78.     then    :
  79.     elif [ -x $offstruct ]
  80.     then    outofdate=
  81.     else    offstruct=./offstruct
  82.     fi
  83. fi
  84. [ -n "$outofdate" ] && outofdate=`find $addstruct -newer $offstruct 2>/dev/null`
  85. [ -n "$outofdate" ] && rm -f $offstruct
  86.  
  87. if [ ! -x $offstruct ]
  88. then    rm -f $offstruct
  89.     cp $addstruct tmpstruct.c         || exit 1
  90.     $cc -O -s -o tmpstruct tmpstruct.c    || exit 1
  91.     rm -f tmpstruct.c            || exit 1
  92.     chmod a+x tmpstruct
  93.     mv -f tmpstruct $offstruct        || exit 1
  94. fi
  95.  
  96. touch tmpstruct.c                || exit 1
  97. for f in $hdrfiles
  98. do    echo "#include \"$f\"" >>tmpstruct.c    || exit 1
  99. done
  100. $cc -P $ccargs tmpstruct.c            || exit 1
  101. mv -f tmpstruct.i tmpstruct.c            || exit 1
  102. $offstruct "$structname" tmpstruct.c        || exit 1
  103. $cc -O -s -o tmpstruct tmpstruct.c        || exit 1
  104. ./tmpstruct > tmpstruct.c            || exit 1
  105. rm -f tmpstruct
  106.  
  107. case "$outfile" in
  108. *.c)    mv -f tmpstruct.c "$outfile"        || exit 1
  109.     ;;
  110. *.h)    mv -f tmpstruct.c "$outfile"        || exit 1
  111.     ;;
  112. *.o)    $cc $ccargs -c tmpstruct.c         || exit 1
  113.     rm -f tmpstruct.c
  114.     mv -f tmpstruct.o "$outfile"        || exit 1
  115.     ;;
  116. *.so)    set -f
  117.     echo "struct offstable *offstab[] = {${structname}offs,0};">>tmpstruct.c
  118.     $cc $ccargs -Kpic -c tmpstruct.c    || exit 1
  119.     rm -f tmpstruct.c
  120.     ld -G -dy -o "$outfile" tmpstruct.o    || exit 1
  121.     rm -f tmpstruct.o
  122.     ;;
  123. esac
  124. exit 0
  125.  
  126. #endif    /* end addstruct shell script: begin offstruct C source */
  127.  
  128. #include <stdio.h>
  129. #include <string.h>
  130. #include <ctype.h>
  131.  
  132. char usage[] = "usage: offstruct structname cppcbfile\n";
  133.  
  134. islabel(char *ptr)
  135. {
  136.     static int parens;
  137.     if (*ptr == ']') {
  138.         parens++;
  139.         return 0;
  140.     }
  141.     if (*ptr == '[') {
  142.         parens--;
  143.         return 0;
  144.     }
  145.     if (parens)
  146.         return 0;
  147.     while (isdigit(*ptr))
  148.         --ptr;
  149.     return (*ptr == '_' || isalpha(*ptr));
  150. }
  151.  
  152. main(int argc, char *argv[])
  153. {
  154.     char *filename, *structname;
  155.     char buf[BUFSIZ+1];
  156.     char *ptr, *eptr;
  157.     FILE *ifp, *ofp;
  158.     size_t namelen;
  159.     long typeoffset;
  160.     int parens, bitfield;
  161.  
  162.     if (argc != 3) {
  163.         fprintf(stderr, usage);
  164.         exit(2);
  165.     }
  166.     structname = argv[1];
  167.     filename = argv[2];
  168.     namelen = strlen(structname);
  169.     if ((ifp = fopen(filename, "r")) == NULL) {
  170.         fprintf(stderr,
  171.             "offstruct: cannot open %s for reading\n", filename);
  172.         exit(1);
  173.     }
  174.     if ((ofp = fopen(filename, "a")) == NULL) {
  175.         fprintf(stderr,
  176.             "offstruct: cannot open %s for writing\n", filename);
  177.         exit(1);
  178.     }
  179.     typeoffset = 0;
  180.     while ((ptr = fgets(buf+1, BUFSIZ, ifp)) != NULL) {
  181.         while (isspace(*ptr))
  182.             ptr++;
  183.         if (*ptr == '#' || *ptr == '\0')
  184.             continue;
  185.         if (typeoffset) {
  186.             if (*ptr++ != '}')
  187.                 continue;
  188.             while (isspace(*ptr))
  189.                 ++ptr;
  190.             if (strncmp(ptr, structname, namelen) == 0
  191.             && (ptr[namelen] == ';' || isspace(ptr[namelen]))) {
  192.                 fseek(ifp, typeoffset, SEEK_SET);
  193.                 break;
  194.             }
  195.             else {
  196.                 typeoffset = 0;
  197.                 continue;
  198.             }
  199.         }
  200.         if (strncmp(ptr, "typedef", 7) == 0
  201.         &&  isspace(ptr[7])) {
  202.             ptr += 8;
  203.             while (isspace(*ptr))
  204.                 ++ptr;
  205.             typeoffset = 1;
  206.         }
  207.         if (strncmp(ptr, "struct", 6) == 0
  208.         &&  isspace(ptr[6])) {
  209.             ptr += 7;
  210.             while (isspace(*ptr))
  211.                 ++ptr;
  212.             if (strncmp(ptr, structname, namelen) == 0
  213.             &&  isspace(ptr[namelen])) {
  214.                 typeoffset = 0;
  215.                 ptr += namelen;
  216.             }
  217.             else if (typeoffset) {
  218.                 while (*ptr == '_'
  219.                 || isalpha(*ptr) || isdigit(*ptr))
  220.                     ++ptr;
  221.             }
  222.             else
  223.                 continue;
  224.             while (isspace(*ptr))
  225.                 ++ptr;
  226.             if (*ptr == '\0')
  227.                 parens = -1;
  228.             else if (*ptr == '{')
  229.                 parens = 0;
  230.             else {
  231.                 typeoffset = 0;
  232.                 continue;
  233.             }
  234.             if (typeoffset)
  235.                 typeoffset = ftell(ifp);
  236.             else
  237.                 break;
  238.         }
  239.         else
  240.             typeoffset = 0;
  241.     }
  242.     if (ptr == NULL) {
  243.         fprintf(stderr, "offstruct: cannot find struct %s in %s\n",
  244.             structname, filename);
  245.         exit(1);
  246.     }
  247.  
  248.     fprintf(ofp, "setoff(structptr)\nchar *structptr;\n{\n");
  249.     fprintf(ofp, "\tchar *fieldptr = structptr - 1;\n");
  250.     fprintf(ofp, "\twhile (*++fieldptr == 0);\n");
  251.     fprintf(ofp, "\treturn fieldptr - structptr;\n}\n\n");
  252.     fprintf(ofp, "main()\n{\n");
  253.     if (typeoffset != 0)
  254.         fprintf(ofp, "\t%s temp;\n", structname);
  255.     else
  256.         fprintf(ofp, "\tstruct %s temp;\n", structname);
  257.     fprintf(ofp, "\tprintf(\"#ifndef _OFFSTABLE\\n#define _OFFSTABLE\\n\");\n");
  258.     fprintf(ofp, "\tprintf(\"struct offstable {long offset; char *name;};\\n\");\n");
  259.     fprintf(ofp, "\tprintf(\"#endif\\n\");\n");
  260.     fprintf(ofp, "\tprintf(\"struct offstable %soffs[] = {\\n\");\n", structname);
  261.     fprintf(ofp, "\tprintf(\"0x%%04x,\\\"%s\\\",\\n\"", structname);
  262.     fprintf(ofp, ",sizeof(temp));\n");
  263.     fprintf(ofp, "\tmemset(&temp,0,sizeof(temp));\n");
  264.  
  265.     eptr = NULL;
  266.     bitfield = 0;
  267.     while ((ptr = eptr) || (ptr = fgets(buf+1, BUFSIZ, ifp))) {
  268.         eptr = NULL;
  269.         while (isspace(*ptr))
  270.             ptr++;
  271.         if (*ptr == '#' || *ptr == '\0')
  272.             continue;
  273.         if ((eptr = strpbrk(ptr, ",;")) != NULL)
  274.             *eptr++ = '\0';
  275.         *(ptr-1) = '\0';
  276.         while (*ptr) {
  277.             if (*ptr == '}') {
  278.                 *ptr = '\0';
  279.                 --parens;
  280.             }
  281.             if (*ptr == '{')
  282.                 ++parens;
  283.             ++ptr;
  284.         }
  285.         if (parens < 0)
  286.             break;
  287.         if (parens > 0)
  288.             continue;
  289.         while (*--ptr) {
  290.             if (*ptr == ':' && bitfield++)
  291.                 break;
  292.             if (islabel(ptr))
  293.                 break;
  294.         }
  295.         if (*ptr == '\0'
  296.         ||  *ptr == ':')
  297.             continue;
  298.         *++ptr = '\0';
  299.         while (*--ptr) {
  300.             if (!islabel(ptr))
  301.                 break;
  302.         }
  303.         ++ptr;
  304.         if (bitfield == 1) {
  305.             bitfield = 2;
  306.             fprintf(ofp, "\ttemp.%s = 1;\n", ptr);
  307.             fprintf(ofp, "\tprintf(\"0x%%04x,\\\"%s\\\",\\n\"",ptr);
  308.             fprintf(ofp, ",setoff((char *)&temp));\n", ptr);
  309.             fprintf(ofp, "\ttemp.%s = 0;\n", ptr);
  310.         }
  311.         else {
  312.             bitfield = 0;
  313.             fprintf(ofp, "\tprintf(\"0x%%04x,\\\"%s\\\",\\n\"",ptr);
  314.             fprintf(ofp, ",(int)&temp.%s - (int)&temp);\n", ptr);
  315.         }
  316.     }
  317.     if (ptr == NULL) {
  318.         fprintf(stderr, "offstruct: cannot find end of struct %s\n",
  319.             structname);
  320.         exit(1);
  321.     }
  322.     fprintf(ofp, "\tprintf(\"0x%%04x,0};\\n\",sizeof(temp));\n");
  323.     fprintf(ofp, "\texit(0,0);\n}\n");
  324.     exit(0);
  325. }
  326. /* end offstruct C source and file */
  327.