Programming

Install (and download) your approved or downloaded WSUS updates – VBScript

Still need to add in email notification and test it headless (not logged in).. however, to solve a problem earlier today.. this will install updates that are approved (and/or already downloaded) from WSUS on our schedule. It’ll also reboot, so we can stagger systems to automatically do this on your schedule, not Microsoft’s.

 

' Automatically install approved updates from WSUS and reboot

' *** check
Set objUpdateSession = CreateObject("Microsoft.Update.Session")
Set objUpdateSearch = objUpdateSession.CreateupdateSearcher()
objUpdateSearch.ServerSelection = 0 'use system default
Set objUpdateSearchResult = objUpdateSearch.Search("IsInstalled=0 and Type='Software'")
For I = 0 To objUpdateSearchResult.Updates.Count-1
Set objUpdate = objUpdateSearchResult.Updates.Item(I)
'WScript.Echo I + 1 & "> " & objUpdate.Title
Next
If objUpdateSearchResult.Updates.Count = 0 Then WScript.Quit 'wscript.echo "no updates"
' *** download
Set objUpdatesDownload = CreateObject("Microsoft.Update.UpdateColl")
For I = 0 to objUpdateSearchResult.Updates.Count-1
Set objUpdate = objUpdateSearchResult.Updates.Item(I)
boolAddThisUpdate = false
If Not objUpdate.InstallationBehavior.CanRequestUserInput = true Then
If objUpdate.EulaAccepted = false Then
objUpdate.AcceptEula()
boolAddThisUpdate = true
Else
boolAddThisUpdate = true
end if
End If
If boolAddThisUpdate = true Then objUpdatesDownload.Add(objUpdate)
Next
If objUpdatesDownload.Count = 0 Then WScript.Quit
Set objUpdateDownloader = objUpdateSession.CreateUpdateDownloader()
objUpdateDownloader.Updates = objUpdatesDownload
objUpdateDownloader.Download()
' *** install
Set objUpdatesInstall = CreateObject("Microsoft.Update.UpdateColl")
For I = 0 To objUpdateSearchResult.Updates.Count-1
set objUpdate = objUpdateSearchResult.Updates.Item(I)
'    WScript.Echo I + 1 & "> " & objUpdate.Title
If objUpdate.IsDownloaded = true Then objUpdatesInstall.Add(objUpdate)
Next
if objUpdatesInstall.Count = 0 then wscript.quit
Set objUpdateInstaller = objUpdateSession.CreateUpdateInstaller()
objUpdateInstaller.Updates = objUpdatesInstall
Set objInstallationResult = objUpdateInstaller.Install()
' *** restart
Set objShell = CreateObject("WScript.Shell")
objShell.Run "shutdown.exe -r -t 0"
Advertisements
Hacking, Linux, Programming

SMTP Relay Stress Test Script

The problem

So.. I had an issue where I had to stress test a new MTA I was deploying. Generating load so I can tweak the config was key.. here’s a handy way to do it.

Behavior:

27% chance of sending a 37,597 byte message with an attachment
17% chance of sending a 3,075 byte message
16% chance of sending a 7,108 byte message
10% chance of sending a 14,743 byte message
6% chance of sending a 547 byte message
6% chance of sending a 60,969 byte message with an attachment
4% chance of sending a 124,167 byte message with an attachment
3% chance of sending a 85,993 byte message with an attachment
2% chance of sending a 171,358 byte message with an attachment
2% chance of sending a 221,826 byte message with an attachment
1% chance of sending a 274,007 byte message with an attachment
1% chance of sending a 313,479 byte message with an attachment
1% chance of sending a 416,983 byte message with an attachment
1% chance of sending a 550,839 byte message with an attachment
1% chance of sending a 761,659 byte message with an attachment
1% chance of sending a 1,214,991 byte message with an attachment
1% chance of sending a 5,505,014 byte message with an attachment

Generate Test Files:

