Using Apple shell script to edit Juce generated property file possible?


#1

Hi jules,

 

This has been my headache for a while and see if I can get some tips in this forum.

My software has this property file/xml file generated using juce's property file class.

The format is simple (say the file is called test.xml):


<?xml version="1.0" encoding="UTF-8"?>
<PROPERTIES>
  <VALUE name="Location" val="/Users/Shared/whateverpath"/>
</PROPERTIES>

 

My goal is to write a shell script on Mac that can read and edit this XML node. As you might have figured out, this shell script will be embeded and used in my software's update installer (I am using Apple's Packagemaker). 

I have tried xpath tool

 xpath test.xml /PROPERTIES 

but it can only print the whole <VALUE name="Location" val="/Users/Shared/whateverpath"/> as a node.

 

Is there a not-so-complicated way to edit this value with Apple shell script? I have to say making a Mac installer is way more difficult than making a Windows one.

thanks.

 


#2

Hi!

I'm doing similar operation in a batch building several variation of CopperLan SDK. I'm using the shell awk command (http://www.grymoire.com/unix/Awk.html)

This command is very powerful and can execute complex tasks. In my case, I've included some special #ifdef .. #endif sections in the original set of header files, and awk is used to remove some of them and make some changes during the copy.

You should be able to get your expected behavior by changing parts of the script hereafter to find some XML tags and replace them by something else.

Here is an example of awk call, keeping CHAI_NORMAL #ifdefs and removing the others.

awk -f ./MakeHeaders.awk -v sourceFiles="$sourceFiles" -v sourcePath="$sourcePath" -v destinationFiles="$sourceFiles" -v destinationPath="$destinationPathSDK" -v inc="CHAI_NORMAL" -v exc="CHAI_FREEWARE CHAI_ACADEMIC CHAI_INTERNAL"

And here is the content of MakeHeaders.awk

BEGIN {
    #print "Source files: " sourceFiles;
    #print "Source path: " sourcePath;
    #print "Destination files: " destinationFiles;
    #print "Destination path: " destinationPath;
    #print "Inc: " inc;
    #print "Exc: " exc;
    // Build SDK files
    split( sourceFiles, arSourceFiles );
    split( destinationFiles, arDestinationFiles );
    for ( i in arSourceFiles ) {
        inFile = sprintf( "%s%s", sourcePath, arSourceFiles[i] );
        outFile = sprintf( "%s%s", destinationPath, arDestinationFiles[i] );
        command = sprintf( "awk -f CleanHeader.awk -v inc=\"%s\" -v exc=\"%s\" %s > %s", inc, exc, inFile, outFile );
        print command
        system( command );
    }
    exit;
}

And finally, the most important script CleanHeader.awk. It is processing an input file and genererating an output file removing some #ifdef..#endif blocks. The first part is testing if the line should be kept (fInclude) depending on the current state (area). The end of the script is copying the original line to the output file if needed, modifying a specific include path by removing the CPGeneral/Common part. Similar operation could be done to identify XML tags and replace value content. 

BEGIN {
    area = 0;
    # 0: normal
    # 1: include
    # 2: exclude
    #DEBUG PURPOSE
    #print "Includes: " inc;
    #print "Excludes: " exc;
    #print "File: " FILENAME;
    #exit
}
{
    sub(/\r$/,""); #remove trailing CRLF
    fInclude = 1;
    if ( area == 2 )
        fInclude = 0;
    if ( $1 ~ /^#ifdef/ ) {
        if ( inc ~ $2 ) {
            fInclude = 0;
            area = 1;
        }
        else if ( exc ~ $2 ) {
            fInclude = 0;
            area = 2;
        }
    }
    else if ( $1 ~ /^#endif/ && area != 0 ) {
        fInclude = 0;
        area = 0;
    }
    if ( fInclude ) {
        if ( $0 ~ /^#include "CPGeneral\/Common\/CPTypes/ ) {
            print "#include \"CPTypes" substr( $0, 35 );
        }
        else {
            print;
        }
    }
}
END {
}