Task: Rosetta Code_Rank languages by popularity

C: #include <stdio.h>
#include <stdlib.h>
#include <string.h>

const char * lang_url = "http:
		"list=categorymembers&cmtitle=Category:Programming_Languages&"
		"cmlimit=500&format=json";
const char * cat_url = "http:

#define BLOCK 1024
char *get_page(const char *url)
{
	char cmd[1024];
	char *ptr, *buf;
	int bytes_read = 1, len = 0;
	sprintf(cmd, "wget -q \"%s\" -O -", url);
	FILE *fp = popen(cmd, "r");
	if (!fp) return 0;
	for (ptr = buf = 0; bytes_read > 0; ) {
		buf = realloc(buf, 1 + (len += BLOCK));
		if (!ptr) ptr = buf;
		bytes_read = fread(ptr, 1, BLOCK, fp);
		if (bytes_read <= 0) break;
		ptr += bytes_read;
	}
	*++ptr = '\0';
	return buf;
}

char ** get_langs(char *buf, int *l)
{
	char **arr = 0;
	for (*l = 0; (buf = strstr(buf, "Category:")) && (buf += 9); ++*l)
		for (	(*l)[arr = realloc(arr, sizeof(char*)*(1 + *l))] = buf;
			*buf != '"' || (*buf++ = 0);
			buf++);

	return arr;
}

typedef struct { const char *name; int count; } cnt_t;
cnt_t * get_cats(char *buf, char ** langs, int len, int *ret_len)
{
	char str[1024], *found;
	cnt_t *list = 0;
	int i, llen = 0;
	for (i = 0; i < len; i++) {
		sprintf(str, "/wiki/Category:%s", langs[i]);
		if (!(found = strstr(buf, str))) continue;
		buf = found + strlen(str);

		if (!(found = strstr(buf, "</a> ("))) continue;
		list = realloc(list, sizeof(cnt_t) * ++llen);
		list[llen - 1].name = langs[i];
		list[llen - 1].count = strtol(found + 6, 0, 10);
	}
	*ret_len = llen;
	return list;
}

int _scmp(const void *a, const void *b)
{
	int x = ((const cnt_t*)a)->count, y = ((const cnt_t*)b)->count;
	return x < y ? -1 : x > y;
}

int main()
{
	int len, clen;
	char ** langs = get_langs(get_page(lang_url), &len);
	cnt_t *cats = get_cats(get_page(cat_url), langs, len, &clen);
	qsort(cats, clen, sizeof(cnt_t), _scmp);
	while (--clen >= 0)
		printf("%4d %s\n", cats[clen].count, cats[clen].name);

	return 0;
}











Ada: with Ada.Integer_Text_IO;   use Ada.Integer_Text_IO;
with Ada.Strings.Fixed;     use Ada.Strings.Fixed;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
with Ada.Text_IO;           use Ada.Text_IO;

with Ada.Containers.Ordered_Sets;
with Ada.Strings.Less_Case_Insensitive;

with AWS.Client;
with AWS.Response;

procedure Test is

   use Ada.Strings;

   function "+" (S : String) return Unbounded_String renames To_Unbounded_String;

   type A_Language_Count is
      record
         Count    : Integer := 0;
         Language : Unbounded_String;
      end record;

   function "=" (L, R : A_Language_Count) return Boolean is
   begin
      return L.Language = R.Language;
   end "=";

   function "<" (L, R : A_Language_Count) return Boolean is
   begin
      
      return L.Count < R.Count
        or else (L.Count = R.Count
                 and then Less_Case_Insensitive (Left  => To_String (L.Language),
                                                 Right => To_String (R.Language)));
   end "<";

   package Sets is new Ada.Containers.Ordered_Sets (A_Language_Count);
   use Sets;

   Counts : Set;

   procedure Find_Counts (S : String) is
      Title_Str : constant String  := "title=""Category:";
      End_A_Str : constant String  := "</a> (";

      Title_At   : constant Natural := Index (S, Title_Str);
   begin
      if Title_At /= 0 then
         declare
            Bracket_At : constant Natural := Index (S (Title_At   + Title_Str'Length .. S'Last), ">");
            End_A_At   : constant Natural := Index (S (Bracket_At + 1                .. S'Last), End_A_Str);
            Space_At   : constant Natural := Index (S (End_A_At   + End_A_Str'Length .. S'Last), " ");
            Count      : constant Natural := Natural'Value (S (End_A_At + End_A_Str'Length .. Space_At - 1));
            Language   : constant String  :=                S (Title_At + Title_Str'Length .. Bracket_At - 2);
         begin
            if Bracket_At /= 0 and then End_A_At /= 0 and then Space_At /= 0 then
               begin
                  Counts.Insert (New_Item => (Count, +Language));
               exception
                  when Constraint_Error =>
                     Put_Line (Standard_Error, "Warning: repeated language: " & Language);
                     
                     null;
               end;
            end if;
            
            Find_Counts (S (Space_At + 1 .. S'Last));
         end;
      end if;

   end Find_Counts;

   Place : Natural := 1;

   procedure Display (C : Cursor) is
   begin
      Put (Place, Width => 1);             Put (". ");
      Put (Element (C).Count, Width => 1); Put (" - ");
      Put_Line (To_String (Element (C).Language));
      Place := Place + 1;
   end Display;
 
   Http_Source : constant AWS.Response.Data :=
     AWS.Client.Get ("http://rosettacode.org/mw/index.php?title=Special:Categories&limit=5000");
begin
   Find_Counts (AWS.Response.Message_Body (Http_Source));
   Counts.Reverse_Iterate (Display'Access);
end Test;