dd if=/dev/urandom of=4031 bs=1 count=4031
dd if=/dev/urandom of=6281 bs=1 count=6281
dd if=/dev/urandom of=18123 bs=1 count=18123
dd if=/dev/urandom of=230 bs=1 count=230
#attachments
dd if=/dev/urandom of=24987.doc bs=1 count=24987
dd if=/dev/urandom of=80234.doc bs=1 count=80234
dd if=/dev/urandom of=112167.doc bs=1 count=112167
dd if=/dev/urandom of=89941.doc bs=1 count=89941
dd if=/dev/urandom of=149344.doc bs=1 count=149344
dd if=/dev/urandom of=221826.doc bs=1 count=221826
dd if=/dev/urandom of=274007.doc bs=1 count=274007
dd if=/dev/urandom of=313479.doc bs=1 count=313479
dd if=/dev/urandom of=416983.doc bs=1 count=416983
dd if=/dev/urandom of=550839.doc bs=1 count=550839
dd if=/dev/urandom of=761659.doc bs=1 count=761659
dd if=/dev/urandom of=1214991.doc bs=1 count=1214991
dd if=/dev/urandom of=5505014.doc bs=1 count=5505014

The Script to Stress Test your Relay:

#!/bin/ksh

if [ -z “$1” ] ; then
echo “Usage: $0 messagecount”
exit 1
fi

# $Absolute path to mutt (mail agent)
MUTT=/usr/bin/mutt

# destination email addresses
RECIPIENTS=null@null.com

COUNTER=0

while [ “$COUNTER” -lt $1 ]
do
RN=`echo $(( RANDOM % 100 + 1))`
if [ $RN -ge 1 -a $RN -le 27 ] ; then
$MUTT -a 24987.doc — $RECIPIENTS < “.”
elif [ $RN -ge 28 -a $RN -le 44 ] ; then
$MUTT -i 4031 $RECIPIENTS < “.”
elif [ $RN -ge 45 -a $RN -le 60 ] ; then
$MUTT -i 6281 $RECIPIENTS < “.”
elif [ $RN -ge 61 -a $RN -le 70 ] ; then
$MUTT -i 18123 $RECIPIENTS < “.”
elif [ $RN -ge 71 -a $RN -le 76 ] ; then
$MUTT -i 230 $RECIPIENTS < “.”
elif [ $RN -ge 77 -a $RN -le 82 ] ; then
$MUTT -a 80234.doc — $RECIPIENTS < “.”
elif [ $RN -ge 83 -a $RN -le 86 ] ; then
$MUTT -a 112167.doc — $RECIPIENTS < “.”
elif [ $RN -ge 87 -a $RN -le 89 ] ; then
$MUTT -a 89941.doc — $RECIPIENTS < “.”
elif [ $RN -ge 90 -a $RN -le 91 ] ; then
$MUTT -a 149344.doc — $RECIPIENTS < “.”
elif [ $RN -ge 92 -a $RN -le 93 ] ; then
$MUTT -a 221826.doc — $RECIPIENTS < “.”
elif [ $RN -eq 94 ] ; then
$MUTT -a 274007.doc — $RECIPIENTS < “.”
elif [ $RN -eq 95 ] ; then
$MUTT -a 313479.doc — $RECIPIENTS < “.”
elif [ $RN -eq 96 ] ; then
$MUTT -a 416983.doc — $RECIPIENTS < “.”
elif [ $RN -eq 97 ] ; then
$MUTT -a 550839.doc — $RECIPIENTS < “.”
elif [ $RN -eq 98 ] ; then
$MUTT -a 761659.doc — $RECIPIENTS < “.”
elif [ $RN -eq 99 ] ; then
$MUTT -a 1214991.doc — $RECIPIENTS < “.”
elif [ $RN -eq 100 ] ; then
$MUTT -a 5505014.doc — $RECIPIENTS < “.”
fi

# add counter
COUNTER=`expr $COUNTER + 1`

done

C#, Games, Programming

