Changeset 6812

Show
Ignore:
Timestamp:
09/09/10 19:58:32 (17 months ago)
Author:
westram
Message:
  • merged r6753, r6788 + r6789 from refactor:
    • multiple attributes get promoted to headers
    • make depends scans __cplusplus sections
Location:
trunk
Files:
7 modified
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/AISC_MKPTPS/Makefile

    r6526 r6812  
    1212 
    1313.cxx.o: 
    14         $(CPP) $(cflags) -c $< $(POST_COMPILE) 
     14        $(CPP) $(cflags) -c $< $(CPPINCLUDES) $(POST_COMPILE) 
    1515 
    1616clean: 
  • trunk/AISC_MKPTPS/mkptypes.cxx

    r6706 r6812  
    2222#include <cctype> 
    2323#include <cstring> 
    24  
    25 #ifndef EXIT_SUCCESS 
    26 #define EXIT_SUCCESS  0 
    27 #define EXIT_FAILURE  1 
    28 #endif 
     24#include <cstdarg> 
     25 
     26#define SIMPLE_ARB_ASSERT 
     27#include <arb_assert.h> 
     28 
     29#define mp_assert(cond) arb_assert(cond) 
    2930 
    3031static void Version(); 
     
    100101} 
    101102 
     103static void errorf(const char *format, ...) __attribute__((format(__printf__, 1, 2))); 
     104static void errorf(const char *format, ...) { 
     105    const int BUFFERSIZE = 1000; 
     106    char      buffer[BUFFERSIZE]; 
     107    va_list   args; 
     108 
     109    va_start(args, format); 
     110    int printed = vsprintf(buffer, format, args); 
     111    if (printed >= BUFFERSIZE) { 
     112        fputs("buffer overflow\n", stderr); 
     113        exit(EXIT_FAILURE); 
     114    } 
     115    va_end(args); 
     116 
     117    error(buffer); 
     118} 
     119 
    102120// ------------------------------------------------------------ 
    103121 
     
    111129 
    112130static void setSymParts(SymPart*& symParts, const char *parts) { 
    113     assert(!symParts); 
     131    mp_assert(!symParts); 
    114132 
    115133    char       *p   = strdup(parts); 
     
    321339static void clear_found_attribute() { 
    322340    free(found__attribute__); found__attribute__ = 0; 
    323     free(found__ATTR__); found__ATTR__      = 0; 
    324 } 
     341    free(found__ATTR__);      found__ATTR__      = 0; 
     342} 
     343 
     344const char *nextNonSpace(const char* ptr) { 
     345    while (isspace(*ptr)) ++ptr; 
     346    return ptr; 
     347} 
     348const char *nextNonWord(const char* ptr) { 
     349    while (isalnum(*ptr) || *ptr == '_') ++ptr; 
     350    return ptr; 
     351} 
     352 
     353inline const char *matchingParen(const char *from) { 
     354    int open = 1; 
     355    int i; 
     356    for (i = 1; from[i] && open>0; ++i) { 
     357        switch (from[i]) { 
     358            case '(': open++; break; 
     359            case ')': open--; break; 
     360        } 
     361    } 
     362    if (open) return NULL; // no matching closing paren 
     363    return from+i-1; 
     364} 
     365 
     366// ----------------- 
     367//      LinePart 
     368 
     369class LinePart { 
     370    const char *line; 
     371    size_t      linelen; // of line 
     372 
     373    size_t pos; 
     374    size_t size; 
     375 
     376    bool part_is_legal() { return (pos <= linelen) && ((pos+size) <= linelen); } 
     377 
     378    void set(size_t newPos, size_t newSize) { 
     379        pos  = newPos; 
     380        size = newSize; 
     381        mp_assert(part_is_legal()); 
     382    } 
     383     
     384public: 
     385 
     386    LinePart(const char *wholeLine, size_t len = -1U) 
     387        : line(wholeLine), 
     388          linelen(len != -1U ? len : strlen(line)) 
     389    { 
     390        mp_assert(line[linelen] == 0); 
     391        undefine(); 
     392    } 
     393 
     394    size_t get_size() const { return size; } 
     395    bool   is_empty() const { return !size; } 
     396 
     397    const char *whole_line() const { return line; } 
     398 
     399    void define(const char *start, const char *end) { set(start-line, end-start+1); } 
     400    void undefine() { set(0, 0); } 
     401 
     402    void copyTo(char *buffer) const { 
     403        mp_assert(!is_empty()); 
     404        memcpy(buffer, line+pos, size); 
     405        buffer[size] = 0; 
     406    } 
     407 
     408    LinePart behind() const { 
     409        mp_assert(!is_empty()); 
     410        size_t behind_offset = pos+size; 
     411        mp_assert(linelen >= behind_offset); 
     412        return LinePart(line+behind_offset, linelen-behind_offset); 
     413    } 
     414 
     415    void error(const char *format) { 
     416        // 'format' has to contain one '%s' 
     417        mp_assert(!is_empty()); 
     418        char part[get_size()+1]; 
     419        copyTo(part); 
     420        errorf(format, part); 
     421        undefine(); 
     422    } 
     423}; 
     424 
     425 
     426// ------------------ 
     427//      PartQueue 
     428 
     429class PartQueue { 
     430    LinePart   first; 
     431    PartQueue *next; 
     432    size_t     size; 
     433 
     434    bool is_empty() const { return !size; } 
     435    size_t get_size() const { return size; } 
     436 
     437    void copyPartsTo(char *buffer) const { 
     438        mp_assert(!first.is_empty()); 
     439        first.copyTo(buffer); 
     440        buffer += first.get_size(); 
     441        if (next) { 
     442            *buffer++ = ' '; 
     443            next->copyPartsTo(buffer); 
     444        } 
     445    } 
     446 
     447public: 
     448    PartQueue(LinePart first_) 
     449        : first(first_), 
     450          next(0), 
     451          size(first.get_size()) 
     452    {} 
     453    ~PartQueue() { delete next; } 
     454 
     455    void append(PartQueue *mp) { 
     456        mp_assert(!next); 
     457        next  = mp; 
     458        size += 1+mp->get_size(); // add pos for space 
     459    } 
     460 
     461    char *to_string() { 
     462        char *result = (char *)malloc(get_size()+1); 
     463        copyPartsTo(result); 
     464        mp_assert(get_size() == strlen(result)); 
     465        return result; 
     466    } 
     467}; 
     468 
     469// ------------------------ 
     470//      AttributeParser 
     471 
     472class AttributeParser { 
     473    const char *attrName; 
     474    size_t      attrNameLen; 
     475    bool        expandName;   // try to expand 'attrName' 
     476    bool        expectParens; // otherwise parens are optional 
     477 
     478public: 
     479    AttributeParser(const char *attrName_, bool expandName_, bool expectParens_) 
     480        : attrName(attrName_), 
     481          attrNameLen(strlen(attrName)), 
     482          expandName(expandName_), 
     483          expectParens(expectParens_) 
     484    {} 
     485 
     486private: 
     487    void parse_one_attr(LinePart& part) const { 
     488        const char *found = strstr(part.whole_line(), attrName); 
     489        if (found) { 
     490            const char *behind     = found+attrNameLen; 
     491            if (expandName) behind = nextNonWord(behind); 
     492            const char *openParen  = nextNonSpace(behind); 
     493 
     494            if (*openParen == '(') { 
     495                const char *closeParen = matchingParen(openParen); 
     496                if (closeParen) part.define(found, closeParen); 
     497                else { 
     498                    part.define(found, openParen); 
     499                    part.error("Could not find matching paren after '%s'"); 
     500                } 
     501            } 
     502            else { 
     503                part.define(found, behind-1); 
     504                if (expectParens) part.error("Expected to see '(' after '%s'"); 
     505            } 
     506        } 
     507    } 
     508 
     509    // rest is not really part of this class - may go to abstract base class if needed 
     510 
     511    PartQueue *parse_all(LinePart from) const { 
     512        parse_one_attr(from); 
     513        if (from.is_empty()) return NULL; 
     514 
     515        PartQueue *head = new PartQueue(from); 
     516        PartQueue *rest = parse_all(from.behind()); 
     517        if (rest) head->append(rest); 
     518 
     519        return head; 
     520    } 
     521 
     522public: 
     523    char *parse(const char *toParse, size_t toParseSize) const { 
     524        char      *result           = NULL; 
     525        PartQueue *found_attributes = parse_all(LinePart(toParse, toParseSize)); 
     526 
     527        if (found_attributes) { 
     528            result = found_attributes->to_string(); 
     529            delete found_attributes; 
     530        } 
     531        return result; 
     532    } 
     533}; 
     534 
     535static AttributeParser attribute_parser("__attribute__", false, true); 
     536static AttributeParser ATTR_parser("__ATTR__", true, false); 
    325537 
    326538static void search_comment_for_attribute() { 
    327     char *att; 
    328  
    329     if (found__attribute__ || found__ATTR__) return; // only take first __attribute__ 
    330  
     539    if (found__attribute__ || found__ATTR__) return; // only parse once (until reset) 
    331540    last_comment[lc_size] = 0;  // close string 
    332541 
    333     att = strstr(last_comment, "__attribute__"); 
    334     if (att != 0) { 
    335         char *a  = att+13; 
    336         int   parens = 1; 
    337  
    338         while (*a && *a != '(') ++a; // search '(' 
    339         if (*a++ == '(') {    // if '(' found 
    340             while (parens && *a) { 
    341                 switch (*a++) { 
    342                     case '(': parens++; break; 
    343                     case ')': parens--; break; 
    344                 } 
    345             } 
    346             *a                 = 0; 
    347             DEBUG_PRINT("__attribute__ found!\n"); 
    348             found__attribute__ = strdup(att); 
    349             if (search__ATTR__) { error("found '__attribute__' but expected '__ATTR__..'"); } 
    350         } 
    351     } 
    352  
    353     att = strstr(last_comment, "__ATTR__"); 
    354     if (att != 0) { 
    355         char *a  = att+8; 
    356  
    357         while (*a && (isalnum(*a) || *a == '_')) ++a; // goto end of name 
    358  
    359         if (*a == '(') { 
    360             int parens = 1; 
    361             a++; 
    362  
    363             while (parens && *a) { 
    364                 switch (*a++) { 
    365                     case '(': parens++; break; 
    366                     case ')': parens--; break; 
    367                 } 
    368             } 
    369             *a = 0; 
    370             DEBUG_PRINT("__ATTR__ with parameters found!\n"); 
    371             found__ATTR__ = strdup(att); 
    372         } 
    373         else { 
    374             *a = 0; 
    375             DEBUG_PRINT("__ATTR__ w/o parameters found!\n"); 
    376             found__ATTR__ = strdup(att); 
    377         } 
    378         if (search__attribute__) { error("found '__ATTR__..' but expected '__attribute__'"); } 
     542    char *seen_attribute = attribute_parser.parse(last_comment, lc_size); 
     543    char *seen_ATTR      = ATTR_parser.parse(last_comment, lc_size); 
     544 
     545    if (search__attribute__) { 
     546        mp_assert(!search__ATTR__); 
     547        found__attribute__ = seen_attribute; 
     548        if (seen_ATTR) { 
     549            error("Expected not to see '__ATTR__..' (when looking for '__attribute__(...)')"); 
     550        } 
     551    } 
     552 
     553    if (search__ATTR__) { 
     554        mp_assert(!search__attribute__); 
     555        found__ATTR__ = seen_ATTR; 
     556        if (seen_attribute) { 
     557            error("Expected not to see '__attribute__(...)' (when looking for '__ATTR__..')"); 
     558        } 
    379559    } 
    380560 
     
    437617        char *behind_promo = promotion_found+promotion_tag_len; 
    438618        char *eol, *eoc; 
    439         assert(behind_promo[-1] == ':'); // wrong promotion_tag_len 
     619        mp_assert(behind_promo[-1] == ':'); // wrong promotion_tag_len 
    440620 
    441621        eol = strchr(behind_promo, '\n'); 
     
    455635        } 
    456636 
    457         assert(eol); 
     637        mp_assert(eol); 
    458638        if (!eol) { 
    459639            promotion_found = 0; 
     
    509689                c                       = ngetc(f); 
    510690                last_comment[lc_size++] = c; 
    511                 assert(lc_size<MAX_COMMENT_SIZE); 
     691                mp_assert(lc_size<MAX_COMMENT_SIZE); 
    512692 
    513693                if (lastc == '*' && c == '/') incomment = 0; 
     
    532712                c                       = ngetc(f); 
    533713                last_comment[lc_size++] = c; 
    534                 assert(lc_size<MAX_COMMENT_SIZE); 
     714                mp_assert(lc_size<MAX_COMMENT_SIZE); 
    535715 
    536716                if (lastc != '\\' && c == '\n') incomment = 0; 
     
    9511131#if !defined(AUTO_INT) 
    9521132            if (add_dummy_name) { 
    953                 assert(dummy_counter<100); 
     1133                mp_assert(dummy_counter<100); 
    9541134                dummy_name[DUMMY_COUNTER_POS] = (dummy_counter/10)+'0'; 
    9551135                dummy_name[DUMMY_COUNTER_POS] = (dummy_counter%10)+'0'; 
     
    15301710    fprintf(stderr, "%s 1.1 ARB\n", ourname); 
    15311711} 
     1712 
     1713// -------------------------------------------------------------------------------- 
     1714 
     1715#if (UNIT_TESTS == 1) 
     1716 
     1717#include <test_unit.h> 
     1718 
     1719inline char*& searchResult(bool ATTR) { return ATTR ? found__ATTR__ : found__attribute__; } 
     1720inline int& doSearchFor(bool ATTR) { return ATTR ? search__ATTR__ : search__attribute__; } 
     1721 
     1722inline const char *test_extract(bool ATTR, const char *str) { 
     1723    doSearchFor(ATTR)  = true; 
     1724    doSearchFor(!ATTR) = false; 
     1725 
     1726    clear_found_attribute(); 
     1727 
     1728    strcpy(last_comment, str); 
     1729    lc_size = strlen(last_comment); 
     1730 
     1731    search_comment_for_attribute(); 
     1732 
     1733    TEST_ASSERT(!searchResult(!ATTR)); 
     1734    return searchResult(ATTR); 
     1735} 
     1736 
     1737#define TEST_ATTR_____(comment,extracted) TEST_ASSERT_EQUAL(test_extract(true, comment), extracted) 
     1738#define TEST_attribute(comment,extracted) TEST_ASSERT_EQUAL(test_extract(false, comment), extracted) 
     1739 
     1740#define TEST_both(c,e) do { TEST_attribute(c,e); TEST_ATTR_____(c,e); } while(0) 
     1741 
     1742void TEST_attribute_parser() { 
     1743    TEST_both("", NULL); 
     1744    TEST_both("nothing here", NULL); 
     1745 
     1746    TEST_attribute("bla bla __attribute__(whatever) more content", "__attribute__(whatever)"); 
     1747    TEST_ATTR_____("bla bla __ATTR__DEPRECATED more content",      "__ATTR__DEPRECATED"); 
     1748    TEST_ATTR_____("bla bla __ATTR__FORMAT(pos) more content",     "__ATTR__FORMAT(pos)"); 
     1749     
     1750    TEST_ATTR_____("__ATTR__DEPRECATED",       "__ATTR__DEPRECATED"); 
     1751    TEST_ATTR_____("__ATTR__FORMAT(pos)",      "__ATTR__FORMAT(pos)"); 
     1752    TEST_ATTR_____("bla __ATTR__FORMAT(pos)",  "__ATTR__FORMAT(pos)"); 
     1753    TEST_ATTR_____("__ATTR__FORMAT(pos) bla",  "__ATTR__FORMAT(pos)"); 
     1754    TEST_ATTR_____("    __ATTR__FORMAT(pos) ", "__ATTR__FORMAT(pos)"); 
     1755     
     1756    TEST_ATTR_____("__ATTR__FORMAT((pos)",           NULL); 
     1757    TEST_ATTR_____("__attribute__(pos",              NULL); 
     1758    TEST_ATTR_____("__ATTR__FORMAT(pos))",           "__ATTR__FORMAT(pos)"); 
     1759    TEST_ATTR_____("__ATTR__FORMAT((pos))",          "__ATTR__FORMAT((pos))"); 
     1760    TEST_ATTR_____("__ATTR__FORMAT((pos)+((sop)))",  "__ATTR__FORMAT((pos)+((sop)))"); 
     1761    TEST_ATTR_____("__ATTR__FORMAT(((pos)))+(sop))", "__ATTR__FORMAT(((pos)))"); 
     1762 
     1763    TEST_ATTR_____("bla bla __ATTR__DEPRECATED __ATTR__FORMAT(pos) more content", "__ATTR__DEPRECATED __ATTR__FORMAT(pos)"); 
     1764    TEST_ATTR_____("bla __ATTR__DEPRECATED bla more__ATTR__FORMAT(pos)content", "__ATTR__DEPRECATED __ATTR__FORMAT(pos)"); 
     1765     
     1766    TEST_ATTR_____(" goes to header: __ATTR__NORETURN  */", "__ATTR__NORETURN"); 
     1767 
     1768    clear_found_attribute(); 
     1769} 
     1770 
     1771#endif 
  • trunk/ARBDB/ad_prot.h

    r6714 r6812  
    139139void GB_raise_critical_error(const char *msg); 
    140140GB_ERROR GB_export_error(const char *error); 
    141 GB_ERROR GB_export_errorf(const char *templat, ...) __ATTR__FORMAT(1); 
     141GB_ERROR GB_export_errorf(const char *templat, ...) __ATTR__FORMAT(1) __ATTR__DEPRECATED; 
    142142GB_ERROR GB_IO_error(const char *action, const char *filename); 
    143143GB_ERROR GB_export_IO_error(const char *action, const char *filename) __ATTR__DEPRECATED; 
  • trunk/ARBDB/adstring.cxx

    r6741 r6812  
    7373 
    7474GB_ERROR GB_export_errorf(const char *templat, ...) { 
    75     // goes to header: __ATTR__FORMAT(1) __ATTR__DEPRECATED 
     75    /* goes to header: 
     76     * __ATTR__FORMAT(1) 
     77     * __ATTR__DEPRECATED 
     78     *          because it's misused (where GBS_global_string should be used) 
     79     *          old functionality will remain available via 'GB_export_error(GBS_global_string(...))'  
     80     */ 
    7681 
    7782    char     buffer[GBS_GLOBAL_STRING_SIZE]; 
  • trunk/Makefile

    r6771 r6812  
    583583AINCLUDES := -I. -I$(ARBHOME)/INCLUDE $(XINCLUDES) 
    584584CPPINCLUDES := -I. -I$(ARBHOME)/INCLUDE $(XINCLUDES) 
    585 MAKEDEPENDFLAGS := -- $(cflags) -- -DARB_OPENGL -DUNIT_TESTS=1 -I. -Y$(ARBHOME)/INCLUDE 
     585MAKEDEPENDFLAGS := -- $(cflags) -- -DARB_OPENGL -DUNIT_TESTS=1 -D__cplusplus -I. -Y$(ARBHOME)/INCLUDE 
    586586 
    587587ifeq ($(VTABLE_INFRONTOF_CLASS),1) 
     
    15521552# for the moment, put all units containing tests into UNITS_TESTED: 
    15531553UNITS_TESTED = \ 
     1554        AISC_MKPTPS/mkptypes.test \ 
    15541555        PROBE_COM/client.test \ 
    15551556        TOOLS/arb_probe.test \ 
  • trunk/SOURCE_TOOLS/fix_depends.pl

    r6617 r6812  
    1212# to avoid CVS/SVN changes caused by formatting. 
    1313 
     14use strict; 
     15use warnings; 
     16 
    1417my $arbhome_quoted = quotemeta($ENV{ARBHOME}); 
    1518my $arbhome = qr/$arbhome_quoted/; 
    16 my $makedependlineseen = 0; 
    17 my @depends; 
    18  
    19 if (0) { 
    20   foreach (<>) { 
    21     print "ALL: $_"; 
    22   } 
    23  
    24   die "done"; 
    25 } 
    2619 
    2720sub fix_name($) { 
     
    2922  $name =~ s/^$arbhome/\$\(ARBHOME\)/ig; # translate $ARBHOME 
    3023  $name =~ s/^.\///ig; # remove './' at start 
    31    
     24 
    3225  # ensure there's a / behind '$(ARBHOME)' 
    3326  if ($name =~ /\$\(ARBHOME\)[^\/]/) { 
     
    3831} 
    3932 
    40 # read input stream 
    41 foreach (<>) { 
    42   if ($makedependlineseen==0) { # simply forward lines before 'DO NOT DELETE' 
    43     print "$_"; 
    44     if (/^\# DO NOT DELETE/) { $makedependlineseen = 1; } 
    45   } 
    46   else { # put lines behind into '@depends' 
    47     chomp; 
    48     if (/^ *[\/\$a-z]/i) { 
    49       if (/^([^:]*): *(.*)$/) { 
    50         my $file       = $1; 
    51         my $depends_on = $2; 
    52         $file = fix_name($file); 
    53  
    54         while ($depends_on =~ / /) { # split lines with multiple dependencies 
    55           my $name = $`; 
    56           my $rest = $'; 
    57           $name = fix_name($name); 
    58           push @depends, "$file: $name"; 
    59           $depends_on = $rest; 
    60         } 
    61         $depends_on = fix_name($depends_on); 
    62         $_ = "$file: $depends_on"; 
    63       } 
    64       push @depends,$_; 
    65     } 
    66   } 
    67 } 
    68  
    69 print "\n# Do not add dependencies manually - use 'make depend' in \$ARBHOME\n"; 
    70 print "# For formatting issues see SOURCE_TOOLS/fix_depends.pl\n"; 
    71  
    72 # sort dependency lines 
    73  
    74 sub beautiful($$) { 
     33sub arb_dependency_order($$) { 
    7534  # sorts files alphabetically (ign. case) 
    7635  # sorts local dependencies first (for each file) 
     
    9958} 
    10059 
    101 @depends = sort beautiful @depends; 
     60sub add_dependency(\@$$) { 
     61  my ($depends_r,$file,$depends_on) = @_; 
     62  $depends_on = fix_name($depends_on); 
    10263 
    103 # print dependency lines 
     64  # skip outside dependencies 
     65  if (not $depends_on =~ m@/usr/include/@) { 
     66    push @$depends_r, "$file: $depends_on"; 
     67  } 
     68} 
    10469 
    105 my $prefix = ''; 
    106 foreach (@depends) { 
    107   my $tprefix = ''; 
    108   if (/^([^:]*):/) { $tprefix = $1; } 
    109   if ($tprefix ne $prefix) { 
    110     print "\n"; # empty line between different files 
    111     $prefix = $tprefix; 
     70sub read_input_stream(\@) { 
     71  my ($depends_r) = @_; 
     72  my $makedependlineseen = 0; 
     73 
     74  foreach (<>) { 
     75    if ($makedependlineseen==0) { # simply forward lines until 'DO NOT DELETE' 
     76      print "$_"; 
     77      if (/^\# DO NOT DELETE/) { $makedependlineseen = 1; } 
     78    } 
     79    else { # put lines behind into '@depends' 
     80      chomp; 
     81      if (/^ *[\/\$a-z]/i) { # skip empty lines 
     82        if (/^([^:]*): *(.*)$/) { 
     83          my $file       = $1; 
     84          my $depends_on = $2; 
     85          $file = fix_name($file); 
     86 
     87          while ($depends_on =~ / /) { # split lines with multiple dependencies 
     88            my $name = $`; 
     89            my $rest = $'; 
     90 
     91            add_dependency(@$depends_r,$file,$name); 
     92            $depends_on = $rest; 
     93          } 
     94          add_dependency(@$depends_r,$file,$depends_on); 
     95        } 
     96        else { 
     97          push @$depends_r,$_; # what lines go here? 
     98        } 
     99      } 
     100    } 
    112101  } 
    113   print "$_\n"; 
    114102} 
     103 
     104sub main() { 
     105  my @depends=(); 
     106  read_input_stream(@depends); 
     107 
     108  @depends = sort arb_dependency_order @depends;  
     109 
     110  print "\n# Do not add dependencies manually - use 'make depend' in \$ARBHOME\n"; 
     111  print "# For formatting issues see SOURCE_TOOLS/fix_depends.pl\n"; 
     112 
     113  # print dependency lines 
     114  my $prefix = ''; 
     115  foreach (@depends) { 
     116    my $tprefix = ''; 
     117    if (/^([^:]*):/) { $tprefix = $1; } 
     118    if ($tprefix ne $prefix) { 
     119      print "\n"; # empty line between different files 
     120      $prefix = $tprefix; 
     121    } 
     122    print "$_\n"; 
     123  } 
     124} 
     125main(); 
  • trunk/UNIT_TESTER/Makefile.test

    r6743 r6812  
    2929# 
    3030RESTRICT_LIB=# run all tests 
     31#RESTRICT_LIB=mkptypes# test only these libraries 
    3132#RESTRICT_LIB=client:arb_probe:AWTC# test only these libraries 
    3233#RESTRICT_LIB=ARBDB# test only this library 
     
    6061EXEOBJDIRS=\ 
    6162        TOOLS \ 
     63        AISC_MKPTPS \ 
    6264 
    6365ISSHAREDLIB=$(findstring $(UNITDIR),$(SHAREDLIBS))