Utveckligen av Shopp går i en rasande fart framåt. Just nu fokuserar utvecklarna främst på att se till att göra kodbasen stabil och se till att allting fungerar.
Jag nämnde i mitt senaste inlägg kring Shopp att en alpha-version skulle dyka upp ganska kort efter att det postades. Den har dykt upp för ganska länge sedan och det ser riktigt bra ut, det som har fått mycket fokus är baksidan, alltså källkoden, det gör att det inte är några jättestora förändringar utseendemässigt. Det är förvisso lite enklare att hitta i orderdetaljerna och en andra småsaker.
Något som jag trivs riktigt bra med är hanteringen av betalningsmodulerna, jag var med Jonathan Davis (huvudutvecklare) en kväll och vi gjorde i ordning Payson-modulen så den är kompatibel med 1.1. Jisses vilken skillnad i kod jämfört med den tidigare versionen 1.0.x.
Momssatser för specifika kategorier är även det möjligt, men det är lite finputsning på det kvar innan den fungerar klockrent.
Så, när kommer den?
Det som just nu tar tid är QA-delen, att se till att allting funkar. Det har varit lite dåligt med testning från min egen sida, men jag räknar med att sätta igång ordentligt någon gång under nästa vecka. Det nämndes i en videointervju med Jonathan att de siktade på slutet av juni, men det är flytande.
I en projektkurs den här perioden ”Operativsystem” har vi skapat ett ganska grundläggande operativsystem vid namn ”Whilenium”, vi har kört det genom Simics med emulering av MIPS. Simics beskrivs så här av Wikipedia:
Simics is a full-system simulator used to run unchanged production binaries of the target hardware at high-performance speeds. Simics was originally developed by the Swedish Institute of Computer Science (SICS), and then spun off to Virtutech for commercial development in 1998.
Vårt operativsystem har i korta drag följande funktioner:
- Skapa flera processer
- Köra processerna samtidigt
- Skicka och ta emot I/O

Däremellan är det väldigt mycket saker varje process ska kunna göra (och inte göra), exempelvis ska processerna kunna avsluta varandra, inte dela minne med varandra etc.
Det har varit en väldigt intressant kurs som byggde på en tidigare väldigt teoretisk kurs med mycket praktiskt arbete. Det som var svårast var nog att förstå kopplingen mellan C och Assembler. Därefter stötte vi på en del problem vad gäller schemaläggningen av processer samt få till systemanropen för att hoppa mellan ”User-space” och ”Kernel-space”
För de som är intresserade kan ni ladda ner källkoden och se (den väldigt korta) dokumentationen här. Ni kan även besöka vårt projekt på Google Code.
Källkoden har en del struktureringsbrister och är inte helt komplett dokumenterad, det hann vi inte med i slutspurten av projektet.

Tack till Jesper Friberg, Oskar Wirén och Daniel Lervik för ett bra arbete!
Rubriken är en del av ett twitter-inlägg postat av Rey Bango och handlar om Internet Explorer 9 som släpptes som en preview idag.
Istället för att jag ska skriva om denna händelse så tänkte jag länka till några andra läsvärda inlägg om detta:
Trevlig läsning! Jag säger som min gode vän Pär Häggström sa: ”Om Microsoft inte gjort rätt den här gången kommer jag aldrig förlåta dem!”
Tänkte snabbt lägga upp koden som vi gjorde i en skoluppgift. Uppgiften gick ut på att skapa en del i ett shell-script, närmare bestämt den delen där kommandon som skrivs i shellet ”pipas”.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
/* The array below will hold the arguments: args[0] is the command. */
static char* args[512];
pid_t pid;
int command_pipe[2];
#define READ 0
#define WRITE 1
/*
* Handle commands separatly
* input: return value from previous command (useful for pipe file descriptor)
* first: 1 if first command in pipe-sequence (no input from previous pipe)
* last: 1 if last command in pipe-sequence (no input from previous pipe)
*
* EXAMPLE: If you type "ls | grep shell | wc" in your shell:
* fd1 = command(0, 1, 0), with args[0] = "ls"
* fd2 = command(fd1, 0, 0), with args[0] = "grep" and args[1] = "shell"
* fd3 = command(fd2, 0, 1), with args[0] = "wc"
*
* So if 'command' returns a file descriptor, the next 'command' has this
* descriptor as its 'input'.
*/
static int command(int input, int first, int last)
{
int pipettes[2];
/* Invoke pipe */
pipe( pipettes );
pid = fork();
/*
SCHEME:
STDIN --> O --> O --> O --> STDOUT
*/
if (pid == 0) {
if (first == 1 && last == 0 && input == 0) {
// First command
dup2( pipettes[WRITE], STDOUT_FILENO );
} else if (first == 0 && last == 0 && input != 0) {
// Middle command
dup2(input, STDIN_FILENO);
dup2(pipettes[WRITE], STDOUT_FILENO);
} else {
// Last command
dup2( input, STDIN_FILENO );
}
if (execvp( args[0], args) == -1)
_exit(EXIT_FAILURE); // If child fails
}
if (input != 0)
close(input);
// Nothing more needs to be written
close(pipettes[WRITE]);
// If it's the last command, nothing more needs to be read
if (last == 1)
close(pipettes[READ]);
return pipettes[READ];
}
/* Final cleanup, 'wait' for processes to terminate.
* n : Number of times 'command' was invoked.
*/
static void cleanup(int n)
{
int i;
for (i = 0; i < n; ++i)
wait(NULL);
}
static int run(char* cmd, int input, int first, int last);
static char line[1024];
static int n = 0; /* number of calls to 'command' */
int main()
{
printf("SIMPLE SHELL: Type 'exit' or send EOF to exit.\n");
while (1) {
/* Print the command prompt */
printf("$> ");
fflush(NULL);
/* Read a command line */
if (!fgets(line, 1024, stdin))
return 0;
int input = 0;
int first = 1;
char* cmd = line;
char* next = strchr(cmd, '|'); /* Find first '|' */
while (next != NULL) {
/* 'next' points to '|' */
*next = '\0';
input = run(cmd, input, first, 0);
cmd = next + 1;
next = strchr(cmd, '|'); /* Find next '|' */
first = 0;
}
input = run(cmd, input, first, 1);
cleanup(n);
n = 0;
}
return 0;
}
static void split(char* cmd);
static int run(char* cmd, int input, int first, int last)
{
split(cmd);
if (args[0] != NULL) {
if (strcmp(args[0], "exit") == 0)
exit(0);
n += 1;
return command(input, first, last);
}
return 0;
}
static char* skipwhite(char* s)
{
while (isspace(*s)) ++s;
return s;
}
static void split(char* cmd)
{
cmd = skipwhite(cmd);
char* next = strchr(cmd, ' ');
int i = 0;
while(next != NULL) {
next[0] = '\0';
args[i] = cmd;
++i;
cmd = skipwhite(next + 1);
next = strchr(cmd, ' ');
}
if (cmd[0] != '\0') {
args[i] = cmd;
next = strchr(cmd, '\n');
next[0] = '\0';
++i;
}
args[i] = NULL;
}
Förra måndagen var jag i Stockholm på Geek Meet hos Creuna och lyssnade på Christopher Blizzard. Christophers föredrag handlade först och främst om HTML5, men med stora inslag om hur Mozilla som organisation fungerade samt vilka produkter de utvecklar.
Något som ligger Mozilla och mig varmt om hjärtat är integritet och öppen källkod. Alla Mozillas produkter är öppen källkod som jag förstått det, och i alla deras produkter så står integritet högt i priolistan.
För att lösa synkroniseringen av data mellan flera datorer så har jag tidigare använt Xmarks, men för någon vecka sedan släpptes Mozilla Weave. När det släpptes så tänkte jag låta det mogna lite innan jag provade det, men efter Christophers föredrag och hans entusiasm över det så tänkte jag att det var lika bra att göra slag i sak och testa det så fort jag kom hem.
Christopher bekräftade mina misstankar att Xmarks läser av datan som sparas hos dem, och jag har känt en längre tid att jag inte alls gillade det. Weave å andra sidan sparar allt hos dem som en enda stor blob som inte ens de kan läsa av (inte utan min nyckel).
Weave gör följande:
- Synkroniserar dina tabbar, så du kan fortsätta det du gör på en annan dator
- Synkroniserar bokmärken, lösenord och Personas,
I kommande versioner är det meningen att Weave ska synkronisera dina tillägg också, något jag verkligen ser fram emot.
Jag har läst på forum att Weave buggar för många, men jag har inte märkt av några problem än så länge. Om någon vecka kan jag nog gå in och ta bort mitt konto hos Xmarks.
Så ett hett tips är: Mozilla Weave!