Programming the Space Invaders – C# XNA 4 – Part 1

Introduction

Work in progress

Hey,
So, I started writing Space Invaders with XNA/C#. I will extend this post once I actually finish the game. However, each milestoneI’m going to take the time to document it and write it here. Let me know if I need to flesh anything out. I hope I can help someone as I help myself. The link to download the actual Visual Studio project is at the bottom of this file, but below is the explanation of the code. I will improve it as I go. I’ve wrote a couple of things already, Pong and the majority of Arkanoid – unfortunately part of the collision detection really stumped me. I will return to it, but to take a break from the physics, I decided to start on Space Invaders. Here’s the outcome.

Please remember that I am not an experienced programmer and my way may not be either the best way or the right way. This is my journey and I will update the posts as I hit problems and learn how to do things in a better way, until the post becomes pointless and forgotten at which time I will ‘de-publish’ it. 😉

This first section will be enough to set up the boilerplate required for the game, display your ship, allow you to move it with AD or Cursor LEFT, RIGHT.

Part 1 – Getting the ship on screen and moving it.

a. Create new Windows Game with XNA. Let’s call it Space Invaders. Drag the Ship.png file into your content pipeline and call it what you want. I call it Ship.
b. Create a new class called Ship.cs. This class will be the object that is your ship to fight the space invaders.
c. Before or after creating this class, we need to write the main program.

a. The graphics

The ship

b. Ship.cs – The player’s ship object/class

Include the XNA Framework in the class.
Include the XNA Framework Graphics subsystem in the class.

Create internal variables:

  • Texture2D shipTexture – this will hold the sprite image/picture.
  • Rectangle shipRectangle – this is the rectangle boundary of your sprite/ship (image, really).
  • Rectangle viewportBoundary – this rectangle contains the screen dimensions – the viewport.. the boundary.
  • public float shipVector – This contains the vector/direction/position of your ship. It will only move on one axis – X, or horizontal. Publicly accessible outside of the class.
  • public int shipLives – The number of lives your ship/player has left. Publicly accessible outside of the class.

Create the methods:

  • Publicly accessible class method Ship. This will import into the class the image to load for the ship sprite, and the dimensions of the viewport/boundary at game initialization/load time/run time.  Parameters are two, Texture2D shipTexture, and Rectangle viewportBoundary.
  • Publicly accessible method of type Rectangle called getShipRectangle. This populates the variable containing the rectangle boundary of your sprite/ship (image, really). Parameters are two integers: int shipVectorX, int shipVectorY. — MAY REMOVE THIS METHOD LATER.
  • Private  void called startShip – using this to contain the object initialization sequence. — MAY HAVE VARIOUS STATE LOGIC HERE LATER WHEN IMPLEMENTING DEATH/REBIRTH/NEW LEVELS.
  • Public void called Initialize() – using this to call the initialization sequence from the outside. All this does for now is call startShip();
  • Public void called Draw. This is where the object/ship/sprite is redrawn every frame and essentially is how it ‘moves’ the ship. It accepts a SpriteBatch parameter called mainSpriteBatch. mainSpriteBatch is where I am going to load all my sprites/ships/aliens/projectiles [I think].
  • Public void called Update. This accepts no parameters but essentially handles the change in ship/sprite position. It will update the shipRectangle.X setting (position of the ship’s rectangle/boundary of the ship/sprite/image) to whatever has been set via the public floating point variable (ironically, casting/converting it to an integer) shipVector. — MAY REMOVE THIS TO PREVENT PUBLIC ACCESS TO THE SHIP’S POSITION WITHOUT GOING THROUGH A CLASS METHOD.

c. Game1.cs – The main game object/class

Create class variables:

  • Ship shipPlayer1. Defining that the variable shipPlayer1 will contain an object of the type Ship (our Ship class from earlier).
  • Rectangle viewportBoundary. This contains a rectangle of the screen dimensions, used for viewport boundary.

