⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 perlhack.pod

📁 视频监控网络部分的协议ddns,的模块的实现代码,请大家大胆指正.
💻 POD
📖 第 1 页 / 共 5 页
字号:
Arguments are passed to PP code and returned from PP code using theargument stack, C<ST>. The typical way to handle arguments is to popthem off the stack, deal with them how you wish, and then push the resultback onto the stack. This is how, for instance, the cosine operatorworks:      NV value;      value = POPn;      value = Perl_cos(value);      XPUSHn(value);We'll see a more tricky example of this when we consider Perl's macrosbelow. C<POPn> gives you the NV (floating point value) of the top SV onthe stack: the C<$x> in C<cos($x)>. Then we compute the cosine, and pushthe result back as an NV. The C<X> in C<XPUSHn> means that the stackshould be extended if necessary - it can't be necessary here, because weknow there's room for one more item on the stack, since we've justremoved one! The C<XPUSH*> macros at least guarantee safety.Alternatively, you can fiddle with the stack directly: C<SP> gives youthe first element in your portion of the stack, and C<TOP*> gives youthe top SV/IV/NV/etc. on the stack. So, for instance, to do unarynegation of an integer:     SETi(-TOPi);Just set the integer value of the top stack entry to its negation.Argument stack manipulation in the core is exactly the same as it is inXSUBs - see L<perlxstut>, L<perlxs> and L<perlguts> for a longerdescription of the macros used in stack manipulation.=item Mark stackI say "your portion of the stack" above because PP code doesn'tnecessarily get the whole stack to itself: if your function callsanother function, you'll only want to expose the arguments aimed for thecalled function, and not (necessarily) let it get at your own data. Theway we do this is to have a "virtual" bottom-of-stack, exposed to eachfunction. The mark stack keeps bookmarks to locations in the argumentstack usable by each function. For instance, when dealing with a tiedvariable, (internally, something with "P" magic) Perl has to callmethods for accesses to the tied variables. However, we need to separatethe arguments exposed to the method to the argument exposed to theoriginal function - the store or fetch or whatever it may be. Here'sroughly how the tied C<push> is implemented; see C<av_push> in F<av.c>:     1	PUSHMARK(SP);     2	EXTEND(SP,2);     3	PUSHs(SvTIED_obj((SV*)av, mg));     4	PUSHs(val);     5	PUTBACK;     6	ENTER;     7	call_method("PUSH", G_SCALAR|G_DISCARD);     8	LEAVE;Let's examine the whole implementation, for practice:     1	PUSHMARK(SP);Push the current state of the stack pointer onto the mark stack. This isso that when we've finished adding items to the argument stack, Perlknows how many things we've added recently.     2	EXTEND(SP,2);     3	PUSHs(SvTIED_obj((SV*)av, mg));     4	PUSHs(val);We're going to add two more items onto the argument stack: when you havea tied array, the C<PUSH> subroutine receives the object and the valueto be pushed, and that's exactly what we have here - the tied object,retrieved with C<SvTIED_obj>, and the value, the SV C<val>.     5	PUTBACK;Next we tell Perl to update the global stack pointer from our internalvariable: C<dSP> only gave us a local copy, not a reference to the global.     6	ENTER;     7	call_method("PUSH", G_SCALAR|G_DISCARD);     8	LEAVE;C<ENTER> and C<LEAVE> localise a block of code - they make sure that allvariables are tidied up, everything that has been localised getsits previous value returned, and so on. Think of them as the C<{> andC<}> of a Perl block.To actually do the magic method call, we have to call a subroutine inPerl space: C<call_method> takes care of that, and it's described inL<perlcall>. We call the C<PUSH> method in scalar context, and we'regoing to discard its return value.  The call_method() functionremoves the top element of the mark stack, so there is nothing forthe caller to clean up.=item Save stackC doesn't have a concept of local scope, so perl provides one. We'veseen that C<ENTER> and C<LEAVE> are used as scoping braces; the savestack implements the C equivalent of, for example:    {        local $foo = 42;        ...    }See L<perlguts/Localising Changes> for how to use the save stack.=back=head2 Millions of MacrosOne thing you'll notice about the Perl source is that it's full ofmacros. Some have called the pervasive use of macros the hardest thingto understand, others find it adds to clarity. Let's take an example,the code which implements the addition operator:   1  PP(pp_add)   2  {   3      dSP; dATARGET; tryAMAGICbin(add,opASSIGN);   4      {   5        dPOPTOPnnrl_ul;   6        SETn( left + right );   7        RETURN;   8      }   9  }Every line here (apart from the braces, of course) contains a macro. Thefirst line sets up the function declaration as Perl expects for PP code;line 3 sets up variable declarations for the argument stack and thetarget, the return value of the operation. Finally, it tries to see ifthe addition operation is overloaded; if so, the appropriate subroutineis called.Line 5 is another variable declaration - all variable declarations startwith C<d> - which pops from the top of the argument stack two NVs (henceC<nn>) and puts them into the variables C<right> and C<left>, hence theC<rl>. These are the two operands to the addition operator. Next, wecall C<SETn> to set the NV of the return value to the result of addingthe two values. This done, we return - the C<RETURN> macro makes surethat our return value is properly handled, and we pass the next operatorto run back to the main run loop.Most of these macros are explained in L<perlapi>, and some of the moreimportant ones are explained in L<perlxs> as well. Pay special attentionto L<perlguts/Background and PERL_IMPLICIT_CONTEXT> for information onthe C<[pad]THX_?> macros.=head2 The .i TargetsYou can expand the macros in a F<foo.c> file by saying    make foo.iwhich will expand the macros using cpp.  Don't be scared by the results.=head1 SOURCE CODE STATIC ANALYSISVarious tools exist for analysing C source code B<statically>, asopposed to B<dynamically>, that is, without executing the code.It is possible to detect resource leaks, undefined behaviour, typemismatches, portability problems, code paths that would cause illegalmemory accesses, and other similar problems by just parsing the C codeand looking at the resulting graph, what does it tell about theexecution and data flows.  As a matter of fact, this is exactlyhow C compilers know to give warnings about dubious code.=head2 lint, splintThe good old C code quality inspector, C<lint>, is available inseveral platforms, but please be aware that there are severaldifferent implementations of it by different vendors, which means thatthe flags are not identical across different platforms.There is a lint variant called C<splint> (Secure Programming Lint)available from http://www.splint.org/ that should compile on anyUnix-like platform.There are C<lint> and <splint> targets in Makefile, but you may haveto diddle with the flags (see above).=head2 CoverityCoverity (http://www.coverity.com/) is a product similar to lint andas a testbed for their product they periodically check several opensource projects, and they give out accounts to open source developersto the defect databases.=head2 cpd (cut-and-paste detector)The cpd tool detects cut-and-paste coding.  If one instance of thecut-and-pasted code changes, all the other spots should probably bechanged, too.  Therefore such code should probably be turned into asubroutine or a macro.cpd (http://pmd.sourceforge.net/cpd.html) is part of the pmd project(http://pmd.sourceforge.net/).  pmd was originally written for staticanalysis of Java code, but later the cpd part of it was extended toparse also C and C++.Download the pmd-bin-X.Y.zip () from the SourceForge site, extract thepmd-X.Y.jar from it, and then run that on source code thusly:  java -cp pmd-X.Y.jar net.sourceforge.pmd.cpd.CPD --minimum-tokens 100 --files /some/where/src --language c > cpd.txtYou may run into memory limits, in which case you should use the -Xmx option:  java -Xmx512M ...=head2 gcc warningsThough much can be written about the inconsistency and coverageproblems of gcc warnings (like C<-Wall> not meaning "all thewarnings", or some common portability problems not being covered byC<-Wall>, or C<-ansi> and C<-pedantic> both being a poorly definedcollection of warnings, and so forth), gcc is still a useful tool inkeeping our coding nose clean.The C<-Wall> is by default on.The C<-ansi> (and its sidekick, C<-pedantic>) would be nice to be onalways, but unfortunately they are not safe on all platforms, they canfor example cause fatal conflicts with the system headers (Solarisbeing a prime example).  If Configure C<-Dgccansipedantic> is used,the C<cflags> frontend selects C<-ansi -pedantic> for the platformswhere they are known to be safe.Starting from Perl 5.9.4 the following extra flags are added:=over 4=item *C<-Wendif-labels>=item *C<-Wextra>=item *C<-Wdeclaration-after-statement>=backThe following flags would be nice to have but they would first needtheir own Augean stablemaster:=over 4=item *C<-Wpointer-arith>=item *C<-Wshadow>=item *C<-Wstrict-prototypes>=backThe C<-Wtraditional> is another example of the annoying tendency ofgcc to bundle a lot of warnings under one switch -- it would beimpossible to deploy in practice because it would complain a lot -- butit does contain some warnings that would be beneficial to have availableon their own, such as the warning about string constants inside macroscontaining the macro arguments: this behaved differently pre-ANSIthan it does in ANSI, and some C compilers are still in transition,AIX being an example.=head2 Warnings of other C compilersOther C compilers (yes, there B<are> other C compilers than gcc) oftenhave their "strict ANSI" or "strict ANSI with some portability extensions"modes on, like for example the Sun Workshop has its C<-Xa> mode on(though implicitly), or the DEC (these days, HP...) has its C<-std1>mode on.=head2 DEBUGGINGYou can compile a special debugging version of Perl, which allows youto use the C<-D> option of Perl to tell more about what Perl is doing.But sometimes there is no alternative than to dive in with a debugger,either to see the stack trace of a core dump (very useful in a bugreport), or trying to figure out what went wrong before the core dumphappened, or how did we end up having wrong or unexpected results.=head2 Poking at PerlTo really poke around with Perl, you'll probably want to build Perl fordebugging, like this:    ./Configure -d -D optimize=-g    makeC<-g> is a flag to the C compiler to have it produce debugginginformation which will allow us to step through a running program,and to see in which C function we are at (without the debugginginformation we might see only the numerical addresses of the functions,which is not very helpful).F<Configure> will also turn on the C<DEBUGGING> compilation symbol whichenables all the internal debugging code in Perl. There are a whole bunchof things you can debug with this: L<perlrun> lists them all, and thebest way to find out about them is to play about with them. The mostuseful options are probably    l  Context (loop) stack processing    t  Trace execution    o  Method and overloading resolution    c  String/numeric conversionsSome of the functionality of the debugging code can be achieved using XSmodules.    -Dr => use re 'debug'    -Dx => use O 'Debug'=head2 Using a source-level debuggerIf the debugging output of C<-D> doesn't help you, it's time to stepthrough perl's execution wit

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -