Application_2.m


max21 Unternehmensgruppe
#import "Aprica.h"
//	Aprica2
//	copyright Pirmin Braun 1997-2009 - pirmin@pirmin.de
//	all Rights reserved;
@implementation Application (Scripting2)
- (NSArray *)analyzeScriptNamed:(NSString *)s statements:(NSArray *)statements showErrors:(BOOL)showErrors;
{ 
// liefert ein Array von PBStatements;
    LMA;
    int errorCount = 0,i,j,i1,j1,i2,j2;
    LMDN(nc); // namechecking; variableName->table
    NSArray *nckeys;
    int nest;
    NSString *subname;
    if(showErrors)LOG(([NSSWF @"########### analyzing Script named %@ ",s]));
    for(i=0,j=[statements count];i<j;i++){
        NSString *line = [statements oai:i];
        PBStatement *stmt;
        
// preprocessor Anweisungen verarbeiten
        stmt = [PBStatement statementFromLine:line];
        if(stmt){
            [stmt setSrclnr:i];
            // drin lassen f. Fehlerlisting if([stmt opcode]==OPC_NOP)continue;
            [lma addObject:stmt];
            if([[stmt line]hasSecurePrefix:@"#eo "]){
                [nc setSecureObject:[MYDD tableNamedCheap:[[stmt op2]content]] forKey:[[stmt op1]content]];
            }
            if(FILLED([stmt error]))errorCount++;
            // -------------------- Nachbearbeitung multiline array --------------------------
            if([stmt opcode]==OPC_Z_ml){
                LMAN(mla);
                i++;
                while(i<j){
                    NSString *s1 = [statements oai:i];
                    if([s1 iE:@"\\end"]){
                        break;
                    }
                    [mla addObject:s1];
                    i++;
                }
                [stmt setOpcode:OPC_Z_set];
                [[stmt operands]removeAllObjects];
                [[stmt operands]addObject:[PBOperand operandWithConstantObject:mla]];
                continue;
            }
            // -------------------- Nachbearbeitung Lookup --------------------------
            if([stmt opcode]==OPC_lookupbegin){  // das dictionary aufbauen und in op2 stellen
                NSMutableDictionary *lud;
                NSArray *colKeys=nil;
                NSString *fs = @"\t";
                int ckc = 0,ii,jj;
                lud = [NSMutableDictionary dictionaryWithCapacity:10];
                while(++i<j){
                    NSArray *a1,*a2;
                    NSMutableDictionary *rowDict;
                    NSString *s = [statements oai:i];
                    NSString *slc = [s lowercaseString];
                    if(!FILLED(s))continue; //Kommentarzeilen sind schon rausgefiltert
                    if([slc hasSecurePrefix:@"lookupend"])break;
                    if([slc hasSecurePrefix:@"lookupfs "]){ //custom fieldseparator
                        NSString *s1 = [s substringFromIndex:9];
                        if(FILLED(s1))fs = s1;
                        continue;
                    }
                    if(!colKeys){
                        colKeys = [s componentsSeparatedByString:fs];
                        ckc = [colKeys count];
                        if(ckc <2){
                            [stmt setError:@" keine Spalten."];
                        }
                        continue;
                    }
                    a1 = [s componentsSeparatedByString:fs];
                    if([a1 count] < 2)continue; //Keine Zeilenwerte
                    a2 = [[a1 firstObject] componentsSeparatedByString:@","]; //schluesseliste; wenn nur ein schluessel auch ok
                    rowDict = [NSMutableDictionary dictionaryWithCapacity:10];
                    for(ii=1,jj=[a1 count];ii<jj && ii<ckc;ii++){ //anzahl colkeys kann unterschiedlich sein wie anzahl der zeilenwerte
                        [rowDict setSecureObject:[a1 oai:ii] forKey:[colKeys oai:ii]];
                    }
                    for(ii=0,jj=[a2 count];ii<jj;ii++){
                        NSString *rowKey = [a2 oai:ii];
                        [lud setSecureObject:rowDict forKey:rowKey];
                    }
                }
                [stmt setOpcode:OPC_Z_set];
                [stmt setTarget:[[stmt operands]firstObject]];
                [stmt setTarget_ds:TGT_ds_vardict];	// intern
                [[stmt operands]removeAllObjects];
                [[stmt operands]addObject:[PBOperand operandWithConstantObject:lud]];
                continue;
            }
            // -------------------- Nachbearbeitung Matrix --------------------------
            if([stmt opcode]==OPC_matrixbegin){  // das Array aufbauen und in op2 stellen
                NSMutableArray *matrix;
                NSString *fs = @"\t";
                matrix = [NSMutableArray arrayWithCapacity:10];
                while(++i<j){
                    NSArray *a1;
                    NSString *s = [statements oai:i];
                    NSString *slc = [s lowercaseString];
                    if(!FILLED(s))continue; //Kommentarzeilen sind schon rausgefiltert
                    if([slc hasSecurePrefix:@"matrixend"])break;
                    if([slc hasSecurePrefix:@"lookupfs "]){ //custom fieldseparator
                        NSString *s1 = [s substringFromIndex:9];
                        if(FILLED(s1))fs = s1;
                        continue;
                    }
                    a1 = [s componentsSeparatedByString:fs];
                    [matrix addObject:a1];
                }
                [stmt setOpcode:OPC_Z_set];
                [stmt setTarget:[[stmt operands]firstObject]];
                [stmt setTarget_ds:TGT_ds_vardict];	// intern
                [[stmt operands]removeAllObjects];
                [[stmt operands]addObject:[PBOperand operandWithConstantObject:matrix]];
                continue;
            }
        }
    }
// namechecking
    nckeys = [nc allKeys];
    j1 = [nckeys count];
    for(i=0,j=[lma count];i<j;i++){
        PBStatement *stmt = [lma oai:i];
        enum OPC opcode = [stmt opcode];
        if(FILLED([stmt error]))continue; // hat schon einen Error
        if(opcode == OPC_NOP)continue; // das #eo statement selbst
        if(j1){  // ueberhaupt namechecking statements definiert
            NSString *tf = [stmt targetFull];
            NSArray *ops = [stmt operands];
            NSString *key1;
            if(tf){  // target pruefen von Zuweisungsbefehlen
                for(i1=0;i1<j1;i1++){
                    NSString *nck = [nckeys oai:i1];
                    if([tf hasSecurePrefix:nck]){
                        key1 = [[tf componentsSeparatedByString:@"."]oai:1];
                        if([key1 rangeOfString:@"$"].length)continue; // variable keys koennen hier nicht geprueft werden
                        if(![[nc ofk:nck]plainAttrNamed:key1]){
                            [stmt setError:[NSSWF @"Namechecking: %@ %@",[[nc ofk:nck] dbName],key1]];
                            errorCount++;
                        }
                    }
                }
            }
            
// Operanden pruefen
            for(i2=0,j2=[ops count];i2<j2;i2++){
                NSString *opc = [(PBOperand *)[ops oai:i2]content]; // z.B. ($as.f1 + $as.rx.fy)
                if(![opc isKindOfClass:[NSString class]])continue; // Matrix u. Lookup haben Dictionaries als Operanden drin
                for(i1=0;i1<j1;i1++){
                    NSString *nck = [nckeys oai:i1];  // $as.
                    NSRange r = [opc rangeOfString:nck];
                    while(r.length){
                        int e=0;
                        opc = [opc secureSubstringFromIndex:r.location + r.length];
                        r = [opc rangeOfString:@"."];
                        if(r.length)e=r.location;
                        r = [opc rangeOfString:@" "];
                        if(r.length && (!e || (r.location < e)))e=r.location;
                        r = [opc rangeOfString:@")"];
                        if(r.length && (!e || (r.location < e)))e=r.location;
                        if(e){
                            key1 = [opc substringToIndex:e];
                        }else{
                            key1 = opc;
                        }
                        if(!([key1 rangeOfString:@"$"].length)){ // variable keys koennen hier nicht geprueft werden
                            if(![[PBEO knownKeys]ofk:key1]){
                                if(![[nc ofk:nck]plainAttrNamed:key1]){
                                    [stmt setError:[NSSWF @"Namechecking: %@ %@",[[nc ofk:nck] dbName],key1]];
                                    errorCount++;
                                }
                            }
                        }
                        r = [opc rangeOfString:nck];
                    }
                }
            }
            if(FILLED([stmt error]))continue; // hat schon einen Error
        }
// jetzt noch verpointerung vornehmen; dabei koennen fehler dazukommen;
        nest = 0;
        [stmt setBranch:-1];
        switch(opcode){
            case OPC_gosub:       // subroutinename constant;
                subname = [[stmt op1]content];
                i2=0;
                for(;i2<j;i2++){
                    PBStatement *stmt_sub = [lma oai:i2];
                    int opc = [stmt_sub opcode];
                    if(opc==OPC_sub && [[[stmt_sub op1]content]iE:subname]){ [stmt setBranch:i2]; break;}
                }
                break;
            case OPC_sub:
                i2=i+1;
                for(;i2<j;i2++){
                    int opc = [[lma oai:i2] opcode];
                    if(opc==OPC_endsub){
                        if(!nest){ [stmt setBranch:i2]; break;}
                        nest--;
                    }
                    if(opc==OPC_sub)nest++;
                }
                break;
            case OPC_foreach:
                i2=i+1;
                for(;i2<j;i2++){
                    int opc = [[lma oai:i2] opcode];
                    if(opc==OPC_endfor){
                        if(!nest){ [stmt setBranch:i2]; break;}
                        nest--;
                    }
                    if(opc==OPC_foreach)nest++;
                }
                break;
            case OPC_continuefor:
                i2=i-1;
                for(;i2>=0;i2--){
                    int opc = [[lma oai:i2] opcode];
                    if(opc==OPC_foreach){
                        if(!nest){ [stmt setBranch:i2]; break;};
                        nest--;
                    }
                    if(opc==OPC_endfor)nest++;
                }
                break;
            case OPC_breakfor:
                i2=i+1;
                for(;i2<j;i2++){
                    int opc = [[lma oai:i2] opcode];
                    if(opc==OPC_endfor){
                        if(!nest){ [stmt setBranch:i2]; break;}
                        nest--;
                    }
                    if(opc==OPC_foreach)nest++;
                }
                break;
            case OPC_endfor:
                i2=i-1;
                for(;i2>=0;i2--){
                    int opc = [[lma oai:i2] opcode];
                    if(opc==OPC_foreach){
                        if(!nest){ [stmt setBranch:i2]; break;};
                        nest--;
                    }
                    if(opc==OPC_endfor)nest++;
                }
                break;
            case OPC_if:
                i2=i+1;
                for(;i2<j;i2++){
                    int opc = [[lma oai:i2] opcode];
                    if((opc==OPC_else || opc==OPC_endif) && !nest){ [stmt setBranch:i2]; break;}
                    if(opc==OPC_endif)nest--;
                    if(opc==OPC_if)nest++;
                }
                break;
            case OPC_else:
                i2=i+1;
                for(;i2<j;i2++){
                    int opc = [[lma oai:i2] opcode];
                    if(opc==OPC_endif){
                        if(!nest){ [stmt setBranch:i2]; break;}
                        nest--;
                    }
                    if(opc==OPC_if)nest++;
                }
                break;
            case OPC_while:
                i2=i+1;
                for(;i2<j;i2++){
                    int opc = [[lma oai:i2] opcode];
                    if(opc==OPC_endwhile){
                        if(!nest){ [stmt setBranch:i2]; break;}
                        nest--;
                    }
                    if(opc==OPC_while)nest++;
                }
                break;
            case OPC_continue:
                i2=i-1;
                for(;i2>=0;i2--){
                    int opc = [[lma oai:i2] opcode];
                    if(opc==OPC_while){
                        if(!nest){ [stmt setBranch:i2]; break;};
                        nest--;
                    }
                    if(opc==OPC_endwhile)nest++;
                }
                break;
            case OPC_break:
                i2=i+1;
                for(;i2<j;i2++){
                    int opc = [[lma oai:i2] opcode];
                    if(opc==OPC_endwhile){
                        if(!nest){ [stmt setBranch:i2]; break;}
                        nest--;
                    }
                    if(opc==OPC_while)nest++;
                }
                break;
            case OPC_endwhile:
                i2=i-1;
                for(;i2>=0;i2--){
                    int opc = [[lma oai:i2] opcode];
                    if(opc==OPC_while){
                        if(!nest){ [stmt setBranch:i2]; break;};
                        nest--;
                    }
                    if(opc==OPC_endwhile)nest++;
                }
                break;
            default:
                [stmt setBranch:0];  // kein branch-Statement
                break;
        }
        if([stmt branch]<0){
            [stmt setError:@"nesting Error"];
            errorCount++;
        }
    }
    if(errorCount){
        LMAN(listing);
        NSString *sys,*err_summary;
        int i,j;
        err_summary = [NSSWF @"======== %@",s];
        if(!showErrors){
            LOG((err_summary));
            [scriptErrors addObject:[NSSWF @"<a  href=\"#\" onClick=\"{document.forms[0].script_clicked.value='%@'; document.forms[0].submitter.value='action_script_bu_open_script'; document.forms[0].submit();}\">======== %@</a>",s,s]];
        }
        for(i=0,j=[lma count];i<j;i++){
            PBStatement *stmt = [lma oai:i];
            if(showErrors){
                if([stmt error]){
                    [listing addObject:[NSSWF @"%@ *** %@",[stmt line],[stmt error]]];
                }else{
                    [listing addObject:[stmt line]];
                }
            }else{
                if([stmt error]){
                    LOG([stmt description]);
                    [scriptErrors addObject:[stmt htmlDescription]];
                }
            }
        }
        if(showErrors){
            NSString *fn = [NSSWF @"%@/%@.script",[_APP tempdir],[s replace:@"/" with:@"_"]];
            // erzeugtes Listing oeffnen
            [[listing componentsJoinedByString:@"\n"]WTF:fn];
            sys = [NSSWF @"open \"%@\"",fn];
            SYSTEM(sys);
        }
    }else{
        if(showErrors)LOGI(([NSSWF @"Script %@ fehlerfrei",s]));
    }
    return lma;
}
- (void)analyzeScriptsIn:(NSDictionary *)d into:(NSMutableDictionary *)into;
{
// alle Scripts analysieren
    NSArray *ks = [d allKeys];
    int i,j;
    LOG(@"########### analyzing Scripts.");
    for(i=0,j=[ks count];i<j;i++){
        NSString *k = [ks oai:i];
        NSArray *statements = [scriptDict ofk:k],*a;
        a = [self analyzeScriptNamed:k statements:statements showErrors:NO];
        [into setObject:a forKey:k];
    }
    LOG(@"########### finished analyzing Scripts.");
}
@end
Foto