Create the methods:

  • In the class method, public Game1. Add the definition to create/instantiate the viewportBoundary rectangle to the desired resolution.
  • Within the protected method Initialize, set the graphics viewport object to have a backbuffer width and height of the desired resolution. Remember to call the ApplyChanges() method for the graphics viewport object.
  • Create private method called gameStart() – will use this to initialize the objects and settings back to the start of a game state, or for example a new level. For now, it just calls the shipPlayer1.Initialize() method. (Remember the Initialize method in the Ship class we wrote earlier? It calls that for the instantiated object you defined at the top of this class; shipPlayer1).
  • Update the protected method LoadContent() to load the sprite image for your ship into your object while instantiating it. shipPlayer1 = new Ship(Content.Load<Texture2D>(“Ship”), viewportBoundary); – Remember we set the parameters up for the class method earlier to accept a Texture2D and a Rectangle for both the image and the screen resolution rectangle. Also here we call the gameStart(); method.
  • Within the protected Update() method, I make a call to another method called inputKeyboard(); We also call the shipPlayer1.Update() method [This runs the Update method we wrote for the Ship class above, remember?]
  • Within the protected Draw() method, this is where we start our spriteBatch object, call shipPlayer1.Draw method and pass it the spriteBatch object, then we end the spritebatch object.
  • Create a private void method called inputKeyboard(). In here we just check for if the Escape key is depressed – if so then exit. If the A or Left cursor key is pressed then update the shipPlayer1.shipVector public variable to decrement by 10. — PROBABLY WANT TO CLEAN THIS UP USING A VARIABLE LATER.  We also do the same for D or Right cursor, but increment the shipVector by 10.

When you compile, you should have a ship that moves around.

Download the Visual Studio 2010 project here:

http://www.laststand.eu/SpaceInvaders.rar

Part 1

C#, Programming

C# Syslog class – Logging to a file in your app, syslog style, xna

When working on our game with a friend, we needed a way to track debug data (and general log info). Here’s what I came up with.
Note, there’s no way to set the logging verbosity (level) as yet, but this will come later.

#if WINDOWS
public enum syslogType
{
ERROR = 0,
WARNING = 1,
INFO = 2,
DEBUG = 3
}
public static class Syslog
{
static bool _enabled;
static string _filename;

static String theTimestamp(this DateTime value)
{
return value.ToString(“yyyy-MM-dd-HH:mm:ss”);
}
static public void initialize()
{
_enabled = true;
_filename = “syslog-” + System.DateTime.Now.ToString(“yyyyMMddHHmmss”) + “.txt”;
StreamWriter outputLog = new StreamWriter(new FileStream(_filename, FileMode.Create, FileAccess.Write));
outputLog.WriteLine(theTimestamp(System.DateTime.Now) + ” [INFO] Log Created”);
outputLog.Close();
}

static public bool Enabled
{
get { return _enabled; }
set { _enabled = value; }
}

// this is the public log interface – Improvement for later: Add optional parameter for module/class to show where entry originated
static public void log(syslogType logType, string logText)
{
if (!_enabled) return;
string logStart = “”;
switch (logType)
{
case syslogType.DEBUG: logStart = “[DEBUG]”; break;
case syslogType.ERROR: logStart = “[ERROR]”; break;
case syslogType.INFO: logStart = “[INFO]”; break;
case syslogType.WARNING: logStart = “[WARNING]”; break;
}
logText = theTimestamp(System.DateTime.Now) + ” ” + logStart + ” ” + logText;
writeLog(logText);
}

static private void writeLog(string logText)
{
try
{
StreamWriter outputLog = new StreamWriter(new FileStream(_filename, FileMode.Append, FileAccess.Write));
outputLog.WriteLine(logText);
outputLog.Close();
}
catch (System.Exception e)
{
string errException = e.Message;
}
}
}
#endif

Call the class with using the public methods and with the following syntax/example:

  Syslog.initialize();

Syslog.log(syslogType.INFO,(“Hello there, I am a log entry: ” + variableifyouneedit));

