]> git.sur5r.net Git - openldap/blob - contrib/slapd-tools/wrap_slap_ops
Happy New Year
[openldap] / contrib / slapd-tools / wrap_slap_ops
1 #!/usr/bin/perl -wn0777
2 # wrap_slap_ops - Help update code to use SLAP_OP() & co.
3 #
4 # This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 #
6 # Copyright 2011-2015 The OpenLDAP Foundation.
7 # Portions Copyright 2011-2013 Hallvard B. Furuseth.
8 # All rights reserved.
9 #
10 # Redistribution and use in source and binary forms, with or without
11 # modification, are permitted only as authorized by the OpenLDAP
12 # Public License.
13 #
14 # A copy of this license is available in the file LICENSE in the
15 # top-level directory of the distribution or, alternatively, at
16 # <http://www.OpenLDAP.org/license.html>.
17
18 use strict;
19
20 sub usage() {
21         warn "Usage: $0 {-l | -u | -U<num>} {file | dir}...
22
23 Update slapd source code to wrap LDAP operation calls in the debug
24 macros SLAP_OP() & co.  They compile like the old code by default.
25 Define USE_RS_ASSERT to enable asserts which verify the SlapReply.
26 See servers/slapd/result.c.
27
28 Options:
29   -u, -U<n> Output unidiffs with n lines of context (-u = default for diff).
30   -l        List files which would change. Show remaining cases on stderr.\n";
31         exit(1);
32 }
33
34 #### File/option handling. Skips symlinks, handles filenames =~ /\.[ch]+p*$/i.
35
36 sub ls_R {
37     map { -l $_ ? () : -d _ ? ls_R(<$_/*>) : /\.[ch]+p*$/i ? $_ : () } @_;
38 }
39
40 use constant Mode => shift(@ARGV) || "";
41 use vars qw($ccnt $rcnt);
42 INIT {
43         usage() unless Mode =~ /^-(l|[uU]\d*)$/ && ($ARGV[0]||"") =~ /^[^\-]/;
44         exit(0) unless @ARGV = ls_R(@ARGV); # Expand ARGV, exit if no files
45         $| = 1;
46         $ccnt = $rcnt = 0;
47 }
48
49 sub file_result( $$ ) {
50         my($contents, $changed) = @_;
51         $ccnt++ if $changed;
52         $rcnt += scalar( my @rest = remaining($contents) );
53         if (Mode eq "-l") {
54                 print "$ARGV\n" if $changed;
55                 print STDERR "$ARGV:\t$_\n" foreach @rest;
56         } elsif ($changed) {
57                 (my $file = "$ARGV") =~ s%^-%./-%;
58                 print "Index: $file\n";
59                 (open(D, "|-", "diff", Mode, $file, "-")
60                  && (print D $contents)
61                  && (close(D) || $! == 0)) or die "$0: diff failed: $!\n";
62         }
63 }
64
65 END {
66         print STDERR <<EOMSG if defined $ccnt;
67 $ccnt files to change. $rcnt suspicious lines remain. (Expect three in slapd).
68 EOMSG
69 }
70
71 #### Edit the contents of a file
72
73 use vars qw($obj_re %addr %func2op $func_re $todo_re);
74 INIT {
75         $obj_re  = qr/(?:\w+ (?:\s* (?:->|\.) \s* \w+)*?)/x;
76         %addr    = ("." => "&", "->" => ""); # x.y => (&x)->y, x->y => x->y
77         %func2op = map { /(\w+) \s+ (?= .*?=>\s* (\w+))/gx } <DATA>;
78         $func_re = '\b(?=b[ei]_)(?:' . join("|", keys %func2op) . ')\b';
79         my %both = (%func2op, reverse %func2op);
80         $todo_re = '\b(?=[bo][eip]_)(?:' . join("|", keys %both) . ')\b';
81 }
82 next if !/$todo_re/;
83 my $orig = "$_";
84
85 # x->func(op, rs)  ==>  slap_bi_op( x, <enum op_func>, op, rs)
86 # x. func(op, rs)  ==>  slap_bi_op(&x, <enum op_func>, op, rs)
87 s%(                                 # 1: entire match: "<delim><function>("
88         ((?: [\)!=\;{}\\] | \*/ | \b if\s*\( | \b return \b ) \s*) # 2: delim
89         (\(\s* (?:\* \s*)?)?        # 3: optional "(*" or "(" in (*f)()
90         ($obj_re) \s* (->|\.)  \s*  # 4: object,          5: "->" or "."
91         (?=(b[ie]_))($func_re) \s*  # 6: "bi_" or "be_",  7: function
92         (\)\s*)?                    # 8: optional ")" in (*f),
93     (\(\s*)                     # 9: "(" + whitespace
94 )% (!$3) == (!$8) ? "$2slap_$6op$9$addr{$5}$4, $func2op{$7}, " : $1 %egox;
95
96 # (&x->bi_op_bind)[which](op, rs)  ==>  slap_bi_op(x, which, op, rs)
97 #    (&x->be_bind)[which](op, rs)  ==>  slap_be_op(x, which, op, rs)
98 s/\(&(\w+(?:(?:->|\.)\w+)*)->b(?=([ei]))(?:e|i_op)_bind\)\[\s* (\w+) \s*\] \((\s*) ([^()]*)\)
99  /slap_b$2_op($4$1, $3, $5)/gox;
100
101 # slap_bi_op(x->bd_info, which, op, rs)  ==>  slap_be_op( x, which, op, rs)
102 # slap_bi_op(x. bd_info, which, op, rs)  ==>  slap_be_op(&x, which, op, rs)
103 s/\b slap_bi_op (\(\s*) ($obj_re) \s* (->|\.) \s* bd_info \s*,
104  /slap_be_op$1$addr{$3}$2,/gox;
105
106 # slap_be_op(op->o_bd, which, &op, rs)   ==>  SLAP_OP(which,  op, rs)
107 # slap_be_op(op. o_bd, which, &op, rs)   ==>  SLAP_OP(which, &op, rs)
108 s/\b(slap_be_op (\(\s*) ($obj_re) \s*(->|\.)\s* o_bd, \s (\w+, \s (&?)\3,))
109  / $addr{$4} eq $6 ? "SLAP_OP$2$5" : die "$ARGV: Bad syntax: $1\n" /egox;
110
111 my $changed = $_ ne $orig;
112
113 # When changing a file, do some whitespace cleanup too
114 if ($changed) {
115         s/\b ((SLAP_OP|slap_b[ei](func)?_op) \b .*?) [\ \t]+$ /$1/gmx;
116         s/\A\s*\n//;
117         s/\s*\z/\n/;
118 }
119
120 file_result($_, $changed);
121
122 ####
123
124 # Return remaining lines that contain operation method names
125 sub remaining {
126         my($contents) = @_;
127         return $contents !~ /$func_re/o ? () : grep {
128                 !/^\# [ \t]* define \s+ ($func_re|slap_bi_op\b) /x &&
129                 # Skip "if ( (&bi->bi_op_bind)[ which ] )" and variants
130                 !/^(\} \s* else \s*)? if \s* \( \s*
131                         \(& (\w+ | \(\s*\w+\s*=\s*$obj_re\s*\)) -> bi_op_bind\)
132                         \s* \[ \s* \w+ \s* \]
133                         \s* [&|\)]/ox;
134         } $contents =~ m% ^[\ \t]* (?=\S) (
135                 # The line contains a member opfunction
136                 .*? (?:->|\.) \s* $func_re
137
138                 # Skip if the member function is assigned, compared,
139                 # 'and/or'ed, followed by a word (this is a comment), or by
140                 # ') {' or ') word' (function is the boolean in an if/while).
141                 (?! \s* (?: [!=&|\w] | \)\s*[\{\w] ))
142
143                 .*?
144         ) \s*?$ %gmox;
145 }
146
147 # %func2op: Member functions => slap_operation_t
148 __DATA__
149 be_bind             bi_op_bind          => op_bind
150 be_unbind           bi_op_unbind        => op_unbind
151 be_search           bi_op_search        => op_search
152 be_compare          bi_op_compare       => op_compare
153 be_modify           bi_op_modify        => op_modify
154 be_modrdn           bi_op_modrdn        => op_modrdn
155 be_add              bi_op_add           => op_add
156 be_delete           bi_op_delete        => op_delete
157 be_abandon          bi_op_abandon       => op_abandon
158 be_extended         bi_extended         => op_extended
159 be_cancel           bi_op_cancel        => op_cancel
160 be_operational      bi_operational      => op_aux_operational
161 be_chk_referrals    bi_chk_referrals    => op_aux_chk_referrals
162 be_chk_controls     bi_chk_controls     => op_aux_chk_controls