Objective-C

2. Objective-C: Objects, Methods, Classes

  • You own a phone.
  • Your phone is an object.
  • Your phone could be a Nokia, Samsung or Apple, etc.
  • Your phone is an instance of a phone.
  • Phone is a class from which your instance was created.
  • Each time a new phone is made, a new instance from the class of phone is made and each instance of the phone is an object.
  • Your phone may have different functionality and look; it may be plastic, metal, etc.
  • You perform certain functions with your phone; you make calls, you text, you write e-mail, etc.

Object, Method

Your Phone, Make a call Your Phone, Send a text Your Phone, send an e-mail Your Phone, charge.

Instances and Methods

  • Unique occurrence of class is an instance, actions performed on instances are methods.
  • Some methods can be applied to the instance only or to the class itself. I.e. finding out how many phones Nokia makes would apply to the class but recharging the phone would be an instance method.
  • Each object contains information about initial characteristics on construction but also the current characteristics. These can change dynamically during the life of the object/instance.

Objective-C syntax for applying methods to classes and instance:

[ ClassOrInstance method ];
  1. Left bracket followed by name of class or instance of the class.
  2. Followed by spaces then followed by the method you wish to perform.
  3. It is finally closed with a right bracket and a terminating semicolon.

When asking a class or instance to perform an action, you are sending it a message. The recipient of that message is called the receiver. Within the outlined format:

[ receiver message ];

Using the previous table:

yourPhone = [Phone new]; // Get a new phone

Sending a new message to the Phone class (the receiver) asking for a new car. The object (becoming the unique instance) is stored in yourPhone. This is now used to reference the unique instance of the phone from the factory.

new is a class method. The rest of the actions on the unique instance will be instance methods, applicable only to the unique instance.

[yourPhone prep]; // Prepare your phone for first time use
[yourPhone charge]; // Charge your phone
[yourPhone call]; // Make a call
[yourPhone send_e-mail]; // Send an email
[yourPhone send_sms]; // Text from your phone
currentCharge = [yourPhone battery_status];

The last entry, currentCharge, is an instance method that returns information. This will return the current charge level of the battery. We store it within the variable currentCharge.

A method taking an argument can be [yourPhone setLockCode: 1234]; // Sets the lock password to 1234

An Objective-C Class for Working with Fractions

1. Procedural Implementation

#import <Foundation/Foundation.h>

int main (int argc, const char* argv[])

{

@autoreleasepool {

int numerator = 1;

int denominator = 3;

NSLog (@”The fraction is %i/%i”, numerator, denominator);

}

return 0;

}

2012-02-10 20:07:06.270 prog1[16626:707] The fraction is 1/3

2. Class Implementation

#import <Foundation/Foundation.h>

// @interface to the class

@interface Fraction: NSObject

-(void) print;

-(void) setNumerator: (int) n;

-(void) setDenominator: (int) d;

@end

// @implementation within the class

@implementation Fraction

{

intnumerator;

intdenominator;

}

-(void) print

{

NSLog(@”%i/%i”, numerator, denominator);

}

-(void) setNumerator:(int)n

{

numerator= n;

}

-(void) setDenominator:(int)d

{

denominator = d;

}

@end

// @@@ Main program

int main (int argc, const char* argv[])

{

@autoreleasepool {

Fraction *myFraction;

// Declare instance of fraction

myFraction = [Fraction alloc];

myFraction = [myFraction init];

// Set fraction to 4/5

[myFraction setNumerator: 4];

[myFraction setDenominator: 5];

// Display fraction using internal print method

NSLog (@”Fraction is:”);

[myFraction print];

}

return 0;

}

Output:

2012-02-10 20:14:22.185 prog1[16728:707] Fraction is:

2012-02-10 20:14:22.190 prog1[16728:707] 4/5

Program ended with exit code: 0

Explanation

Program is logically divided into three sections:

  • @interface section
  • @implementation section
  • program section

The @interface section DESCRIBES the class and it’s methods. @implementation DESCRIBES the data (instance variables etc), and contains code to implement the methods declared in the @interface section. The final section being program contains the main program to carry out the purpose of the program.

One can also declare instance variables for a class within the interface section. Declaring within the implementation section is considered a better way to do it.

Each of these sections is part of every Objective C program. Each section is typically within its own file.

@Interface Section

When defining a new class. You have to tell the compiler where the class came from. Name the parent class. Then you have to define the operations – methods – to be used when working with objects created from this class. Items called properties are also listed within the @interface section.

@interface NewClass: ParentClass
propertyAndMethodDeclarations;
@end

Convention states class names begin with an uppercase letter.

Class and Instance Methods

You must define methods to work with your Fractions class. You will not have direct access to the internal variables in the instance. You have to write methods to set the variables within the instance, in the previous case – numerator and denominator. You also wrote a method called print that displays the value of the fraction.

-(void) print;

The minus sign tells the compiler that the method is an instance method. The only other option is a plus sign, which indicates a class method. A class method performs an operation on the class itself, like creating a new instance of the class.

An instance method performs operations on an instance (the unique object) of a class, like setting values, displaying etc.

Return Values

When declaring a new method, you have to tell the compiler if the method returns a value and what type it is. Enclose the return type in parentheses after the leading minus or plus sign. For example, this returns an integer:

-(int) currentAge;

This returns a double precision value:

-(double) returnDouble;

A value is returned using the return statement. If the method returns no value you indicate this using void.

-(void) print;

This declares and instance method called print that returns no value. You do not need to execute a return statement at the end of the method in this case. You can also execute a return without any value legally too.

return;

Method Arguments

Two other methods were declared in the @interface on the previous program:

-(void) setNumerator: (int) n; -(void) setDenominator: (int) d;

These are instance methods that return no value. Each method accepts an integer argument as indicated by the (int) in front of argument name. When a method accepts an argument, you append a colon to the method name when referring to the method. Therefore, setNumerator: is the correct way to identify the method which takes an argument. Identifying print without a trailing colon indicates that the method does not accept any arguments.

@implementation section

@implementation section contains code for methods declared in @interface section. You must specify the type of data to be stored in the objects of the class. Describe the data that members of the class will contain. These members are called instance variables.

Declare the methods in the @interface section and Define them in the @implementation section.

The general format for @implementation is:

@implementation NewClass{
memberDeclarations;
}
methodDefinitions;
@end

NewClass is the same name used for the class in the @interface section. You can use trailing colon followed by the parent class name, like the @interface section. @implementation Fraction: NSObject. However, this is optional and typically not done.

memberDeclarations section specifies what type of data is stored in a ParentClass, along with the names of those data types. Members declared here; int numerator; are known as instance variables. Each time you create a new object, a new and unique set of instance variables are created. They are internal variables only applicable to that instance Instance1 of parentClass and Instance2 of parentClass will have independent copies of each instance variable.

The program section

The program section contains code to solve the particular problem, which can be spread out across many files. A main routine must exist. This is where the program begins execution.

Define a variable called myFraction. The asterisk in the declaration says that myFraction is a pointer (reference) to a Fraction object. The variable does not store the data it stores a reference – a memory address – indicating where the object’s data is located in memory.

Fraction *myFraction;

myFraction defined as an object of type Fraction. Creating the actual object of Fraction. Ask the factory for a new object:

myFraction = [Fraction alloc];

alloc being short for allocate. This allocates memory for the new Fraction. The expression sends a MESSAGE to the Fraction class – [Fraction alloc].

myFraction = [myFraction init];

The init method initializes the class instance. The message is sent to the object you created – the unique instance. The init method returns a value — the initialized object. Here, we store the initialized class in the myFraction variable.

It is possible to combined the two line operation of allocating the new instance of a class and initializing it:

myFraction = [[Fraction alloc] init];

This can be taken further and can be shortened to have allocation and initialization within the declaration statement:

Fraction *myFraction = [[Fraction alloc] init];

Setting the values of variables within the class:

[myFraction setNumerator: 1];

[myFraction setDenominator: 3];

The first message statement sends setNumerator: message to myFraction. The supplied parameter is value 1. Same again with the second line for setDenominator.

Accessing Instance Variables and Data Encapuslation

Need to flesh out

Objective-C

1. Objective-C: First out the gate, building the first app

Using X-Code.
“Create a New Xcode Project” from startup screen (or File->New->New Project).
Command Line Tool application type.

Product name: prog1
Company identifier: Whatever!

Ensure that Foundation is select as the Type.
Ensure Use Automatic Reference Counting is selected.

Choose your location for your project.

Left hand pane, main.m. Open this and use this as the home for the first app.

  • Extension; Meaning
  • .c; C language source
  • .cc, .cpp; C++ language source
  • .h; Header file
  • .m; Objective-C source
  • .mm; Objective-C++ source
  • .pl; Perl source
  • .o; Object (compiled) file

The first application:

//
//  main.m
//  prog1
//
//  Created by Duncan Bowring on 1/15/12.
//

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[])
{

@autoreleasepool {

// insert code here...
NSLog(@"The first app");

}
return 0;
}

Under the View toolbar menu, middle icon is to show the window which will display the program output. Mouse tooltip should say “Hide or show the Debug area”.
Xcode should display this window whenever anything is written to the debug area. Here is the output from the first app:

2012-01-21 19:45:52.626 prog1[1355:707] The first app

 

Program Explanation

  • Objective-C the code is case sensitive.
  • White space doesn’t matter; Objective-C does not care where on the line the code is entered.
  • The first 6 lines of the program are comments. Comments are not executed by the compiler and are used to document the program for the person reading the source code.
    • Two ways of entering comments:
      • // (two slashes) which are for single line comments.
      • /* to begin a comment block; this marks the beginning of the block.
      • */ will mark the end of the comment block and terminate the comment.
        • Handy if you want multi line comments. /* Comments cannot be nested.
  • Next line of code tells compiler to find and process/include a file named Foundation.h.
    • This is a system file.
    • Foundation.h contains information about other classes/functions that are used later in the program.
  • main is a special name indicating where the program is to begin execution. int specifies the type of value main returns. It is an integer.
  • The contents of ( ) are for command line arguments which is part of the C language.
  • The main routine’s program statements are contained within the braces { }
  • @autoreleasepool
    • Anything executed within the { } is within a context called autorelease pool. The autorelease pool is a mechanism which allows system to manage the memory the application uses as it creates new objects.
  • The statement NSLog is called within the routine and has a string argument; @”The first app”. The @ sign and the “” makes this known as a constant NSString object. Without the @ you will be writing a constant C-style string. With it you are writing an NSString string object.
  • NSLog routine is an Objective-C function that logs the arguments. Before it logs them it displays date and time the routine is executed, the program name and other data relating to process.
  • All statements in Objective-C must be terminated with a semi-colon.
  • Final code statement is return 0;. – This tells main upon termination to return a status value of 0. 0 as a return code means the program ended without error.

Summary of the whole process:

  1. Start XCode.
  2. Create new project; File->New->New Project or Create New Xcode Project from startup screen.
  3. Type of application, select Application->Command Line Tool.
  4. Enter name of application and set type to Foundation. Ensure Use Automatic Reference Counting is checked.
  5. Select name for project folder and choose directory to store project files in.
  6. Left hand window, main.m. It may be hidden in the tree view. Click the file and type program into the edit window that appears in the rightmost pane.
  7. In toolbar, select middle icon under View. This will show Debug window. This is where program output will show.
  8. Build and run the application by clicking Run button in toolbar.
  9. If any compiler errors show here, change the program code and run it again.

Displaying Variable Values

NSLog can also display the variable values and results of computations.

int main (int argc, const char * argv[])

{

@autoreleasepool {

int sum;

sum = 10 + 15;

NSLog(@”The sum of 10 and 15 is %i”, sum);

}

return 0;

}

Program Output:

2012-01-21 20:25:32.175 prog1[2193:707] The sum of 10 and 15 is 25

Program ended with exit code: 0

int sum; declares the variable sum to be set up of type integer. All variables must be declared before they can be used.
Variable declaration tells the compiler how the program should use it. Type int can only hold integer values – basically a number without a remainder/floating point only.
The number 15 is added to the number 10 and the computational result is stored (as indicated by the = sign) in the variable called sum.
NSLog routine has two arguments enclosed within the ( ) brackets. These arguments are separated by the comma.
The first argument of NSLog is the string. We want to have the value of variable sum displayed after the constant string characters defined here. The % character is a special character that NSLog recognizes. The character immediately following the % sign specifies what type of value to display at this point in the string. The letter i signals that an integer is to be displayed. When NSLog finds %i within the first parameter (the string), it will display the value of the next argument to the routine. sum is the next argument to NSLog, the value is automatically displayed after the initial string of “The sum of 10 and 15 is “.

You can stack these. For example, you can have multiple %i %i %i %i within the first parameter (character string), and afterwards have , variable1, variable2, variable3, variable4 and it will display as such.

Some other Programming Exercises:

1. Write a program that displays the following text:

In Objective-C, lowercase letters are significant.
main is where program execution begins.
Open and closed braces enclose program statements in a routine.
All program statements must be terminated by a semicolon.

Source Code:

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[])

{

@autoreleasepool {

NSLog(@”In Objective-C, lowercase letters are significant.\nmain is where program execution begins.\nOpen and closed braces enclose program statements in a routine.\nAll program statements must be terminated by a semicolon.”);

}

return 0;

}

Code Output:

In Objective-C, lowercase letters are significant.

main is where program execution begins.

Open and closed braces enclose program statements in a routine.

All program statements must be terminated by a semicolon.

2. What output would you expect from the following program?

Source Code:

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[])

{

@autoreleasepool {

int i;

i = 1;

NSLog (@”Testing…”);

NSLog (@”….%i”, i);

NSLog (@”…%i”, i + 1);

NSLog (@”..%i”, i + 2);

}

return 0;

}

Code Output:

2012-01-21 21:45:24.596 prog1[2997:707] Testing…

2012-01-21 21:45:24.597 prog1[2997:707] ….1

2012-01-21 21:45:24.599 prog1[2997:707] …2

2012-01-21 21:45:24.600 prog1[2997:707] ..3

3. Write a program that subtracts the value 15 from 87 and displays the result, together with an appropriate message.

Source Code:

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[])

{

@autoreleasepool {

int sum;

sum = 8715;

NSLog (@”87 – 15 = %i”,sum);

}

return 0;

}

Code Output:

2012-01-21 21:49:14.405 prog1[3093:707] 87 – 15 = 72

 

4. Identify the syntactic errors in the following program. Then type in and run the corrected program to make sure you have identified all the mistakes:

Source Code:

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[])

{

@autoreleasepool {

INT sum;

/* COMPUTE RESULT //

sum = 25 + 37 – 19

/ DISPLAY RESULTS /

NSLog (@’The answer is %i’ sum);

}

return 0;

}

Answer:

  • Upper case INT; should be lower case.
  • No close to quote block; // instead of */
  • No semicolon ending statement after computation; sum
  • Invalid single line quote; / instead of //
  • No double quote for character string as first parameter of NSLog.

Correct Source Code:

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[])

{

@autoreleasepool {

int sum;

/* COMPUTE RESULT */

sum = 25 + 3719;

// DISPLAY RESULTS /

NSLog (@”The answer is %i”, sum);

}

return 0;

}

Code Output:

2012-01-21 21:55:31.080 prog1[3238:707] The answer is 43

 

Onto 2.