Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
3
Task/Rosetta-Code-Find-unimplemented-tasks/00-META.yaml
Normal file
3
Task/Rosetta-Code-Find-unimplemented-tasks/00-META.yaml
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
from: http://rosettacode.org/wiki/Rosetta_Code/Find_unimplemented_tasks
|
||||
note: Rosetta Code related
|
||||
9
Task/Rosetta-Code-Find-unimplemented-tasks/00-TASK.txt
Normal file
9
Task/Rosetta-Code-Find-unimplemented-tasks/00-TASK.txt
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
;Task:
|
||||
Given the name of a language on Rosetta Code, find all tasks which are not implemented in that language.
|
||||
|
||||
|
||||
Note: Implementations should allow for fetching more data than can be returned in one request to Rosetta Code.
|
||||
|
||||
You'll need to use the Media Wiki API, which you can find out about locally, [http://rosettacode.org/mw/api.php here], or in Media Wiki's API documentation at, [http://www.mediawiki.org/wiki/API_Query API:Query]
|
||||
<br><br>
|
||||
|
||||
|
|
@ -0,0 +1,469 @@
|
|||
/* ARM assembly Raspberry PI */
|
||||
/* program tasksearchRasp.s */
|
||||
/* access RosettaCode.org and data extract */
|
||||
/* use openssl for access to port 443 */
|
||||
/* test openssl : package libssl-dev */
|
||||
|
||||
/* REMARK 1 : this program use routines in a include file
|
||||
see task Include a file language arm assembly
|
||||
for the routine affichageMess conversion10
|
||||
see at end of this program the instruction include */
|
||||
|
||||
/*******************************************/
|
||||
/* Constantes */
|
||||
/*******************************************/
|
||||
.include "../constantes.inc"
|
||||
|
||||
//.equ EXIT, 1
|
||||
.equ TAILLEBUFFER, 500
|
||||
|
||||
.equ SSL_OP_NO_SSLv3, 0x02000000
|
||||
.equ SSL_OP_NO_COMPRESSION, 0x00020000
|
||||
.equ SSL_MODE_AUTO_RETRY, 0x00000004
|
||||
.equ SSL_CTRL_MODE, 33
|
||||
|
||||
.equ BIO_C_SET_CONNECT, 100
|
||||
.equ BIO_C_DO_STATE_MACHINE, 101
|
||||
.equ BIO_C_SET_SSL, 109
|
||||
.equ BIO_C_GET_SSL, 110
|
||||
|
||||
.equ LGBUFFERREQ, 512001
|
||||
.equ LGBUFFER2, 128001
|
||||
|
||||
/*********************************/
|
||||
/* Initialized data */
|
||||
/*********************************/
|
||||
.data
|
||||
szMessDebutPgm: .asciz "Program 32 bits start \n"
|
||||
szRetourLigne: .asciz "\n"
|
||||
szMessFinOK: .asciz "Program end OK. \n"
|
||||
szMessErreur: .asciz "Erreur !!!"
|
||||
//szMessExtractArea: .asciz "Extraction = "
|
||||
szMessConnectOK: .asciz "Connexion site OK.\n"
|
||||
szMessInitOK: .asciz "Initialisation SSL OK.\n"
|
||||
szMessReqOK: .asciz "Send requete OK.\n"
|
||||
szNomSite1: .asciz "www.rosettacode.org:443" @ host name and port
|
||||
szLibStart: .asciz "<query><categorymembers>" @ search string
|
||||
szLibsearch1: .asciz "<cm pageid="
|
||||
szLibsearch2: .asciz "title="
|
||||
szNomrepCertif: .asciz "/pi/certificats"
|
||||
szRequete1: .asciz "GET /w/api.php?action=query&list=categorymembers&cmtitle=Category:Programming_Tasks&cmlimit=1000&format=xml HTTP/1.1 \r\nHost: rosettacode.org\r\nConnection: keep-alive\r\nContent-Type: text/plain\r\n\r\n"
|
||||
szRequete2: .asciz "GET /w/api.php?action=query&list=categorymembers&cmtitle=Category:ARM%20Assembly&cmlimit=500&format=xml HTTP/1.1 \r\nHost: rosettacode.org\r\nConnection: keep-alive\r\nContent-Type: text/plain\r\n\r\n"
|
||||
|
||||
/*********************************/
|
||||
/* UnInitialized data */
|
||||
/*********************************/
|
||||
.bss
|
||||
.align 4
|
||||
sBufferreq: .skip LGBUFFERREQ
|
||||
sBufferreq1: .skip LGBUFFERREQ
|
||||
szExtractArea: .skip TAILLEBUFFER
|
||||
szExtractArea1: .skip TAILLEBUFFER
|
||||
szTaskName: .skip 128
|
||||
szTaskNamePgm: .skip 128
|
||||
.align 4
|
||||
stNewSSL: .skip 200
|
||||
/*********************************/
|
||||
/* code section */
|
||||
/*********************************/
|
||||
.text
|
||||
.global main
|
||||
main:
|
||||
ldr r0,iAdrszMessDebutPgm
|
||||
bl affichageMess @ start message
|
||||
|
||||
/* connexion host port 443 and send query */
|
||||
ldr r0,iAdrszNomSite1
|
||||
ldr r1,iAdrszRequete1
|
||||
ldr r2,iAdrsBufferreq
|
||||
bl envoiRequete
|
||||
cmp r0,#-1
|
||||
beq 99f @ error ?
|
||||
|
||||
ldr r0,iAdrszNomSite1
|
||||
ldr r1,iAdrszRequete2
|
||||
ldr r2,iAdrsBufferreq1
|
||||
bl envoiRequete
|
||||
cmp r0,#-1
|
||||
beq 99f @ error ?
|
||||
|
||||
bl analyseReponse
|
||||
|
||||
ldr r0,iAdrszMessFinOK @ end message
|
||||
bl affichageMess
|
||||
mov r0, #0 @ return code ok
|
||||
b 100f
|
||||
99:
|
||||
ldr r0,iAdrszMessErreur @ error
|
||||
bl affichageMess
|
||||
mov r0, #1 @ return code error
|
||||
b 100f
|
||||
100:
|
||||
mov r7,#EXIT @ program end
|
||||
svc #0 @ system call
|
||||
iAdrszMessDebutPgm: .int szMessDebutPgm
|
||||
iAdrszMessFinOK: .int szMessFinOK
|
||||
iAdrszMessErreur: .int szMessErreur
|
||||
iAdrszNomSite1: .int szNomSite1
|
||||
iAdrszRequete2: .int szRequete2
|
||||
iAdrszRequete1: .int szRequete1
|
||||
iAdrsBufferreq: .int sBufferreq
|
||||
iAdrsBufferreq1: .int sBufferreq1
|
||||
/*********************************************************/
|
||||
/* connexion host port 443 and send query */
|
||||
/*********************************************************/
|
||||
envoiRequete:
|
||||
push {r2-r9,lr} @ save registers
|
||||
mov r8,r0 @ save address site name
|
||||
mov r9,r1 @ save address requete
|
||||
mov r7,r2 @ save address buffer
|
||||
@*************************************
|
||||
@ openSsl functions use *
|
||||
@*************************************
|
||||
@init ssl
|
||||
mov r0,#0
|
||||
bl OPENSSL_init_crypto
|
||||
bl ERR_load_BIO_strings
|
||||
mov r2, #0
|
||||
mov r1, #0
|
||||
mov r0, #2
|
||||
bl OPENSSL_init_crypto
|
||||
mov r2, #0
|
||||
mov r1, #0
|
||||
mov r0, #0
|
||||
bl OPENSSL_init_ssl
|
||||
cmp r0,#0
|
||||
blt erreur
|
||||
bl TLS_client_method
|
||||
bl SSL_CTX_new
|
||||
cmp r0,#0
|
||||
ble erreur
|
||||
mov r6,r0 @ save ctx
|
||||
ldr r1,iFlag
|
||||
bl SSL_CTX_set_options
|
||||
mov r0,r6
|
||||
mov r1,#0
|
||||
ldr r2,iAdrszNomrepCertif
|
||||
bl SSL_CTX_load_verify_locations
|
||||
cmp r0,#0
|
||||
ble erreur
|
||||
mov r0,r6
|
||||
bl BIO_new_ssl_connect
|
||||
cmp r0,#0
|
||||
beq erreur
|
||||
cmp r0,#-1
|
||||
beq erreur
|
||||
mov r5,r0 @ save bio
|
||||
ldr r0,iAdrszMessInitOK
|
||||
bl affichageMess
|
||||
mov r0,r5
|
||||
mov r1,#BIO_C_GET_SSL
|
||||
mov r2,#0
|
||||
ldr r3,iAdrstNewSSL
|
||||
bl BIO_ctrl
|
||||
ldr r0,iAdrstNewSSL
|
||||
ldr r0,[r0]
|
||||
mov r1,#SSL_CTRL_MODE
|
||||
mov r2,#SSL_MODE_AUTO_RETRY
|
||||
mov r3,#0
|
||||
bl SSL_ctrl
|
||||
mov r0,r5 @ bio
|
||||
mov r1,#BIO_C_SET_CONNECT
|
||||
mov r2,#0
|
||||
mov r3,r8 @ site address
|
||||
bl BIO_ctrl
|
||||
mov r0,r5 @ bio
|
||||
mov r1,#BIO_C_DO_STATE_MACHINE
|
||||
mov r2,#0
|
||||
mov r3,#0
|
||||
bl BIO_ctrl
|
||||
cmp r0,#0
|
||||
blt erreur
|
||||
|
||||
ldr r0,iAdrszMessConnectOK
|
||||
bl affichageMess
|
||||
@ compute query length
|
||||
mov r2,#0 @ init length
|
||||
mov r1,r9 @ query address
|
||||
1: @ loop compute length query
|
||||
ldrb r0,[r1,r2]
|
||||
cmp r0,#0
|
||||
addne r2,#1
|
||||
bne 1b
|
||||
@ send query
|
||||
mov r0,r5 @ bio
|
||||
@ r1 = address query
|
||||
@ r2 = length query
|
||||
mov r3,#0
|
||||
bl BIO_write @ send query
|
||||
cmp r0,#0
|
||||
blt erreur
|
||||
ldr r0,iAdrszMessReqOK
|
||||
bl affichageMess
|
||||
2: @ begin loop to read datas
|
||||
mov r0,r5 @ bio
|
||||
mov r1,r7 @ buffer address
|
||||
mov r2,#LGBUFFERREQ - 1
|
||||
mov r3,#0
|
||||
bl BIO_read
|
||||
cmp r0,#0
|
||||
ble 4f @ error ou pb server
|
||||
mov r1,r7
|
||||
add r7,r0
|
||||
sub r2,r7,#6
|
||||
ldr r2,[r2]
|
||||
ldr r3,iCharEnd
|
||||
cmp r2,r3 @ text end ?
|
||||
beq 4f
|
||||
mov r1,#0xFF @ delay loop
|
||||
3:
|
||||
subs r1,#1
|
||||
bgt 3b
|
||||
b 2b @ loop read other chunk
|
||||
4: @ read end
|
||||
//ldr r0,iAdrsBufferreq @ to display buffer response of the query
|
||||
//bl affichageMess
|
||||
mov r0, r5 @ close bio
|
||||
bl BIO_free_all
|
||||
mov r0,#0
|
||||
b 100f
|
||||
erreur: @ error display
|
||||
ldr r1,iAdrszMessErreur
|
||||
bl afficheerreur
|
||||
mov r0,#-1 @ error code
|
||||
b 100f
|
||||
100:
|
||||
pop {r2-r9,pc} @ restaur registers
|
||||
iFlag: .int SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION
|
||||
iAdrstNewSSL: .int stNewSSL
|
||||
iAdrszNomrepCertif: .int szNomrepCertif
|
||||
iCharEnd: .int 0x0A0D300A
|
||||
iAdrszMessConnectOK: .int szMessConnectOK
|
||||
iAdrszMessInitOK: .int szMessInitOK
|
||||
iAdrszMessReqOK: .int szMessReqOK
|
||||
/*********************************************************/
|
||||
/* response analyze */
|
||||
/*********************************************************/
|
||||
analyseReponse:
|
||||
push {r1-r6,lr} @ save registers
|
||||
@ search start in task buffer
|
||||
ldr r0,iAdrsBufferreq @ buffer address
|
||||
mov r7,r0
|
||||
ldr r1,iAdrszLibStart @ key text address
|
||||
bl rechercheSousChaine
|
||||
cmp r0,#-1
|
||||
beq 99f
|
||||
add r7,r7,r0 @ new search buffer address
|
||||
mov r0,r7
|
||||
@ search start in task buffer
|
||||
ldr r0,iAdrsBufferreq11 @ buffer address
|
||||
mov r5,r0
|
||||
ldr r1,iAdrszLibStart @ key text address
|
||||
bl rechercheSousChaine
|
||||
cmp r0,#-1
|
||||
beq 99f @ error ?
|
||||
add r5,r5,r0
|
||||
mov r0,r5
|
||||
1: @ loop begin to find task in program buffer
|
||||
mov r0,r5
|
||||
ldr r1,iAdrszLibsearch1 @ text code task address
|
||||
mov r2,#1 @ occurence key text
|
||||
mov r3,#2 @ offset
|
||||
ldr r4,iAdrszExtractArea1 @ address result area
|
||||
bl extChaine
|
||||
cmp r0,#-1
|
||||
beq 99f @ error ?
|
||||
mov r5,r0 @ new address to search
|
||||
ldr r0,iAdrszExtractArea1
|
||||
bl conversionAtoD @ conversion code task to numeric
|
||||
mov r10,r0 @ save numeric code
|
||||
mov r0,r5 @ search task name in pgm buffer @
|
||||
ldr r1,iAdrszLibsearch2 @ key text address
|
||||
mov r2,#1 @ occurence key text
|
||||
mov r3,#2 @ offset
|
||||
ldr r4,iAdrszTaskNamePgm @ address result area
|
||||
bl extChaine
|
||||
cmp r0,#-1
|
||||
beq 99f
|
||||
mov r5,r0 @ new address to search
|
||||
2: @ loop search buffer tasks
|
||||
mov r0,r7
|
||||
ldr r1,iAdrszLibsearch1 @ key text address
|
||||
mov r2,#1 @ occurence key text
|
||||
mov r3,#2 @ offset
|
||||
ldr r4,iAdrszExtractArea @ address result area
|
||||
bl extChaine
|
||||
cmp r0,#-1
|
||||
beq 99f
|
||||
mov r7,r0
|
||||
mov r0,r7
|
||||
ldr r1,iAdrszLibsearch2 @ key text address
|
||||
mov r2,#1 @ occurence key text
|
||||
mov r3,#2 @ offset
|
||||
ldr r4,iAdrszTaskName @ address result area
|
||||
bl extChaine
|
||||
cmp r0,#-1
|
||||
beq 99f
|
||||
mov r7,r0 @ new search address in task buffer
|
||||
ldr r0,iAdrszExtractArea
|
||||
bl conversionAtoD @ conversion code task in numeric
|
||||
cmp r10,r0 @ compere two task code
|
||||
beq 10f @ search next codes if equals
|
||||
|
||||
ldr r0,iAdrszTaskName @ else display task name
|
||||
bl affichageMess
|
||||
ldr r0,iAdrszRetourLigne
|
||||
bl affichageMess
|
||||
|
||||
add r0,r7,#4 @ search if end of task list
|
||||
ldrb r2,[r0]
|
||||
cmp r2,#'/'
|
||||
bne 2b @ no -> loop
|
||||
add r0,#1
|
||||
ldrb r2,[r0]
|
||||
cmp r2,#'c'
|
||||
bne 2b @ no -> loop
|
||||
|
||||
b 100f @ yes -> list end
|
||||
10:
|
||||
add r0,r5,#4 @ search if end of pgm task list
|
||||
ldrb r2,[r0]
|
||||
cmp r2,#'/'
|
||||
bne 1b
|
||||
add r0,#1
|
||||
ldrb r2,[r0]
|
||||
cmp r2,#'c'
|
||||
bne 1b
|
||||
|
||||
b 100f @ list pgm end
|
||||
|
||||
99:
|
||||
ldr r0,iAdrszMessErreur1 @ error
|
||||
bl affichageMess
|
||||
mov r0, #-1 @ error return code
|
||||
b 100f
|
||||
100:
|
||||
pop {r1-r6,pc} @ restaur registers
|
||||
iAdrsBufferreq11: .int sBufferreq1
|
||||
iAdrszLibStart: .int szLibStart
|
||||
iAdrszLibsearch1: .int szLibsearch1
|
||||
iAdrszLibsearch2: .int szLibsearch2
|
||||
iAdrszTaskName: .int szTaskName
|
||||
iAdrszTaskNamePgm: .int szTaskNamePgm
|
||||
iAdrszExtractArea: .int szExtractArea
|
||||
iAdrszExtractArea1: .int szExtractArea1
|
||||
iAdrszRetourLigne: .int szRetourLigne
|
||||
iAdrszMessErreur1: .int szMessErreur
|
||||
/*********************************************************/
|
||||
/* Text Extraction behind text key */
|
||||
/*********************************************************/
|
||||
/* r0 buffer address */
|
||||
/* r1 key text to search */
|
||||
/* r2 number occurences to key text */
|
||||
/* r3 offset */
|
||||
/* r4 result address */
|
||||
extChaine:
|
||||
push {r2-r8,lr} @ save registers
|
||||
mov r5,r0 @ save buffer address
|
||||
mov r6,r1 @ save key text
|
||||
@ compute text length
|
||||
mov r7,#0
|
||||
1: @ loop
|
||||
ldrb r0,[r5,r7] @ load a byte
|
||||
cmp r0,#0 @ end ?
|
||||
addne r7,#1 @ no -> loop
|
||||
bne 1b
|
||||
add r7,r5 @ compute text end
|
||||
|
||||
mov r8,#0
|
||||
2: @ compute length text key
|
||||
ldrb r0,[r6,r8]
|
||||
cmp r0,#0
|
||||
addne r8,#1
|
||||
bne 2b
|
||||
|
||||
3: @ loop to search nième(r2) key text
|
||||
mov r0,r5
|
||||
mov r1,r6
|
||||
bl rechercheSousChaine
|
||||
cmp r0,#0
|
||||
blt 100f
|
||||
subs r2,#1
|
||||
addgt r5,r0
|
||||
addgt r5,r8
|
||||
bgt 3b
|
||||
add r0,r5 @ add address text to index
|
||||
add r3,r0 @ add offset
|
||||
sub r3,#1
|
||||
@ and add length key text
|
||||
add r3,r8
|
||||
cmp r3,r7 @ > at text end
|
||||
movge r0,#-1 @ yes -> error
|
||||
bge 100f
|
||||
mov r0,#0
|
||||
4: @ character loop copy
|
||||
ldrb r2,[r3,r0]
|
||||
strb r2,[r4,r0]
|
||||
cmp r2,#0 @ text end ?
|
||||
moveq r0,#0 @ return zero
|
||||
beq 100f
|
||||
cmp r2,#'"' @ text end ?
|
||||
beq 5f
|
||||
cmp r0,#48 @ extraction length
|
||||
beq 5f
|
||||
add r0,#1
|
||||
b 4b @ and loop
|
||||
5:
|
||||
mov r2,#0 @ store final zéro
|
||||
strb r2,[r4,r0]
|
||||
add r0,#1
|
||||
add r0,r3 @ r0 return the last position of extraction
|
||||
@ it is possible o search another text
|
||||
100:
|
||||
pop {r2-r8,pc} @ restaur registers
|
||||
|
||||
/******************************************************************/
|
||||
/* search substring in string */
|
||||
/******************************************************************/
|
||||
/* r0 contains address string */
|
||||
/* r1 contains address substring */
|
||||
/* r0 return start index substring or -1 if not find */
|
||||
rechercheSousChaine:
|
||||
push {r1-r6,lr} @ save registers
|
||||
mov r2,#0 @ index position string
|
||||
mov r3,#0 @ index position substring
|
||||
mov r6,#-1 @ search index
|
||||
ldrb r4,[r1,r3] @ load first byte substring
|
||||
cmp r4,#0 @ zero final ?
|
||||
moveq r0,#-1 @ error
|
||||
beq 100f
|
||||
1:
|
||||
ldrb r5,[r0,r2] @ load string byte
|
||||
cmp r5,#0 @ zero final ?
|
||||
moveq r0,#-1 @ yes -> not find
|
||||
beq 100f
|
||||
cmp r5,r4 @ compare character two strings
|
||||
beq 2f
|
||||
mov r6,#-1 @ not equal - > raz index
|
||||
mov r3,#0 @ and raz byte counter
|
||||
ldrb r4,[r1,r3] @ and load byte
|
||||
add r2,#1 @ and increment byte counter
|
||||
b 1b @ and loop
|
||||
2: @ characters equal
|
||||
cmp r6,#-1 @ first character equal ?
|
||||
moveq r6,r2 @ yes -> start index in r6
|
||||
add r3,#1 @ increment substring counter
|
||||
ldrb r4,[r1,r3] @ and load next byte
|
||||
cmp r4,#0 @ zero final ?
|
||||
beq 3f @ yes -> search end
|
||||
add r2,#1 @ else increment string index
|
||||
b 1b @ and loop
|
||||
3:
|
||||
mov r0,r6 @ return start index substring in the string
|
||||
100:
|
||||
pop {r1-r6,pc} @ restaur registres
|
||||
|
||||
/***************************************************/
|
||||
/* ROUTINES INCLUDE */
|
||||
/***************************************************/
|
||||
.include "../affichage.inc"
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
with Aws.Client, Aws.Messages, Aws.Response, Aws.Resources, Aws.Url;
|
||||
with Dom.Readers, Dom.Core, Dom.Core.Documents, Dom.Core.Nodes, Dom.Core.Attrs;
|
||||
with Input_Sources.Strings, Unicode, Unicode.Ces.Utf8;
|
||||
with Ada.Strings.Unbounded, Ada.Text_IO, Ada.Command_Line;
|
||||
with Ada.Containers.Vectors;
|
||||
|
||||
use Aws.Client, Aws.Messages, Aws.Response, Aws.Resources, Aws.Url;
|
||||
use Dom.Readers, Dom.Core, Dom.Core.Documents, Dom.Core.Nodes, Dom.Core.Attrs;
|
||||
use Aws, Ada.Strings.Unbounded, Input_Sources.Strings;
|
||||
use Ada.Text_IO, Ada.Command_Line;
|
||||
|
||||
procedure Not_Coded is
|
||||
|
||||
package Members_Vectors is new Ada.Containers.Vectors (
|
||||
Index_Type => Positive,
|
||||
Element_Type => Unbounded_String);
|
||||
use Members_Vectors;
|
||||
|
||||
All_Tasks, Language_Members : Vector;
|
||||
|
||||
procedure Get_Vector (Category : in String; Mbr_Vector : in out Vector) is
|
||||
Reader : Tree_Reader;
|
||||
Doc : Document;
|
||||
List : Node_List;
|
||||
N : Node;
|
||||
A : Attr;
|
||||
Page : Aws.Response.Data;
|
||||
S : Messages.Status_Code;
|
||||
|
||||
-- Query has cmlimit value of 100, so we need 5 calls to
|
||||
-- retrieve the complete list of Programming_category
|
||||
Uri_Xml : constant String :=
|
||||
"http://rosettacode.org/mw/api.php?action=query&list=categorymembers"
|
||||
&
|
||||
"&format=xml&cmlimit=100&cmtitle=Category:";
|
||||
Cmcontinue : Unbounded_String := Null_Unbounded_String;
|
||||
begin
|
||||
loop
|
||||
Page :=
|
||||
Aws.Client.Get (Uri_Xml & Category & (To_String (Cmcontinue)));
|
||||
S := Response.Status_Code (Page);
|
||||
if S not in Messages.Success then
|
||||
Put_Line
|
||||
("Unable to retrieve data => Status Code :" &
|
||||
Image (S) &
|
||||
" Reason :" &
|
||||
Reason_Phrase (S));
|
||||
raise Connection_Error;
|
||||
end if;
|
||||
declare
|
||||
Xml : constant String := Message_Body (Page);
|
||||
Source : String_Input;
|
||||
begin
|
||||
Open
|
||||
(Xml'Unrestricted_Access,
|
||||
Unicode.Ces.Utf8.Utf8_Encoding,
|
||||
Source);
|
||||
Parse (Reader, Source);
|
||||
Close (Source);
|
||||
end;
|
||||
Doc := Get_Tree (Reader);
|
||||
List := Get_Elements_By_Tag_Name (Doc, "cm");
|
||||
for Index in 1 .. Length (List) loop
|
||||
N := Item (List, Index - 1);
|
||||
A := Get_Named_Item (Attributes (N), "title");
|
||||
Members_Vectors.Append
|
||||
(Mbr_Vector,
|
||||
To_Unbounded_String (Value (A)));
|
||||
end loop;
|
||||
Free (List);
|
||||
List := Get_Elements_By_Tag_Name (Doc, "query-continue");
|
||||
if Length (List) = 0 then
|
||||
-- we are done
|
||||
Free (List);
|
||||
Free (Reader);
|
||||
exit;
|
||||
end if;
|
||||
N := First_Child (Item (List, 0));
|
||||
A := Get_Named_Item (Attributes (N), "cmcontinue");
|
||||
Cmcontinue :=
|
||||
To_Unbounded_String
|
||||
("&cmcontinue=" & Aws.Url.Encode (Value (A)));
|
||||
Free (List);
|
||||
Free (Reader);
|
||||
end loop;
|
||||
end Get_Vector;
|
||||
|
||||
procedure Quick_Diff (From : in out Vector; Substract : in Vector) is
|
||||
Beginning, Position : Extended_Index;
|
||||
begin
|
||||
-- take adavantage that both lists are already sorted
|
||||
Beginning := First_Index (From);
|
||||
for I in First_Index (Substract) .. Last_Index (Substract) loop
|
||||
Position :=
|
||||
Find_Index
|
||||
(Container => From,
|
||||
Item => Members_Vectors.Element (Substract, I),
|
||||
Index => Beginning);
|
||||
if not (Position = No_Index) then
|
||||
Delete (From, Position);
|
||||
Beginning := Position;
|
||||
end if;
|
||||
end loop;
|
||||
end Quick_Diff;
|
||||
|
||||
begin
|
||||
if Argument_Count = 0 then
|
||||
Put_Line ("Can't process : No language given!");
|
||||
return;
|
||||
else
|
||||
Get_Vector (Argument (1), Language_Members);
|
||||
end if;
|
||||
|
||||
Get_Vector ("Programming_Tasks", All_Tasks);
|
||||
Quick_Diff (All_Tasks, Language_Members);
|
||||
|
||||
for I in First_Index (All_Tasks) .. Last_Index (All_Tasks) loop
|
||||
Put_Line (To_String (Members_Vectors.Element (All_Tasks, I)));
|
||||
end loop;
|
||||
Put_Line
|
||||
("Numbers of tasks not implemented :=" &
|
||||
Integer'Image (Last_Index ((All_Tasks))));
|
||||
end Not_Coded;
|
||||
|
|
@ -0,0 +1,184 @@
|
|||
#NoEnv ; do not resolve environment variables (speed)
|
||||
#SingleInstance force ; allow only one instance
|
||||
SetBatchLines, -1 ; set to highest script speed
|
||||
SetControlDelay, 0 ; set delay between control commands to lowest
|
||||
|
||||
; additional label, for clarity only
|
||||
AutoExec:
|
||||
Gui, Add, DDL, x10 y10 w270 r20 vlngStr ; add drop-down list
|
||||
Gui, Add, Button, x290 y10 gShowLng, Show Unimplemented ; add button
|
||||
Gui, Add, ListView, x10 y36 w400 h300 vcatLst gOnLV, Unimplemented ; add listview
|
||||
Gui, Add, StatusBar, vsbStr, ; add statusbar
|
||||
Gui, Show, , RosettaCode unimplemented list ; show the gui
|
||||
allLng := getList("lng") ; get a list of all available languages
|
||||
selectStr = Select language... ; set selection string for ddl
|
||||
GuiControl, , LngStr, |%selectStr%||%allLng% ; set the ddl to new contents
|
||||
SB_SetIcon("user32.dll", 5) ; change statusbar icon
|
||||
SB_SetText("Done loading languages. Select from menu.") ; change statusbar text
|
||||
Return ; end of the autoexec section. Script waits for input.
|
||||
|
||||
; subroutine for language list in ddl update
|
||||
ShowLng:
|
||||
Gui, Submit, NoHide ; refresh all gui variables
|
||||
If (lngStr != selectStr) ; if the current selected language is not the selection string
|
||||
{
|
||||
SB_SetIcon("user32.dll", 2) ; set statusbar icon to exclamation
|
||||
SB_SetText("Loading unimplemented tasks... Please wait.") ; set statusbar text
|
||||
allTsk := getList("tsk") ; get a list of all tasks
|
||||
allThis := getList(lngStr) ; get a list of all done tasks for this language
|
||||
Loop, Parse, allTsk, | ; parse the list of all tasks
|
||||
{
|
||||
If !InStr(allThis,A_LoopField) ; if the current task is not found in the list of all tasks
|
||||
notImpl .= A_LoopField . "|" ; add the current field to the notImpl variable
|
||||
allTskCnt := A_Index ; save the index for final count
|
||||
}
|
||||
StringTrimRight, notImpl, notImpl, 1 ; remove last delimiter
|
||||
LV_Delete() ; emty the listview
|
||||
GuiControl, -Redraw, catLst ; set the listview to not redraw while adding (speed)
|
||||
Loop, Parse, notImpl, | ; parse the list of not implemented tasks
|
||||
{
|
||||
LV_Add("", A_LoopField) ; add them to the listview, field by field
|
||||
notImplCnt := A_Index ; save the index for final count
|
||||
}
|
||||
GuiControl, +Redraw, catLst ; set the listview back to normal
|
||||
SB_SetIcon("user32.dll", 5) ; change statusbar icon to information
|
||||
SB_SetText("There are " . notImplCnt . " of " . allTskCnt
|
||||
. " tasks unimplemented. Double-click task to open in browser.") ; set the statusbar text
|
||||
notImpl = ; empty the notImpl variable
|
||||
notImplCnt = 0 ; set the count back to 0
|
||||
}
|
||||
Return
|
||||
|
||||
; subroutine for action on listview
|
||||
OnLV:
|
||||
If (A_GuiEvent = "DoubleClick") ; if the listview was double-clicked
|
||||
{
|
||||
LV_GetText(rowTxt, A_EventInfo) ; get the text of the clicked row
|
||||
rowTxt := Enc_Uri(rowTxt) ; uri-encode the text
|
||||
StringReplace, rowTxt, rowTxt, `%20, _, All ; replace all space-encodings with underscores
|
||||
Run % "http://rosettacode.org/wiki/" . rowTxt ; run the resulting link in the default browser
|
||||
}
|
||||
Return
|
||||
|
||||
; generic function to gather list
|
||||
getList(category)
|
||||
{
|
||||
fileName = temp.xml ; set temp-file name
|
||||
If (category = "lng") ; if the category received is lng
|
||||
{
|
||||
category = Programming_Languages ; set the category
|
||||
fileName = lng.xml ; set temp-file name
|
||||
IfExist, %fileName% ; if the file already exists
|
||||
{
|
||||
FileGetTime, modTime, %fileName% ; get the last modified time
|
||||
EnvSub, modTime, %A_Now%, days ; get the difference between now and last modified time in days
|
||||
If (modTime < 3) ; if the result is less than 3
|
||||
Goto, GetFileNoDL ; go to function-internal subroutine to parse
|
||||
}
|
||||
SB_SetIcon("user32.dll", 2) ; set statusbar icon
|
||||
SB_SetText("Loading languages... Please wait.") ; set statusbar text
|
||||
}
|
||||
If (category = "tsk") ; if the category received is tsk
|
||||
category = Programming_Tasks ; set the category
|
||||
|
||||
getFile: ; function-internal subroutine for getting a file and parsing it
|
||||
; construct the url
|
||||
url := "http://www.rosettacode.org/w/api.php?action=query&list="
|
||||
. "categorymembers&cmtitle=Category:" . category
|
||||
. "&cmlimit=500&format=xml" . doContinue
|
||||
UrlDownloadToFile, %url%, %fileName% ; download the url
|
||||
|
||||
getFileNoDL: ; function-internal subroutine for parsing a file
|
||||
FileRead, data, %fileName% ; read file into variable
|
||||
pos = 1 ; set while-loop counter
|
||||
rxp = title="(.*?)" ; set regular expression
|
||||
While (pos := RegExMatch(data, rxp, title, pos)) ; get the contents of the title fields one-by-one
|
||||
{
|
||||
If InStr(title1, "Category:") ; if the contents contain Category:
|
||||
StringTrimLeft, title1, title1, 9 ; remove that from the contents
|
||||
StringReplace, title1, title1, |, `|, All ; escape all containing delimiters
|
||||
title1 := Dec_XML(UTF82Ansi(title1)) ; convert to ansi first and then decode html entities
|
||||
allTitles .= title1 . "|" ; add this title to list
|
||||
pos++ ; increment counter
|
||||
}
|
||||
rxp = cmcontinue="(.*?)" ; set regular expression
|
||||
If RegExMatch(data, rxp, next) ; when found
|
||||
{
|
||||
doContinue = &cmcontinue=%next1% ; set continuation string to add to url
|
||||
Goto getFile ; go to function-internal subroutine to redownload and parse
|
||||
}
|
||||
StringTrimRight, allTitles, allTitles, 1 ; remove last delimiter from result
|
||||
Return allTitles ; return result
|
||||
}
|
||||
|
||||
; function to convert html entities to ansi equivalents
|
||||
Dec_XML(str)
|
||||
{
|
||||
Loop
|
||||
If RegexMatch(str, "S)(&#(\d+);)", dec)
|
||||
StringReplace, str, str, %dec1%, % Chr(dec2), All
|
||||
Else If RegexMatch(str, "Si)(&#x([\da-f]+);)", hex)
|
||||
StringReplace, str, str, %hex1%, % Chr("0x" . hex2), All
|
||||
Else
|
||||
Break
|
||||
StringReplace, str, str, , %A_Space%, All
|
||||
StringReplace, str, str, ", ", All
|
||||
StringReplace, str, str, ', ', All
|
||||
StringReplace, str, str, <, <, All
|
||||
StringReplace, str, str, >, >, All
|
||||
StringReplace, str, str, &, &, All
|
||||
return, str
|
||||
}
|
||||
|
||||
; function to uri-encode input string
|
||||
Enc_Uri(str)
|
||||
{
|
||||
f = %A_FormatInteger%
|
||||
SetFormat, Integer, Hex
|
||||
If RegExMatch(str, "^\w+:/{0,2}", pr)
|
||||
StringTrimLeft, str, str, StrLen(pr)
|
||||
StringReplace, str, str, `%, `%25, All
|
||||
Loop
|
||||
If RegExMatch(str, "i)[^\w\.~%/:]", char)
|
||||
StringReplace, str, str, %char%, % "%" . SubStr(Asc(char),3), All
|
||||
Else Break
|
||||
SetFormat, Integer, %f%
|
||||
Return, pr . str
|
||||
}
|
||||
|
||||
; function to convert unicode to ansi text
|
||||
UTF82Ansi(zString)
|
||||
{
|
||||
Ansi2Unicode(zString, wString, 65001)
|
||||
Unicode2Ansi(wString, sString, 0)
|
||||
Return sString
|
||||
}
|
||||
|
||||
; helper function for unicode to ansi function
|
||||
Ansi2Unicode(ByRef sString, ByRef wString, CP = 0)
|
||||
{
|
||||
nSize := DllCall("MultiByteToWideChar", "Uint", CP
|
||||
, "Uint", 0, "Uint", &sString, "int", -1
|
||||
, "Uint", 0, "int", 0)
|
||||
VarSetCapacity(wString, nSize * 2)
|
||||
DllCall("MultiByteToWideChar"
|
||||
, "Uint", CP, "Uint", 0, "Uint", &sString, "int", -1
|
||||
, "Uint", &wString, "int", nSize)
|
||||
}
|
||||
|
||||
; helper function for unicode to ansi function
|
||||
Unicode2Ansi(ByRef wString, ByRef sString, CP = 0)
|
||||
{
|
||||
nSize := DllCall("WideCharToMultiByte"
|
||||
, "Uint", CP, "Uint", 0, "Uint", &wString, "int", -1
|
||||
, "Uint", 0, "int", 0, "Uint", 0, "Uint", 0)
|
||||
VarSetCapacity(sString, nSize)
|
||||
DllCall("WideCharToMultiByte"
|
||||
, "Uint", CP, "Uint", 0, "Uint", &wString, "int", -1
|
||||
, "str", sString, "int", nSize, "Uint", 0, "Uint", 0)
|
||||
}
|
||||
|
||||
; subroutine called when user closes the gui
|
||||
GuiClose:
|
||||
ExitApp ; exit the script
|
||||
Return
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Net;
|
||||
|
||||
class Program {
|
||||
static List<string> GetTitlesFromCategory(string category) {
|
||||
string searchQueryFormat = "http://www.rosettacode.org/w/api.php?action=query&list=categorymembers&cmtitle=Category:{0}&format=json{1}";
|
||||
List<string> results = new List<string>();
|
||||
string cmcontinue = string.Empty;
|
||||
|
||||
do {
|
||||
string cmContinueKeyValue;
|
||||
|
||||
//append continue variable as needed
|
||||
if (cmcontinue.Length > 0)
|
||||
cmContinueKeyValue = String.Format("&cmcontinue={0}", cmcontinue);
|
||||
else
|
||||
cmContinueKeyValue = String.Empty;
|
||||
|
||||
//execute query
|
||||
string query = String.Format(searchQueryFormat, category, cmContinueKeyValue);
|
||||
string content = new WebClient().DownloadString(query);
|
||||
|
||||
results.AddRange(new Regex("\"title\":\"(.+?)\"").Matches(content).Cast<Match>().Select(x => x.Groups[1].Value));
|
||||
|
||||
//detect if more results are available
|
||||
cmcontinue = Regex.Match(content, @"{""cmcontinue"":""([^""]+)""}", RegexOptions.IgnoreCase).Groups["1"].Value;
|
||||
} while (cmcontinue.Length > 0);
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
static string[] GetUnimplementedTasksFromLanguage(string language) {
|
||||
List<string> alltasks = GetTitlesFromCategory("Programming_Tasks");
|
||||
List<string> lang = GetTitlesFromCategory(language);
|
||||
|
||||
return alltasks.Where(x => !lang.Contains(x)).ToArray();
|
||||
}
|
||||
|
||||
static void Main(string[] args) {
|
||||
string[] unimpl = GetUnimplementedTasksFromLanguage(args[0]);
|
||||
|
||||
foreach (string i in unimpl) Console.WriteLine(i);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
(require
|
||||
'[clojure.xml :as xml]
|
||||
'[clojure.set :as set]
|
||||
'[clojure.string :as string])
|
||||
(import '[java.net URLEncoder])
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
(defn titles-cont [url]
|
||||
(let [docseq (-> url xml/parse xml-seq)]
|
||||
((juxt #(filter string? %), #(-> (filter map? %) first :cmcontinue))
|
||||
(for [{:keys [tag attrs content]} docseq :when (#{:cm :query-continue} tag)]
|
||||
(if (= tag :cm)
|
||||
(attrs :title)
|
||||
(-> content first :attrs))))))
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
(defn urlencode [s] (URLEncoder/encode s "UTF-8"))
|
||||
(defn param [p v] (str p (urlencode v)))
|
||||
|
||||
(defn get-titles
|
||||
([category]
|
||||
(let [urlbase "http://www.rosettacode.org/w/api.php"
|
||||
params ["action=query"
|
||||
"list=categorymembers"
|
||||
"format=xml"
|
||||
"cmlimit=200"
|
||||
(param "cmtitle=Category:" category)]
|
||||
url (str urlbase "?" (string/join "&" params)]
|
||||
(get-titles url nil)))
|
||||
([url continue-at]
|
||||
(let [continue-param (if continue-at (param "&cmcontinue=" continue-at))
|
||||
[titles continue] (titles-cont (str url continue-param))]
|
||||
(if continue
|
||||
(lazy-cat titles (get-titles url continue))
|
||||
titles))))
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
(defn unimplemented [lang-name]
|
||||
(let [title-set #(future (apply sorted-set (get-titles %)))
|
||||
all-titles (title-set "Programming_Tasks")
|
||||
lang-titles (title-set lang-name)]
|
||||
(seq (set/difference @all-titles @lang-titles))))
|
||||
|
||||
(let [titles (unimplemented "Clojure")]
|
||||
(doseq [title titles] (println title))
|
||||
(println "count: " (count titles)))
|
||||
(shutdown-agents)
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
#!/usr/bin/env rune
|
||||
|
||||
# NOTE: This program will not work in released E, because TermL is an
|
||||
# imperfect superset of JSON in that version: it does not accept "\/".
|
||||
# If you build E from the latest source in SVN then it will work.
|
||||
#
|
||||
# Usage: rosettacode-cat-subtract.e [<syntaxhighlight lang="e">]
|
||||
#
|
||||
# Prints a list of tasks which have not been completed in the language.
|
||||
# If unspecified, the default language is E.
|
||||
|
||||
pragma.syntax("0.9")
|
||||
pragma.enable("accumulator")
|
||||
|
||||
def termParser := <import:org.quasiliteral.term.makeTermParser>
|
||||
def jURLEncoder := <unsafe:java.net.makeURLEncoder>
|
||||
|
||||
def urlEncode(text) {
|
||||
return jURLEncoder.encode(text, "UTF-8")
|
||||
}
|
||||
|
||||
/** Convert JSON-as-term-tree to the corresponding natural E data structures. */
|
||||
def jsonTermToData(term) {
|
||||
switch (term) {
|
||||
|
||||
# JSON object to E map
|
||||
match term`{@assocs*}` {
|
||||
return accum [].asMap() for term`@{key :String}: @valueJson` in assocs {
|
||||
_.with(key, jsonTermToData(valueJson))
|
||||
}
|
||||
}
|
||||
|
||||
# JSON array to E list
|
||||
match term`[@elements*]` {
|
||||
return accum [] for elem in elements { _.with(jsonTermToData(elem)) }
|
||||
}
|
||||
|
||||
# Literals just need to be coerced
|
||||
match lit :any[String, int, float64] {
|
||||
return lit
|
||||
}
|
||||
|
||||
# Doesn't support true/false/null, but we don't need that for this application.
|
||||
}
|
||||
}
|
||||
|
||||
def fetchCategoryAccum(name, membersSoFar :Set, extraArgs) {
|
||||
stderr.println(`Fetching Category:$name $extraArgs...`)
|
||||
|
||||
def categoryAPIResource := <http>[`//rosettacode.org/w/api.php?` +
|
||||
`action=query&list=categorymembers&cmtitle=Category:${urlEncode(name)}&` +
|
||||
`format=json&cmlimit=500&cmprop=title$extraArgs`]
|
||||
|
||||
def members :=
|
||||
when (def responseJSON := categoryAPIResource <- getTwine()) -> {
|
||||
# stderr.println(`Fetched Category:$name $extraArgs, parsing...`)
|
||||
def response := jsonTermToData(termParser(responseJSON))
|
||||
|
||||
# stderr.println(`Parsed Category:$name $extraArgs response, extracting data...`)
|
||||
def [
|
||||
"query" => ["categorymembers" => records],
|
||||
"query-continue" => continueData := null
|
||||
] := response
|
||||
def members := accum membersSoFar for record in records { _.with(record["title"]) }
|
||||
|
||||
switch (continueData) {
|
||||
match ==null {
|
||||
stderr.println(`Got all ${members.size()} for Category:$name.`)
|
||||
members
|
||||
}
|
||||
match ["categorymembers" => ["cmcontinue" => continueParam]] {
|
||||
stderr.println(`Fetched ${members.size()} members for Category:$name...`)
|
||||
fetchCategoryAccum(name, members, `&cmcontinue=` + urlEncode(continueParam))
|
||||
}
|
||||
}
|
||||
} catch p { throw(p) }
|
||||
|
||||
return members
|
||||
}
|
||||
|
||||
def fetchCategory(name) {
|
||||
return fetchCategoryAccum(name, [].asSet(), "")
|
||||
}
|
||||
|
||||
# Interpret program arguments
|
||||
def lang := switch (interp.getArgs()) {
|
||||
match [lang] { lang }
|
||||
match [] { "E" }
|
||||
}
|
||||
|
||||
# Fetch categories
|
||||
when (def allTasks := fetchCategory("Programming_Tasks"),
|
||||
def doneTasks := fetchCategory(lang),
|
||||
def omitTasks := fetchCategory(lang + "/Omit")
|
||||
) -> {
|
||||
|
||||
# Compute difference and report
|
||||
def notDoneTasks := allTasks &! (doneTasks | omitTasks)
|
||||
println()
|
||||
println("\n".rjoin(notDoneTasks.getElements().sort()))
|
||||
|
||||
} catch p {
|
||||
# Whoops, something went wrong
|
||||
stderr.println(`$p${p.eStack()}`)
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
-module( find_unimplemented_tasks ).
|
||||
-include_lib( "xmerl/include/xmerl.hrl" ).
|
||||
|
||||
-export( [init_http/0, per_language/1, rosetta_code_list_of/1] ).
|
||||
|
||||
init_http() ->
|
||||
application:start( inets ).
|
||||
|
||||
per_language( Language ) ->
|
||||
ok = init_http(),
|
||||
Tasks = rosetta_code_list_of( "Programming_Tasks" ),
|
||||
Uninplemented = Tasks -- rosetta_code_list_of( Language ),
|
||||
io:fwrite( "Unimplemented total: ~p~n", [erlang:length(Uninplemented)] ),
|
||||
[io:fwrite("~p~n", [X]) || X <- Uninplemented].
|
||||
|
||||
rosetta_code_list_of( Category ) ->
|
||||
URL = "http://rosettacode.org/mw/api.php?action=query&list=categorymembers&cmlimit=500&format=xml&cmtitle=Category:"
|
||||
++ Category,
|
||||
title_contents( URL, "", [] ).
|
||||
|
||||
|
||||
|
||||
title_contents( URL, Continue, Acc ) ->
|
||||
{ok, {{_HTTP,200,"OK"}, _Headers, Body}} = httpc:request( URL ++ Continue ),
|
||||
{XML, _} = xmerl_scan:string( Body ),
|
||||
News = xml_selection( "title", XML ),
|
||||
New_continue = title_contents_url_continue( xml_selection("cmcontinue", XML) ),
|
||||
title_contents_continue( URL, New_continue, Acc ++ News ).
|
||||
|
||||
title_contents_continue( _URL, "", Acc ) -> Acc;
|
||||
title_contents_continue( URL, Continue, Acc ) -> title_contents( URL, Continue, Acc ).
|
||||
|
||||
title_contents_url_continue( [] ) -> "";
|
||||
title_contents_url_continue( [Continue | _] ) -> "&cmcontinue=" ++ Continue.
|
||||
|
||||
xml_selection( Selection, XML ) ->
|
||||
[lists:map( fun xml_8211/1, X) || #xmlAttribute{value=X} <- xmerl_xpath:string("//@" ++ Selection, XML)].
|
||||
|
||||
xml_8211( 8211 ) -> $-;
|
||||
xml_8211( 924 ) -> $\s;
|
||||
xml_8211( 1050 ) -> $\s;
|
||||
xml_8211( 1052 ) -> $\s;
|
||||
xml_8211( Character ) -> Character.
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
const language = "Go"
|
||||
|
||||
var baseQuery = "http://rosettacode.org/mw/api.php?action=query" +
|
||||
"&format=xml&list=categorymembers&cmlimit=100"
|
||||
|
||||
func req(u string, foundCm func(string)) string {
|
||||
resp, err := http.Get(u)
|
||||
if err != nil {
|
||||
fmt.Println(err) // connection or request fail
|
||||
return ""
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
for p := xml.NewDecoder(resp.Body); ; {
|
||||
t, err := p.RawToken()
|
||||
switch s, ok := t.(xml.StartElement); {
|
||||
case err == io.EOF:
|
||||
return ""
|
||||
case err != nil:
|
||||
fmt.Println(err)
|
||||
return ""
|
||||
case !ok:
|
||||
continue
|
||||
case s.Name.Local == "cm":
|
||||
for _, a := range s.Attr {
|
||||
if a.Name.Local == "title" {
|
||||
foundCm(a.Value)
|
||||
}
|
||||
}
|
||||
case s.Name.Local == "categorymembers" && len(s.Attr) > 0 &&
|
||||
s.Attr[0].Name.Local == "cmcontinue":
|
||||
return url.QueryEscape(s.Attr[0].Value)
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func main() {
|
||||
// get language members, store in a map
|
||||
langMap := make(map[string]bool)
|
||||
storeLang := func(cm string) { langMap[cm] = true }
|
||||
languageQuery := baseQuery + "&cmtitle=Category:" + language
|
||||
continueAt := req(languageQuery, storeLang)
|
||||
for continueAt > "" {
|
||||
continueAt = req(languageQuery+"&cmcontinue="+continueAt, storeLang)
|
||||
}
|
||||
|
||||
// a quick check to avoid long output
|
||||
if len(langMap) == 0 {
|
||||
fmt.Println("no tasks implemented for", language)
|
||||
return
|
||||
}
|
||||
|
||||
// get tasks, print as we go along
|
||||
printUnImp := func(cm string) {
|
||||
if !langMap[cm] {
|
||||
fmt.Println(cm)
|
||||
}
|
||||
}
|
||||
taskQuery := baseQuery + "&cmtitle=Category:Programming_Tasks"
|
||||
continueAt = req(taskQuery, printUnImp)
|
||||
for continueAt > "" {
|
||||
continueAt = req(taskQuery+"&cmcontinue="+continueAt, printUnImp)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
import Network.Browser
|
||||
import Network.HTTP
|
||||
import Network.URI
|
||||
import Data.List
|
||||
import Data.Maybe
|
||||
import Text.XML.Light
|
||||
import Control.Arrow
|
||||
import Data.Char
|
||||
|
||||
getRespons url = do
|
||||
rsp <- Network.Browser.browse $ do
|
||||
setAllowRedirects True
|
||||
setOutHandler $ const (return ()) -- quiet
|
||||
request $ getRequest url
|
||||
return $ rspBody $ snd rsp
|
||||
|
||||
replaceWithSpace c = (\x -> if c==x then ' ' else x)
|
||||
|
||||
encl = chr 34
|
||||
|
||||
unimpTasks lang = do
|
||||
allTasks <- getRespons "http://www.rosettacode.org/w/api.php?action=query&list=categorymembers&cmtitle=Category:Programming_Tasks&cmlimit=500&format=xml"
|
||||
impl <- getRespons ( "http://rosettacode.org/json/isb/" ++ lang ++ ".json")
|
||||
let langxx = map (map(replaceWithSpace '_')) $ filter (/=",") $ words $ map (replaceWithSpace encl ) $ init $ drop 1 impl
|
||||
xml = onlyElems $ parseXML allTasks
|
||||
allxx = concatMap (map (fromJust.findAttr (unqual "title")). filterElementsName (== unqual "cm")) xml
|
||||
mapM_ putStrLn $ sort $ allxx \\ langxx
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
import Network.HTTP
|
||||
import Data.Text (splitOn, pack, unpack)
|
||||
import Data.List
|
||||
|
||||
getTasks :: String -> IO [String]
|
||||
getTasks url = do
|
||||
resp <- simpleHTTP (getRequest url)
|
||||
body <- getResponseBody resp
|
||||
return $ tail $ map (unpack . head . splitOn (pack "\"}")) $ splitOn (pack "\"title\":\"") (pack body)
|
||||
|
||||
main :: String -> IO ()
|
||||
main lang = do
|
||||
implTasks <- getTasks $ "http://rosettacode.org/mw/api.php?action=query&list=categorymembers&cmtitle=Category:" ++ lang ++ "&format=json&cmlimit=500"
|
||||
allTasks <- getTasks "http://rosettacode.org/mw/api.php?action=query&list=categorymembers&cmtitle=Category:Programming_Tasks&format=json&cmlimit=500"
|
||||
mapM_ putStrLn $ allTasks \\ implTasks
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
$define RCINDEX "http://rosettacode.org/mw/api.php?format=xml&action=query&list=categorymembers&cmtitle=Category:Programming_Tasks&cmlimit=500"
|
||||
$define RCTASK "http://rosettacode.org/mw/index.php?action=raw&title="
|
||||
$define RCUA "User-Agent: Unicon Rosetta 0.1"
|
||||
$define RCXUA "X-Unicon: http://unicon.org/"
|
||||
$define TASKTOT "* Total Tasks *"
|
||||
$define TOTTOT "* Total Headers*"
|
||||
|
||||
link strings
|
||||
link hexcvt
|
||||
|
||||
procedure main(A) # simple single threaded read all at once implementation
|
||||
lang := \A[1] | "Unicon"
|
||||
write("Unimplemented tasks for ",lang," as of ",&date)
|
||||
every task := taskNames() do {
|
||||
if lang == languages(task) then next
|
||||
write(task)
|
||||
}
|
||||
end
|
||||
|
||||
# Generate task names
|
||||
procedure taskNames()
|
||||
continue := ""
|
||||
while \(txt := ReadURL(RCINDEX||continue)) do {
|
||||
txt ? {
|
||||
while tab(find("<cm ") & find(s :="title=\"")+*s) do
|
||||
suspend tab(find("\""))\1
|
||||
if tab(find("cmcontinue=")) then {
|
||||
continue := "&"||tab(upto(' \t'))
|
||||
}
|
||||
else break
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
# Generate language headers in a task
|
||||
procedure languages(task)
|
||||
static WS
|
||||
initial WS := ' \t'
|
||||
page := ReadURL(RCTASK||CleanURI(task))
|
||||
page ? while (tab(find("\n==")),tab(many(WS))|"",tab(find("{{"))) do {
|
||||
header := tab(find("=="))
|
||||
header ? {
|
||||
while tab(find("{{header|")) do {
|
||||
suspend 2(="{{header|",tab(find("}}")))\1
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
procedure CleanURI(u) #: clean up a URI
|
||||
static tr,dxml # xml & http translation
|
||||
initial {
|
||||
tr := table()
|
||||
every c := !string(~(&digits++&letters++'-_.!~*()/\'`')) do
|
||||
tr[c] := "%"||hexstring(ord(c),2)
|
||||
every /tr[c := !string(&cset)] := c
|
||||
tr[" "] := "_" # wiki convention
|
||||
every push(dxml := [],"&#"||right(ord(c := !"&<>'\""),3,"0")||";",c)
|
||||
}
|
||||
|
||||
dxml[1] := u # insert URI as 1st arg
|
||||
u := replacem!dxml # de-xml it
|
||||
every (c := "") ||:= tr[!u] # reencode everything
|
||||
c := replace(c,"%3E","'") # Hack to put single quotes back in
|
||||
c := replace(c,"%26quot%3B","\"") # Hack to put double quotes back in
|
||||
return c
|
||||
end
|
||||
|
||||
procedure ReadURL(url) #: read URL into string
|
||||
page := open(url,"m",RCUA,RCXUA) | stop("Unable to open ",url)
|
||||
text := ""
|
||||
if page["Status-Code"] < 300 then while text ||:= reads(page,-1)
|
||||
else write(&errout,image(url),": ",
|
||||
page["Status-Code"]," ",page["Reason-Phrase"])
|
||||
close(page)
|
||||
return text
|
||||
end
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
require 'strings web/gethttp'
|
||||
|
||||
findUnimpTasks=: ('Programming_Tasks' -.&getCategoryMembers ,&'/Omit') ([ #~ -.@e.) getCategoryMembers
|
||||
|
||||
getTagContents=: dyad define
|
||||
'starttag endtag'=. x
|
||||
('\' -.~ endtag&taketo)&.>@(starttag&E. <@((#starttag)&}.);.1 ]) y
|
||||
)
|
||||
|
||||
NB. RosettaCode Utilities
|
||||
parseTitles=: ('"title":"';'"')&getTagContents
|
||||
parseCMcontinue=:('"cmcontinue":"';'"')&getTagContents
|
||||
getCMcontquery=: ('&cmcontinue=' , urlencode)^:(0 < #)@>@parseCMcontinue
|
||||
|
||||
getCategoryMembers=: monad define
|
||||
buildqry=. 'action=query&list=categorymembers&cmtitle=Category:' , ,&'&cmlimit=500&format=json'
|
||||
url=.'http://www.rosettacode.org/w/api.php'
|
||||
uri=. url ,'?', buildqry urlencode y
|
||||
catmbrs=. qrycont=. ''
|
||||
whilst. #qrycont=. ,getCMcontquery jsondat do.
|
||||
jsondat=. '-sL' gethttp uri , qrycont
|
||||
catmbrs=. catmbrs, parseTitles jsondat
|
||||
end.
|
||||
catmbrs
|
||||
)
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
4{. findUnimpTasks 'J' NB. get first 4 unimplemented tasks for J
|
||||
┌────────────────┬────────────────────────┬──────────────────────────────────┬──────────────┐
|
||||
│15 puzzle solver│Active Directory/Connect│Active Directory/Search for a user│Atomic updates│
|
||||
└────────────────┴────────────────────────┴──────────────────────────────────┴──────────────┘
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
(function (strXPath) {
|
||||
var xr = document.evaluate(
|
||||
strXPath,
|
||||
document,
|
||||
null, 0, 0
|
||||
),
|
||||
|
||||
oNode = xr.iterateNext(),
|
||||
lstTasks = [];
|
||||
|
||||
while (oNode) {
|
||||
lstTasks.push(oNode.title);
|
||||
oNode = xr.iterateNext();
|
||||
}
|
||||
|
||||
return [
|
||||
lstTasks.length + " items found in " + document.title,
|
||||
''
|
||||
].concat(lstTasks).join('\n')
|
||||
|
||||
})(
|
||||
'//*[@id="mw-content-text"]/div[2]/table/tbody/tr/td/ul/li/a'
|
||||
);
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
using HTTP, JSON
|
||||
|
||||
const baseuri = "http://www.rosettacode.org/w/api.php?action=query&list=categorymembers&cmtitle=Category:"
|
||||
const enduri = "&cmlimit=500&format=json"
|
||||
queries(x) = baseuri * HTTP.Strings.escapehtml(x) * enduri
|
||||
|
||||
function getimplemented(query)
|
||||
tasksdone = Vector{String}()
|
||||
request = query
|
||||
while (resp = HTTP.request("GET", request)).status == 200
|
||||
fromjson = JSON.parse(String(resp.body))
|
||||
for d in fromjson["query"]["categorymembers"]
|
||||
if haskey(d, "title")
|
||||
push!(tasksdone, d["title"])
|
||||
end
|
||||
end
|
||||
if haskey(fromjson, "continue")
|
||||
cmcont, cont = fromjson["continue"]["cmcontinue"], fromjson["continue"]["continue"]
|
||||
request = query * "&cmcontinue=$cmcont&continue=$cont"
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
tasksdone
|
||||
end
|
||||
|
||||
alltasks = getimplemented(queries("Programming_Tasks"))
|
||||
|
||||
showunimp(x) = (println("\nUnimplemented in $x:"); for t in setdiff(alltasks,
|
||||
getimplemented(queries(x))) println(t) end)
|
||||
|
||||
showunimp("Julia")
|
||||
showunimp("C++")
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
local requests = require('requests')
|
||||
local lang = arg[1]
|
||||
|
||||
local function merge_tables(existing, from_req)
|
||||
local result = existing
|
||||
|
||||
for _, v in ipairs(from_req) do
|
||||
result[v.title] = true
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
local function get_task_list(category)
|
||||
local url = 'http://www.rosettacode.org/mw/api.php'
|
||||
local query = {
|
||||
action = 'query',
|
||||
list = 'categorymembers',
|
||||
cmtitle = string.format('Category:%s', category),
|
||||
cmlimit = 500,
|
||||
cmtype = 'page',
|
||||
format = 'json'
|
||||
}
|
||||
local categories = {}
|
||||
|
||||
while true do
|
||||
local resp = assert(requests.get({ url, params = query }).json())
|
||||
|
||||
categories = merge_tables(categories, resp.query.categorymembers)
|
||||
|
||||
if resp.continue then
|
||||
query.cmcontinue = resp.continue.cmcontinue
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
return categories
|
||||
end
|
||||
|
||||
local function get_open_tasks(lang)
|
||||
if not lang then error('Language missing!') end
|
||||
local all_tasks = get_task_list('Programming_Tasks')
|
||||
local lang_tasks = get_task_list(lang)
|
||||
local task_list = {}
|
||||
|
||||
for t, _ in pairs(all_tasks) do
|
||||
if not lang_tasks[t] then
|
||||
table.insert(task_list, t)
|
||||
end
|
||||
end
|
||||
|
||||
table.sort(task_list)
|
||||
return task_list
|
||||
end
|
||||
|
||||
local open_tasks = get_open_tasks(lang)
|
||||
|
||||
io.write(string.format('%s has %d unimplemented programming tasks: \n', lang, #open_tasks))
|
||||
for _, t in ipairs(open_tasks) do
|
||||
io.write(string.format(' %s\n', t))
|
||||
end
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
#Example with the Maple Language
|
||||
lan := "Maple":
|
||||
x := URL:-Get(cat("http://rosettacode.org/wiki/Reports:Tasks_not_implemented_in_", StringTools:-SubstituteAll(lan, " ", "_")), output = content):
|
||||
x := StringTools:-StringSplit(x, "<h2><span class=\"mw-headline\" id=\"Not_implemented\">Not implemented</span>")[2]:
|
||||
x := StringTools:-StringSplit(x, "<span class=\"mw-headline\" id=\"Draft_tasks_without_implementation\">Draft tasks without implementation</span>")[1]:
|
||||
x := StringTools:-StringSplit(x,"<li><a href=\"/wiki/")[2..]:
|
||||
for problem in x do
|
||||
printf("%s\n", StringTools:-SubstituteAll(StringTools:-Decode(StringTools:-StringSplit(problem, "\" title=")[1], 'percent'), "_", " "));
|
||||
end do:
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
ClearAll[ImportAll]
|
||||
ImportAll[lang_String] :=
|
||||
Module[{data, continue, cmcontinue, extra, xml, next},
|
||||
data = {};
|
||||
continue = True;
|
||||
cmcontinue = "";
|
||||
While[continue,
|
||||
extra = If[cmcontinue =!= "", "&cmcontinue=" <> cmcontinue, ""];
|
||||
xml = Import["http://www.rosettacode.org/w/api.php?action=query&list=categorymembers&cmtitle=Category:" <> lang <> "&cmlimit=500&format=xml" <> extra, "XML"];
|
||||
AppendTo[data, Cases[xml, XMLElement["cm", _, {}], \[Infinity]]];
|
||||
next = Flatten[Cases[xml, {"cmcontinue" -> _}, \[Infinity]]];
|
||||
If[Length[next] > 0,
|
||||
next = First[next];
|
||||
cmcontinue = "cmcontinue" /. next;
|
||||
,
|
||||
continue = False;
|
||||
];
|
||||
];
|
||||
Cases[Flatten[data], HoldPattern["title" -> x_] :> x, \[Infinity]]
|
||||
]
|
||||
Complement[ImportAll["Programming_Tasks"], ImportAll["Mathematica"]]
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
url = "http://rosettacode.org/wiki/Reports:Tasks_not_implemented_in_Mathematica";
|
||||
html = Import[url, "XMLObject"];
|
||||
pos = Position[html, XMLElement["div", {"class" -> "mw-content-ltr", "dir" -> "ltr", "lang" -> "en"}, ___]];
|
||||
pos = First[pos];
|
||||
data = Extract[html, pos];
|
||||
pos = Position[data, XMLElement["li", {}, {XMLElement["a", {"shape" -> "rect", "href" -> _, "title" -> x_}, {x_}]}]];
|
||||
data = Extract[data, pos];
|
||||
data = data[[All, -1, -1, 2]];
|
||||
data = {"title", "href"} /. # & /@ %;
|
||||
data[[All, 2]] = "http://rosettacode.org" <> # & /@ data[[All, 2]];
|
||||
newb = data[[All, 1]];
|
||||
data = Hyperlink @@@ data;
|
||||
data // Column
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
import httpclient, strutils, xmltree, xmlparser, cgi, os
|
||||
|
||||
|
||||
proc findrc(category: string): seq[string] =
|
||||
|
||||
var
|
||||
name = "http://www.rosettacode.org/w/api.php?action=query&list=categorymembers&cmtitle=Category:$#&cmlimit=500&format=xml" % encodeUrl(category)
|
||||
cmcontinue = ""
|
||||
client = newHttpClient()
|
||||
|
||||
while true:
|
||||
var x = client.getContent(name & cmcontinue).parseXml()
|
||||
for node in x.findAll("cm"):
|
||||
result.add node.attr("title")
|
||||
|
||||
cmcontinue.setLen(0)
|
||||
for node in x.findAll("continue"):
|
||||
let u = node.attr("cmcontinue")
|
||||
if u.len != 0: cmcontinue = u.encodeUrl()
|
||||
|
||||
if cmcontinue.len > 0: cmcontinue = "&cmcontinue=" & cmcontinue
|
||||
else: break
|
||||
|
||||
|
||||
proc chooselang(): string =
|
||||
if paramCount() < 1: "Nim" else: paramStr(1)
|
||||
|
||||
|
||||
let alltasks = findrc("Programming_Tasks")
|
||||
let lang = chooselang()
|
||||
let langTasks = lang.findrc()
|
||||
echo "Unimplemented tasks for language ", lang, ':'
|
||||
for task in alltasks:
|
||||
if task notin langTasks:
|
||||
echo " ", task
|
||||
|
|
@ -0,0 +1,127 @@
|
|||
declare
|
||||
[HTTPClient] = {Link ['x-ozlib://mesaros/net/HTTPClient.ozf']}
|
||||
[XMLParser] = {Link ['x-oz://system/xml/Parser.ozf']}
|
||||
|
||||
fun {FindUnimplementedTasks Language}
|
||||
AllTasks = {FindCategory "Programming Tasks"}
|
||||
LangTasks = {FindCategory Language}
|
||||
in
|
||||
{ListDiff AllTasks LangTasks}
|
||||
end
|
||||
|
||||
fun {FindCategory Cat}
|
||||
CatUrl = "http://www.rosettacode.org/mw/api.php?action=query"
|
||||
#"&list=categorymembers"
|
||||
#"&cmtitle=Category:"#{PercentEncode Cat}
|
||||
#"&cmlimit=500&format=xml"
|
||||
|
||||
fun {Loop CMContinue}
|
||||
[_ Doc] = {Parse {GetPage CatUrl#CMContinue}}
|
||||
Titles = {XPath Doc
|
||||
[api query categorymembers cm {Attribute title}]}
|
||||
in
|
||||
case {XPath Doc
|
||||
[api 'query-continue' categorymembers {Attribute cmcontinue}]}
|
||||
of nil then Titles
|
||||
[] [NewCMContinueAtom] then
|
||||
NewCMContinue = {PercentEncode {Atom.toString NewCMContinueAtom}}
|
||||
in
|
||||
{Append Titles
|
||||
{Loop "&cmcontinue="#NewCMContinue}}
|
||||
end
|
||||
end
|
||||
in
|
||||
{Loop nil}
|
||||
end
|
||||
|
||||
|
||||
%% XPath emulation
|
||||
fun {XPath Doc Path}
|
||||
P|Pr = Path
|
||||
in
|
||||
Doc.name = P %% assert
|
||||
{FoldL Pr XPathStep [Doc]}
|
||||
end
|
||||
|
||||
Nothing = {NewName}
|
||||
fun {NotNothing X} X \= Nothing end
|
||||
|
||||
fun {XPathStep Elements P}
|
||||
if {Atom.is P} then
|
||||
{FilteredChildren Elements P}
|
||||
elseif {Procedure.is P} then
|
||||
{Filter {Map Elements P} NotNothing}
|
||||
end
|
||||
end
|
||||
|
||||
%% A flat list of all Type-children of all Elements.
|
||||
fun {FilteredChildren Elements Type}
|
||||
{Flatten
|
||||
{Map Elements
|
||||
fun {$ E}
|
||||
{Filter E.children
|
||||
fun {$ X}
|
||||
case X of element(name:!Type ...) then true
|
||||
else false
|
||||
end
|
||||
end}
|
||||
end}}
|
||||
end
|
||||
|
||||
fun {Attribute Attr}
|
||||
fun {$ Element}
|
||||
case {Filter Element.attributes fun {$ A} A.name == Attr end}
|
||||
of [A] then A.value
|
||||
else Nothing
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
%% GetPage
|
||||
Client = {New HTTPClient.urlGET init(inPrms(toFile:false toStrm:true) _)}
|
||||
fun {GetPage RawUrl}
|
||||
Url = {VirtualString.toString RawUrl}
|
||||
OutParams
|
||||
in
|
||||
{Client getService(Url ?OutParams ?_)}
|
||||
OutParams.sOut
|
||||
end
|
||||
|
||||
fun {PercentEncode Xs}
|
||||
case Xs of nil then nil
|
||||
[] X|Xr then
|
||||
if {Char.isDigit X} orelse {Member X [&- &_ &. &~]}
|
||||
orelse X >= &a andthen X =< &z
|
||||
orelse X >= &z andthen X =< &Z then
|
||||
X|{PercentEncode Xr}
|
||||
else
|
||||
{Append &%|{ToHex2 X} {PercentEncode Xr}}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
fun {ToHex2 X}
|
||||
[{ToHex1 X div 16} {ToHex1 X mod 16}]
|
||||
end
|
||||
|
||||
fun {ToHex1 X}
|
||||
if X >= 0 andthen X =< 9 then &0 + X
|
||||
elseif X >= 10 andthen X =< 15 then &A + X - 10
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
%% Parse
|
||||
local
|
||||
Parser = {New XMLParser.parser init}
|
||||
in
|
||||
fun {Parse Xs} {Parser parseVS(Xs $)} end
|
||||
end
|
||||
|
||||
fun {ListDiff Xs Ys}
|
||||
{FoldL Ys List.subtract Xs}
|
||||
end
|
||||
in
|
||||
%% show tasks not implemented in Oz
|
||||
{ForAll {FindUnimplementedTasks "Oz"} System.showInfo}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
use LWP::UserAgent;
|
||||
|
||||
my $ua = LWP::UserAgent->new;
|
||||
$ua->agent('');
|
||||
|
||||
sub enc { join '', map {sprintf '%%%02x', ord} split //, shift }
|
||||
sub get { $ua->request( HTTP::Request->new( GET => shift))->content }
|
||||
|
||||
sub tasks {
|
||||
my($category) = shift;
|
||||
my $fmt = 'http://www.rosettacode.org/w/api.php?' .
|
||||
'action=query&generator=categorymembers&gcmtitle=Category:%s&gcmlimit=500&format=json&rawcontinue=';
|
||||
my @tasks;
|
||||
my $json = get(sprintf $fmt, $category);
|
||||
while (1) {
|
||||
push @tasks, $json =~ /"title":"(.+?)"\}/g;
|
||||
$json =~ /"gcmcontinue":"(.+?)"\}/ or last;
|
||||
$json = get(sprintf $fmt . '&gcmcontinue=%s', $category, enc $1);
|
||||
}
|
||||
@tasks;
|
||||
}
|
||||
|
||||
my %language = map {$_, 1} tasks shift || 'perl';
|
||||
$language{$_} or print "$_\n" foreach tasks('Programming_Tasks'), tasks('Draft_Programming_Tasks');
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
(notonline)-->
|
||||
<span style="color: #000080;font-style:italic;">-- demo\rosetta\Find_unimplemented_tasks.exw</span>
|
||||
<span style="color: #008080;">without</span> <span style="color: #008080;">js</span> <span style="color: #000080;font-style:italic;">-- (libcurl, file i/o, peek, progress..)</span>
|
||||
<span style="color: #008080;">constant</span> <span style="color: #000000;">language</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"Phix"</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000080;font-style:italic;">-- language = "Go",
|
||||
-- language = "Julia",
|
||||
-- language = "Python",
|
||||
-- language = "Wren",</span>
|
||||
<span style="color: #000000;">base_query</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"http://rosettacode.org/mw/api.php?action=query"</span><span style="color: #0000FF;">&</span>
|
||||
<span style="color: #008000;">"&format=xml&list=categorymembers&cmlimit=100"</span>
|
||||
|
||||
<span style="color: #008080;">include</span> <span style="color: #000000;">builtins</span><span style="color: #0000FF;">\</span><span style="color: #000000;">libcurl</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
|
||||
<span style="color: #004080;">atom</span> <span style="color: #000000;">curl</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">NULL</span>
|
||||
<span style="color: #004080;">atom</span> <span style="color: #000000;">pErrorBuffer</span>
|
||||
<span style="color: #008080;">include</span> <span style="color: #000000;">builtins</span><span style="color: #0000FF;">\</span><span style="color: #000000;">xml</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">req</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">url</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">rid</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">curl</span><span style="color: #0000FF;">=</span><span style="color: #004600;">NULL</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #7060A8;">curl_global_init</span><span style="color: #0000FF;">()</span>
|
||||
<span style="color: #000000;">curl</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">curl_easy_init</span><span style="color: #0000FF;">()</span>
|
||||
<span style="color: #000000;">pErrorBuffer</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">allocate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">CURL_ERROR_SIZE</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #7060A8;">curl_easy_setopt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">curl</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">CURLOPT_ERRORBUFFER</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">pErrorBuffer</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #7060A8;">curl_easy_setopt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">curl</span><span style="color: #0000FF;">,</span> <span style="color: #004600;">CURLOPT_URL</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">url</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">object</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">curl_easy_perform_ex</span><span style="color: #0000FF;">(</span><span style="color: #000000;">curl</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #004080;">integer</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #004080;">string</span> <span style="color: #000000;">error</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"%d [%s]"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">peek_string</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pErrorBuffer</span><span style="color: #0000FF;">)})</span>
|
||||
<span style="color: #7060A8;">crash</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Download error: %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">error</span><span style="color: #0000FF;">})</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #004080;">string</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">9</span><span style="color: #0000FF;">/</span><span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #004080;">object</span> <span style="color: #000000;">xml</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">xml_parse</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">)[</span><span style="color: #000000;">XML_CONTENTS</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">xml_get_nodes</span><span style="color: #0000FF;">(</span><span style="color: #000000;">xml</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"continue"</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">=={}?</span><span style="color: #008000;">""</span><span style="color: #0000FF;">:</span><span style="color: #000000;">xml_get_attribute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">],</span><span style="color: #008000;">"cmcontinue"</span><span style="color: #0000FF;">))</span>
|
||||
<span style="color: #000000;">xml</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">xml_get_nodes</span><span style="color: #0000FF;">(</span><span style="color: #000000;">xml</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"query"</span><span style="color: #0000FF;">)[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #000000;">xml</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">xml_get_nodes</span><span style="color: #0000FF;">(</span><span style="color: #000000;">xml</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"categorymembers"</span><span style="color: #0000FF;">)[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #000000;">xml</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">xml_get_nodes</span><span style="color: #0000FF;">(</span><span style="color: #000000;">xml</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"cm"</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">xml</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #7060A8;">call_proc</span><span style="color: #0000FF;">(</span><span style="color: #000000;">rid</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">xml_get_attribute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">xml</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #008000;">"title"</span><span style="color: #0000FF;">)})</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">html_clean</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">ri</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">ri</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">substitute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ri</span><span style="color: #0000FF;">,</span><span style="color: #008000;">`"`</span><span style="color: #0000FF;">,</span><span style="color: #008000;">`"`</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">ri</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">substitute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ri</span><span style="color: #0000FF;">,</span><span style="color: #008000;">`'`</span><span style="color: #0000FF;">,</span><span style="color: #008000;">`'`</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">ri</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">substitute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ri</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\xE2\x80\x99"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"'"</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">ri</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">substitute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ri</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\xC3\xB6"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"o"</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">ri</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">substitute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ri</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%3A"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">":"</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">ri</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">substitute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ri</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%E2%80%93"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"-"</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">ri</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">substitute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ri</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%E2%80%99"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"'"</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">ri</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">substitute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ri</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%27"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"'"</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">ri</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">substitute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ri</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%2B"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"+"</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">ri</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">substitute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ri</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%C3%A8"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"e"</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">ri</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">substitute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ri</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%C3%A9"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"e"</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">ri</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">substitute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ri</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%C3%B6"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"o"</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">ri</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">substitute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ri</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%C5%91"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"o"</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">ri</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">substitute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ri</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%22"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">`"`</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">ri</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">substitute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ri</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%2A"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"*"</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">ri</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">titles</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
|
||||
<span style="color: #008080;">procedure</span> <span style="color: #000000;">store_title</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">title</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">titles</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">titles</span><span style="color: #0000FF;">,</span><span style="color: #000000;">title</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
|
||||
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">unimplemented_count</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">task_count</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
|
||||
<span style="color: #008080;">procedure</span> <span style="color: #000000;">print_unimplemented</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">title</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">title</span><span style="color: #0000FF;">,</span><span style="color: #000000;">titles</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #000000;">title</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">html_clean</span><span style="color: #0000FF;">(</span><span style="color: #000000;">title</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">title</span><span style="color: #0000FF;">})</span>
|
||||
<span style="color: #000000;">unimplemented_count</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #000000;">task_count</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
|
||||
|
||||
<span style="color: #008080;">procedure</span> <span style="color: #000000;">main</span><span style="color: #0000FF;">()</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Loading implemented tasks list...\n"</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000080;font-style:italic;">-- get and store task itles</span>
|
||||
<span style="color: #004080;">string</span> <span style="color: #000000;">lang_query</span> <span style="color: #0000FF;">:=</span> <span style="color: #000000;">base_query</span> <span style="color: #0000FF;">&</span> <span style="color: #008000;">"&cmtitle=Category:"</span> <span style="color: #0000FF;">&</span> <span style="color: #000000;">language</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">continue_at</span> <span style="color: #0000FF;">:=</span> <span style="color: #000000;">req</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lang_query</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">store_title</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">while</span> <span style="color: #000000;">continue_at</span><span style="color: #0000FF;">!=</span><span style="color: #008000;">""</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #000000;">continue_at</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">req</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lang_query</span><span style="color: #0000FF;">&</span><span style="color: #008000;">"&cmcontinue="</span><span style="color: #0000FF;">&</span><span style="color: #000000;">continue_at</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">store_title</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
|
||||
|
||||
<span style="color: #000080;font-style:italic;">-- a quick check to avoid long output</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">titles</span><span style="color: #0000FF;">)==</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"no tasks implemented for %s\n"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">language</span><span style="color: #0000FF;">})</span>
|
||||
<span style="color: #008080;">return</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
|
||||
<span style="color: #000080;font-style:italic;">-- get tasks, print as we go along</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Tasks:\n"</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">string</span> <span style="color: #000000;">task_query</span> <span style="color: #0000FF;">:=</span> <span style="color: #000000;">base_query</span> <span style="color: #0000FF;">&</span> <span style="color: #008000;">"&cmtitle=Category:Programming_Tasks"</span>
|
||||
<span style="color: #000000;">continue_at</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">req</span><span style="color: #0000FF;">(</span><span style="color: #000000;">task_query</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">print_unimplemented</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">while</span> <span style="color: #000000;">continue_at</span><span style="color: #0000FF;">!=</span><span style="color: #008000;">""</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #000000;">continue_at</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">req</span><span style="color: #0000FF;">(</span><span style="color: #000000;">task_query</span><span style="color: #0000FF;">&</span><span style="color: #008000;">"&cmcontinue="</span><span style="color: #0000FF;">&</span><span style="color: #000000;">continue_at</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">print_unimplemented</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%d unimplemented tasks found for %s.\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">unimplemented_count</span><span style="color: #0000FF;">,</span><span style="color: #000000;">language</span><span style="color: #0000FF;">})</span>
|
||||
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">full_tasks</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">unimplemented_count</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Draft tasks:\n"</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">task_query</span> <span style="color: #0000FF;">:=</span> <span style="color: #000000;">base_query</span> <span style="color: #0000FF;">&</span> <span style="color: #008000;">"&cmtitle=Category:Draft_Programming_Tasks"</span>
|
||||
<span style="color: #000000;">continue_at</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">req</span><span style="color: #0000FF;">(</span><span style="color: #000000;">task_query</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">print_unimplemented</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">while</span> <span style="color: #000000;">continue_at</span><span style="color: #0000FF;">!=</span><span style="color: #008000;">""</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #000000;">continue_at</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">req</span><span style="color: #0000FF;">(</span><span style="color: #000000;">task_query</span><span style="color: #0000FF;">&</span><span style="color: #008000;">"&cmcontinue="</span><span style="color: #0000FF;">&</span><span style="color: #000000;">continue_at</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">print_unimplemented</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">draft_tasks</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">unimplemented_count</span><span style="color: #0000FF;">-</span><span style="color: #000000;">full_tasks</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%d unimplemented draft tasks found for %s.\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">draft_tasks</span><span style="color: #0000FF;">,</span><span style="color: #000000;">language</span><span style="color: #0000FF;">})</span>
|
||||
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%d unimplemented tasks in total found for %s (out of %d).\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">unimplemented_count</span><span style="color: #0000FF;">,</span><span style="color: #000000;">language</span><span style="color: #0000FF;">,</span><span style="color: #000000;">task_count</span><span style="color: #0000FF;">})</span>
|
||||
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
|
||||
<span style="color: #000000;">main</span><span style="color: #0000FF;">()</span>
|
||||
<!--
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
(load "@lib/http.l" "@lib/xm.l")
|
||||
|
||||
(de rosettaCategory (Cat)
|
||||
(let (Cont NIL Xml)
|
||||
(make
|
||||
(loop
|
||||
(client "rosettacode.org" 80
|
||||
(pack
|
||||
"mw/api.php?action=query&list=categorymembers&cmtitle=Category:"
|
||||
Cat
|
||||
"&cmlimit=200&format=xml"
|
||||
Cont )
|
||||
(while (line))
|
||||
(setq Xml (and (xml?) (xml))) )
|
||||
(NIL Xml)
|
||||
(for M (body Xml 'query 'categorymembers)
|
||||
(link (attr M 'title)) )
|
||||
(NIL (attr Xml 'query-continue' categorymembers 'cmcontinue))
|
||||
(setq Cont (pack "&cmcontinue=" @)) ) ) ) )
|
||||
|
||||
(de unimplemented (Task)
|
||||
(diff
|
||||
(rosettaCategory "Programming_Tasks")
|
||||
(rosettaCategory Task) ) )
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
function Find-UnimplementedTask
|
||||
{
|
||||
[CmdletBinding()]
|
||||
[OutputType([string[]])]
|
||||
Param
|
||||
(
|
||||
[Parameter(Mandatory=$true,
|
||||
Position=0)]
|
||||
[string]
|
||||
$Language
|
||||
)
|
||||
|
||||
$url = "http://rosettacode.org/wiki/Reports:Tasks_not_implemented_in_$Language"
|
||||
$web = Invoke-WebRequest $url
|
||||
$unimplemented = 1
|
||||
|
||||
[string[]](($web.AllElements |
|
||||
Where-Object {$_.class -eq "mw-content-ltr"})[$unimplemented].outerText -split "`r`n" |
|
||||
Select-String -Pattern "[^0-9A-Z]$" -CaseSensitive)
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
$tasks = Find-UnimplementedTask -Language PowerShell
|
||||
|
||||
$tasks[0..5],".`n.`n.",$tasks[-6..-1]
|
||||
Write-Host "`nTotal unimplemented Tasks: $($tasks.Count)"
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
"""
|
||||
Given the name of a language on Rosetta Code,
|
||||
finds all tasks which are not implemented in that language.
|
||||
"""
|
||||
from operator import attrgetter
|
||||
from typing import Iterator
|
||||
|
||||
import mwclient
|
||||
|
||||
URL = 'www.rosettacode.org'
|
||||
API_PATH = '/mw/'
|
||||
|
||||
|
||||
def unimplemented_tasks(language: str,
|
||||
*,
|
||||
url: str,
|
||||
api_path: str) -> Iterator[str]:
|
||||
"""Yields all unimplemented tasks for a specified language"""
|
||||
site = mwclient.Site(url, path=api_path)
|
||||
all_tasks = site.categories['Programming Tasks']
|
||||
language_tasks = site.categories[language]
|
||||
name = attrgetter('name')
|
||||
all_tasks_names = map(name, all_tasks)
|
||||
language_tasks_names = set(map(name, language_tasks))
|
||||
for task in all_tasks_names:
|
||||
if task not in language_tasks_names:
|
||||
yield task
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
tasks = unimplemented_tasks('Python', url=URL, api_path=API_PATH)
|
||||
print(*tasks, sep='\n')
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
"""
|
||||
Given the name of a language on Rosetta Code,
|
||||
finds all tasks which are not implemented in that language.
|
||||
"""
|
||||
from functools import partial
|
||||
from operator import itemgetter
|
||||
from typing import (Dict,
|
||||
Iterator,
|
||||
Union)
|
||||
|
||||
import requests
|
||||
|
||||
URL = 'http://www.rosettacode.org/mw/api.php'
|
||||
REQUEST_PARAMETERS = dict(action='query',
|
||||
list='categorymembers',
|
||||
cmlimit=500,
|
||||
rawcontinue=True,
|
||||
format='json')
|
||||
|
||||
|
||||
def unimplemented_tasks(language: str,
|
||||
*,
|
||||
url: str,
|
||||
request_params: Dict[str, Union[str, int, bool]]
|
||||
) -> Iterator[str]:
|
||||
"""Yields all unimplemented tasks for a specified language"""
|
||||
with requests.Session() as session:
|
||||
tasks = partial(tasks_titles,
|
||||
session=session,
|
||||
url=url,
|
||||
**request_params)
|
||||
all_tasks = tasks(cmtitle='Category:Programming_Tasks')
|
||||
language_tasks = set(tasks(cmtitle=f'Category:{language}'))
|
||||
for task in all_tasks:
|
||||
if task not in language_tasks:
|
||||
yield task
|
||||
|
||||
|
||||
def tasks_titles(*,
|
||||
session: requests.Session,
|
||||
url: str,
|
||||
**params: Union[str, int, bool]) -> Iterator[str]:
|
||||
"""Yields tasks names for a specified category"""
|
||||
while True:
|
||||
request = session.get(url, params=params)
|
||||
data = request.json()
|
||||
yield from map(itemgetter('title'), data['query']['categorymembers'])
|
||||
query_continue = data.get('query-continue')
|
||||
if query_continue is None:
|
||||
return
|
||||
params.update(query_continue['categorymembers'])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
tasks = unimplemented_tasks('Python',
|
||||
url=URL,
|
||||
request_params=REQUEST_PARAMETERS)
|
||||
print(*tasks, sep='\n')
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
import xml.dom.minidom
|
||||
import urllib, sys
|
||||
|
||||
def findrc(category):
|
||||
name = "http://www.rosettacode.org/w/api.php?action=query&list=categorymembers&cmtitle=Category:%s&cmlimit=500&format=xml" % urllib.quote(category)
|
||||
cmcontinue, titles = '', []
|
||||
while True:
|
||||
u = urllib.urlopen(name + cmcontinue)
|
||||
xmldata = u.read()
|
||||
u.close()
|
||||
x = xml.dom.minidom.parseString(xmldata)
|
||||
titles += [i.getAttribute("title") for i in x.getElementsByTagName("cm")]
|
||||
cmcontinue = filter( None,
|
||||
(urllib.quote(i.getAttribute("cmcontinue"))
|
||||
for i in x.getElementsByTagName("categorymembers")) )
|
||||
if cmcontinue:
|
||||
cmcontinue = '&cmcontinue=' + cmcontinue[0]
|
||||
else:
|
||||
break
|
||||
return titles
|
||||
|
||||
alltasks = findrc("Programming_Tasks")
|
||||
lang = findrc(sys.argv[1])
|
||||
|
||||
for i in [i for i in alltasks if i not in lang]:
|
||||
print i
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
#Aamrun, 3rd February 2023
|
||||
|
||||
import xml.dom.minidom
|
||||
import sys, urllib.parse, urllib.request
|
||||
|
||||
def findrc(category):
|
||||
name = "http://www.rosettacode.org/w/api.php?action=query&list=categorymembers&cmtitle=Category:%s&cmlimit=500&format=xml" % urllib.parse.quote(category)
|
||||
cmcontinue, titles = '', []
|
||||
while True:
|
||||
u = urllib.request.urlopen(name + cmcontinue)
|
||||
xmldata = u.read()
|
||||
u.close()
|
||||
x = xml.dom.minidom.parseString(xmldata)
|
||||
titles += [i.getAttribute("title") for i in x.getElementsByTagName("cm")]
|
||||
cmcontinue = list(filter( None,
|
||||
(urllib.parse.quote(i.getAttribute("cmcontinue"))
|
||||
for i in x.getElementsByTagName("categorymembers")) ))
|
||||
if cmcontinue:
|
||||
cmcontinue = '&cmcontinue=' + cmcontinue[0]
|
||||
else:
|
||||
break
|
||||
return titles
|
||||
|
||||
alltasks = findrc("Programming_Tasks")
|
||||
lang = findrc(sys.argv[1])
|
||||
|
||||
for i in [i for i in alltasks if i not in lang]:
|
||||
print(i)
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
library(XML)
|
||||
find.unimplemented.tasks <- function(lang="R"){
|
||||
PT <- xmlInternalTreeParse( paste("http://www.rosettacode.org/w/api.php?action=query&list=categorymembers&cmtitle=Category:Programming_Tasks&cmlimit=500&format=xml",sep="") )
|
||||
PT.nodes <- getNodeSet(PT,"//cm")
|
||||
PT.titles = as.character( sapply(PT.nodes, xmlGetAttr, "title") )
|
||||
language <- xmlInternalTreeParse( paste("http://www.rosettacode.org/w/api.php?action=query&list=categorymembers&cmtitle=Category:",
|
||||
lang, "&cmlimit=500&format=xml",sep="") )
|
||||
lang.nodes <- getNodeSet(language,"//cm")
|
||||
lang.titles = as.character( sapply(lang.nodes, xmlGetAttr, "title") )
|
||||
unimplemented <- setdiff(PT.titles, lang.titles)
|
||||
unimplemented
|
||||
}
|
||||
# Usage
|
||||
find.unimplemented.tasks(lang="Python")
|
||||
langs <- c("R","python","perl")
|
||||
sapply(langs, find.unimplemented.tasks) # fetching data for multiple languages
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
#lang racket
|
||||
|
||||
(require net/url net/uri-codec json (only-in racket/dict [dict-ref ref]))
|
||||
|
||||
(define (RC-get verb params)
|
||||
((compose1 get-pure-port string->url format)
|
||||
"http://rosettacode.org/mw/~a.php?~a" verb (alist->form-urlencoded params)))
|
||||
|
||||
(define (get-category catname)
|
||||
(let loop ([c #f])
|
||||
(define t
|
||||
((compose1 read-json RC-get) 'api
|
||||
`([action . "query"] [format . "json"]
|
||||
[list . "categorymembers"] [cmtitle . ,(format "Category:~a" catname)]
|
||||
[cmcontinue . ,(and c (ref c 'cmcontinue))] [cmlimit . "500"])))
|
||||
(define (c-m key) (ref (ref t key '()) 'categorymembers #f))
|
||||
(append (for/list ([page (c-m 'query)]) (ref page 'title))
|
||||
(cond [(c-m 'query-continue) => loop] [else '()]))))
|
||||
|
||||
;; The above is the required "library" code, same as the "Rosetta
|
||||
;; Code/Count" entry
|
||||
|
||||
(define (show-unimplemented lang)
|
||||
(for-each displayln (remove* (get-category lang)
|
||||
(get-category 'Programming_Tasks))))
|
||||
|
||||
(show-unimplemented 'Racket) ; see all of the Racket entries
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
use HTTP::UserAgent;
|
||||
use URI::Escape;
|
||||
use JSON::Fast;
|
||||
use Sort::Naturally;
|
||||
|
||||
unit sub MAIN( Str :$lang = 'Raku' );
|
||||
|
||||
my $client = HTTP::UserAgent.new;
|
||||
my $url = 'https://rosettacode.org/w';
|
||||
|
||||
my @total;
|
||||
my @impl;
|
||||
|
||||
@total.append: .&get-cat for 'Programming_Tasks', 'Draft_Programming_Tasks';
|
||||
@impl = get-cat $lang;
|
||||
|
||||
say "Unimplemented tasks in $lang:";
|
||||
my @unimplemented = (@total (-) @impl).keys.sort: *.&naturally;
|
||||
.say for @unimplemented;
|
||||
say "{+@unimplemented} unimplemented tasks";
|
||||
|
||||
sub get-cat ($category) {
|
||||
flat mediawiki-query(
|
||||
$url, 'pages',
|
||||
:generator<categorymembers>,
|
||||
:gcmtitle("Category:$category"),
|
||||
:gcmlimit<350>,
|
||||
:rawcontinue(),
|
||||
:prop<title>
|
||||
).map({ .<title> });
|
||||
}
|
||||
|
||||
sub mediawiki-query ($site, $type, *%query) {
|
||||
my $url = "$site/api.php?" ~ uri-query-string(
|
||||
:action<query>, :format<json>, :formatversion<2>, |%query);
|
||||
my $continue = '';
|
||||
|
||||
gather loop {
|
||||
my $response = $client.get("$url&$continue");
|
||||
my $data = from-json($response.content);
|
||||
take $_ for $data.<query>.{$type}.values;
|
||||
$continue = uri-query-string |($data.<query-continue>{*}».hash.hash or last);
|
||||
}
|
||||
}
|
||||
|
||||
sub uri-query-string (*%fields) { %fields.map({ "{.key}={uri-escape .value}" }).join("&") }
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
# Project: Rosetta Code/Find unimplemented tasks
|
||||
|
||||
load "stdlib.ring"
|
||||
ros= download("http://rosettacode.org/wiki/Category:Programming_Tasks")
|
||||
lang = "Ring"
|
||||
pos = 1
|
||||
num = 0
|
||||
totalros = 0
|
||||
rosname = ""
|
||||
rostitle = ""
|
||||
see "Tasks not implemented in " + lang + " language:" + nl
|
||||
for n = 1 to len(ros)
|
||||
nr = searchstring(ros,'<li><a href="/wiki/',pos)
|
||||
if nr = 0
|
||||
exit
|
||||
else
|
||||
pos = nr + 1
|
||||
ok
|
||||
nr = searchname(nr)
|
||||
nr = searchtitle(nr)
|
||||
next
|
||||
see nl
|
||||
see "Total: " + totalros + " examples." + nl
|
||||
|
||||
func searchstring(str,substr,n)
|
||||
newstr=right(str,len(str)-n+1)
|
||||
nr = substr(newstr, substr)
|
||||
if nr = 0
|
||||
return 0
|
||||
else
|
||||
return n + nr -1
|
||||
ok
|
||||
|
||||
func searchname(sn)
|
||||
nr2 = searchstring(ros,'">',sn)
|
||||
nr3 = searchstring(ros,"</a></li>",sn)
|
||||
rosname = substr(ros,nr2+2,nr3-nr2-2)
|
||||
return sn
|
||||
|
||||
func searchtitle(sn)
|
||||
st = searchstring(ros,"title=",sn)
|
||||
rostitle = substr(ros,sn+19,st-sn-21)
|
||||
rostitle = "rosettacode.org/wiki/" + rostitle
|
||||
rostitle = download(rostitle)
|
||||
s = substr(rostitle,lang)
|
||||
if s = 0
|
||||
num = num + 1
|
||||
totalros = totalros + 1
|
||||
see "" + num + ". " + rosname + nl
|
||||
ok
|
||||
return sn
|
||||
|
||||
func count(cstring,dstring)
|
||||
sum = 0
|
||||
while substr(cstring,dstring) > 0
|
||||
sum = sum + 1
|
||||
cstring = substr(cstring,substr(cstring,dstring)+len(string(sum)))
|
||||
end
|
||||
return sum
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
require 'rosettacode'
|
||||
require 'time'
|
||||
|
||||
module RosettaCode
|
||||
def self.get_unimplemented(lang)
|
||||
programming_tasks = []
|
||||
category_members("Programming_Tasks") {|task| programming_tasks << task}
|
||||
|
||||
lang_tasks = []
|
||||
category_members(lang) {|task| lang_tasks << task}
|
||||
|
||||
lang_tasks_omit = []
|
||||
category_members("#{lang}/Omit") {|task| lang_tasks_omit << task}
|
||||
|
||||
[programming_tasks - lang_tasks, lang_tasks_omit]
|
||||
end
|
||||
|
||||
def self.created_time(title)
|
||||
url = get_api_url({
|
||||
"action" => "query",
|
||||
"titles" => title,
|
||||
"format" => "xml",
|
||||
"rvlimit" => 500,
|
||||
"prop" => "revisions",
|
||||
"rvprop" => "timestamp"
|
||||
})
|
||||
doc = REXML::Document.new open(url)
|
||||
REXML::XPath.each(doc, "//rev").collect do |node|
|
||||
Time.parse( node.attribute("timestamp").value )
|
||||
end.min
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
puts Time.now
|
||||
lang = ARGV[0] || "Ruby"
|
||||
unimplemented, omitted = RosettaCode.get_unimplemented(lang)
|
||||
unimplemented.collect {|title| [title, RosettaCode.created_time(title)]} .
|
||||
sort_by {|e| e[1]} .
|
||||
each do |title, date|
|
||||
puts "%s %6s %s" % [
|
||||
date.strftime("%Y-%m-%d"),
|
||||
omitted.include?(title) ? "[omit]" : "" ,
|
||||
title
|
||||
]
|
||||
end
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
WordWrap$ = "style='white-space: pre-wrap;white-space: -moz-pre-wrap;white-space: -pre-wrap;white-space: -o-pre-wrap;word-wrap: break-word'"
|
||||
a$ = httpGet$("http://rosettacode.org/wiki/Category:Programming_Languages")
|
||||
a$ = word$(a$,2,"mw-subcategories")
|
||||
a$ = word$(a$,1,"</table>")
|
||||
i = instr(a$,"/wiki/Category:")
|
||||
html "<B> Select language from list<BR>"
|
||||
html "<SELECT name='lang'>"
|
||||
while i <> 0
|
||||
j = instr(a$,""" title=""Category:",i)
|
||||
lang$ = mid$(a$,i+15,j-i-15)
|
||||
k = instr(a$,""">",j + 18)
|
||||
langName$ = mid$(a$,j + 18,k-(j+18))
|
||||
count = count + 1
|
||||
html "<option value='";lang$;"'>";langName$;"</option>"
|
||||
i = instr(a$,"/wiki/Category:",k)
|
||||
wend
|
||||
html "</select>"
|
||||
html "<p>Number of Languages:";count;"<BR> "
|
||||
button #go,"GO", [go]
|
||||
html " "
|
||||
button #ex, "Exit", [exit]
|
||||
wait
|
||||
|
||||
[go]
|
||||
cls
|
||||
lang$ = #request get$("lang")
|
||||
h$ = "http://rosettacode.org/wiki/Reports:Tasks_not_implemented_in_";lang$
|
||||
a$ = httpGet$(h$)
|
||||
a$ = word$(a$,3,"mw-content-ltr")
|
||||
html "<table border=1><tr>"
|
||||
i = instr(a$,"<a href=""/wiki/")
|
||||
while i > 0
|
||||
i = instr(a$,"title=""",i)
|
||||
j = instr(a$,""">",i+7)
|
||||
if c mod 4 = 0 then html "</tr><tr ";WordWrap$;">"
|
||||
c = c + 1
|
||||
html "<td>";mid$(a$,i+7,j-(i+7));"</td>"
|
||||
i = instr(a$,"<a href=""/wiki/",i+7)
|
||||
wend
|
||||
html "</tr></table>"
|
||||
print "Total unImplemented Tasks:";c
|
||||
[exit]
|
||||
end
|
||||
|
|
@ -0,0 +1,141 @@
|
|||
use std::collections::{BTreeMap, HashSet};
|
||||
|
||||
use reqwest::Url;
|
||||
use serde::Deserialize;
|
||||
use serde_json::Value;
|
||||
|
||||
/// A Rosetta Code task.
|
||||
#[derive(Clone, PartialEq, Eq, Hash, Debug, Deserialize)]
|
||||
pub struct Task {
|
||||
/// The ID of the page containing the task in the MediaWiki API.
|
||||
#[serde(rename = "pageid")]
|
||||
pub id: u64,
|
||||
|
||||
/// The human-readable title of the task.
|
||||
pub title: String,
|
||||
}
|
||||
|
||||
/// Encapsulates errors that might occur during JSON parsing.
|
||||
#[derive(Debug)]
|
||||
enum TaskParseError {
|
||||
/// Something went wrong with the HTTP request to the API.
|
||||
Http(reqwest::Error),
|
||||
|
||||
/// There was a problem parsing the API response into JSON.
|
||||
Json(serde_json::Error),
|
||||
|
||||
/// The response JSON contained unexpected keys or values.
|
||||
UnexpectedFormat,
|
||||
}
|
||||
|
||||
impl From<serde_json::Error> for TaskParseError {
|
||||
fn from(err: serde_json::Error) -> Self {
|
||||
TaskParseError::Json(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<reqwest::Error> for TaskParseError {
|
||||
fn from(err: reqwest::Error) -> Self {
|
||||
TaskParseError::Http(err)
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents a category of pages on Rosetta Code, such as "Rust".
|
||||
struct Category {
|
||||
name: String,
|
||||
continue_params: Option<BTreeMap<String, String>>,
|
||||
}
|
||||
|
||||
impl Category {
|
||||
fn new(name: &str) -> Category {
|
||||
let mut continue_params = BTreeMap::new();
|
||||
continue_params.insert("continue".to_owned(), "".to_owned());
|
||||
|
||||
Category {
|
||||
name: name.to_owned(),
|
||||
continue_params: Some(continue_params),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Sends a request to Rosetta Code through the MediaWiki API. If successful, returns the response
|
||||
/// as a JSON object.
|
||||
fn query_api(
|
||||
category_name: &str,
|
||||
continue_params: &BTreeMap<String, String>,
|
||||
) -> Result<Value, TaskParseError> {
|
||||
let mut url = Url::parse("http://rosettacode.org/mw/api.php").expect("invalid URL");
|
||||
url.query_pairs_mut()
|
||||
.append_pair("action", "query")
|
||||
.append_pair("list", "categorymembers")
|
||||
.append_pair("cmtitle", &format!("Category:{}", category_name))
|
||||
.append_pair("cmlimit", "500")
|
||||
.append_pair("format", "json")
|
||||
.extend_pairs(continue_params);
|
||||
|
||||
Ok(reqwest::blocking::get(url)?.json()?)
|
||||
}
|
||||
|
||||
/// Given a JSON object, parses the task information from the MediaWiki API response.
|
||||
fn parse_tasks(json: &Value) -> Result<Vec<Task>, TaskParseError> {
|
||||
let tasks_json = json
|
||||
.pointer("/query/categorymembers")
|
||||
.and_then(Value::as_array)
|
||||
.ok_or(TaskParseError::UnexpectedFormat)?;
|
||||
|
||||
tasks_json
|
||||
.iter()
|
||||
.map(|json| Task::deserialize(json).map_err(From::from))
|
||||
.collect()
|
||||
}
|
||||
|
||||
impl Iterator for Category {
|
||||
type Item = Vec<Task>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
self.continue_params.as_ref()?;
|
||||
|
||||
query_api(&self.name, self.continue_params.as_ref()?)
|
||||
.and_then(|result| {
|
||||
// If there are more pages of results to request, save them for the next iteration.
|
||||
self.continue_params =
|
||||
result
|
||||
.get("continue")
|
||||
.and_then(Value::as_object)
|
||||
.map(|continue_params| {
|
||||
continue_params
|
||||
.iter()
|
||||
.map(|(key, value)| {
|
||||
(key.to_owned(), value.as_str().unwrap().to_owned())
|
||||
})
|
||||
.collect()
|
||||
});
|
||||
|
||||
parse_tasks(&result)
|
||||
})
|
||||
.map_err(|err| println!("Error parsing response: {:?}", err))
|
||||
.ok()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn all_tasks() -> Vec<Task> {
|
||||
Category::new("Programming Tasks").flatten().collect()
|
||||
}
|
||||
|
||||
pub fn unimplemented_tasks(lang: &str) -> Vec<Task> {
|
||||
let all_tasks = all_tasks().iter().cloned().collect::<HashSet<_>>();
|
||||
let implemented_tasks = Category::new(lang).flatten().collect::<HashSet<_>>();
|
||||
let mut unimplemented_tasks = all_tasks
|
||||
.difference(&implemented_tasks)
|
||||
.cloned()
|
||||
.collect::<Vec<Task>>();
|
||||
unimplemented_tasks.sort_by(|a, b| a.title.cmp(&b.title));
|
||||
unimplemented_tasks
|
||||
}
|
||||
|
||||
|
||||
fn main() {
|
||||
for task in find_unimplemented_tasks::unimplemented_tasks("Rust") {
|
||||
println!("{:6} {}", task.id, task.title);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
import com.softwaremill.sttp.json4s._
|
||||
import com.softwaremill.sttp.quick._
|
||||
|
||||
implicit val serialization = org.json4s.native.Serialization
|
||||
import org.json4s.DefaultFormats
|
||||
implicit val formats = DefaultFormats
|
||||
|
||||
case class Task(pageid: Int, title: String)
|
||||
case class Category(categorymembers: List[Task])
|
||||
case class Query(query: Category)
|
||||
|
||||
List("Programming Tasks", "Scala")
|
||||
.map { title =>
|
||||
sttp
|
||||
.get(uri"http://www.rosettacode.org/mw/api.php?action=query&list=categorymembers&cmtitle=Category:${title}&cmlimit=1000&format=json")
|
||||
.header("User-Agent", mozillaUserAgent)
|
||||
.response(asJson[Query])
|
||||
.send()
|
||||
.body
|
||||
}
|
||||
.map {
|
||||
case Right(r) => r.query.categorymembers.toSet
|
||||
case Left(s) => Set.empty[Task]
|
||||
}
|
||||
.foldRight(Set.empty[Task])((acc: Set[Task], ele: Set[Task]) => acc -- ele)
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
package require Tcl 8.5
|
||||
package require http
|
||||
package require json
|
||||
package require struct::set
|
||||
|
||||
fconfigure stdout -buffering none
|
||||
|
||||
# Initialize a cache of lookups
|
||||
array set cache {}
|
||||
proc log msg {
|
||||
#puts -nonewline $msg
|
||||
}
|
||||
|
||||
proc get_tasks {category} {
|
||||
global cache
|
||||
if {[info exists cache($category)]} {
|
||||
return $cache($category)
|
||||
}
|
||||
set base_url http://www.rosettacode.org/mw/api.php
|
||||
set query {
|
||||
action query
|
||||
list categorymembers
|
||||
cmtitle Category:%s
|
||||
format json
|
||||
cmlimit 500
|
||||
}
|
||||
set query [list {*}$query]; # remove excess whitespace
|
||||
set this_query [dict create {*}[split [format $query $category]]]
|
||||
set tasks [list]
|
||||
|
||||
while {1} {
|
||||
set url [join [list $base_url [http::formatQuery {*}$this_query]] ?]
|
||||
while 1 {
|
||||
set response [http::geturl $url]
|
||||
# Process redirects
|
||||
if {[http::ncode $response] == 301} {
|
||||
set newurl [dict get [http::meta $response] Location]
|
||||
if {[string match http://* $newurl]} {
|
||||
set url $newurl
|
||||
} else {
|
||||
set url [regexp -inline {http://[^/]+} $url]
|
||||
append url $newurl
|
||||
}
|
||||
continue
|
||||
}
|
||||
# Check for oopsies!
|
||||
if {
|
||||
[set s [http::status $response]] ne "ok"
|
||||
|| [http::ncode $response] != 200
|
||||
} then {
|
||||
error "Oops: url=$url\nstatus=$s\nhttp code=[http::code $response]"
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
# Get the data out of the message
|
||||
set data [json::json2dict [http::data $response]]
|
||||
http::cleanup $response
|
||||
|
||||
# add tasks to list
|
||||
foreach task [dict get $data query categorymembers] {
|
||||
lappend tasks [dict get [dict create {*}$task] title]
|
||||
}
|
||||
|
||||
if {[catch {
|
||||
dict get $data query-continue categorymembers cmcontinue
|
||||
} continue_task]} then {
|
||||
# no more continuations, we're done
|
||||
break
|
||||
}
|
||||
dict set this_query cmcontinue $continue_task
|
||||
}
|
||||
return [set cache($category) $tasks]
|
||||
}
|
||||
|
||||
proc get_unimplemented {lang} {
|
||||
set tasks [get_tasks Programming_Tasks]
|
||||
set collected [get_tasks Collection_Members]
|
||||
set doneTasks [get_tasks $lang]
|
||||
set omittedTasks [get_tasks $lang/Omit]
|
||||
|
||||
# Map generic collection task categories to specific ones
|
||||
set tasks [regsub -all {Category:(\S+)} $tasks "\\1/$lang"]
|
||||
|
||||
set collectOfLang [struct::set intersect $collected $doneTasks]
|
||||
set ignorable [struct::set union $doneTasks $omittedTasks $collectOfLang]
|
||||
set unimplemented [struct::set difference $tasks $ignorable]
|
||||
|
||||
puts "\n$lang has [llength $unimplemented] unimplemented programming tasks:"
|
||||
if {[llength $unimplemented]} {
|
||||
puts " [join [lsort $unimplemented] "\n "]"
|
||||
}
|
||||
}
|
||||
|
||||
catch {console show}
|
||||
catch {wm withdraw .}
|
||||
foreach lang {Perl Python Ruby Tcl} {
|
||||
get_unimplemented $lang
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
Set http= CreateObject("WinHttp.WinHttpRequest.5.1")
|
||||
Set oDic = WScript.CreateObject("scripting.dictionary")
|
||||
|
||||
start="https://rosettacode.org"
|
||||
Const lang="VBScript"
|
||||
Dim oHF
|
||||
|
||||
gettaskslist "about:/wiki/Category:Programming_Tasks" ,True
|
||||
print odic.Count
|
||||
gettaskslist "about:/wiki/Category:Draft_Programming_Tasks",True
|
||||
print "total tasks " & odic.Count
|
||||
gettaskslist "about:/wiki/Category:"&lang,False
|
||||
print "total tasks not in " & lang & " " &odic.Count & vbcrlf
|
||||
For Each d In odic.keys
|
||||
print d &vbTab & Replace(odic(d),"about:", start)
|
||||
next
|
||||
WScript.Quit(1)
|
||||
|
||||
Sub print(s):
|
||||
On Error Resume Next
|
||||
WScript.stdout.WriteLine (s)
|
||||
If err= &h80070006& Then WScript.echo " Please run this script with CScript": WScript.quit
|
||||
End Sub
|
||||
|
||||
Function getpage(name)
|
||||
Set oHF=Nothing
|
||||
Set oHF = CreateObject("HTMLFILE")
|
||||
http.open "GET",name,False ''synchronous!
|
||||
http.send
|
||||
oHF.write "<html><body></body></html>"
|
||||
oHF.body.innerHTML = http.responsetext
|
||||
Set getpage=Nothing
|
||||
End Function
|
||||
|
||||
Sub gettaskslist(b,build)
|
||||
nextpage=b
|
||||
While nextpage <>""
|
||||
|
||||
nextpage=Replace(nextpage,"about:", start)
|
||||
WScript.Echo nextpage
|
||||
getpage(nextpage)
|
||||
Set xtoc = oHF.getElementbyId("mw-pages")
|
||||
nextpage=""
|
||||
For Each ch In xtoc.children
|
||||
If ch.innertext= "next page" Then
|
||||
nextpage=ch.attributes("href").value
|
||||
': WScript.Echo nextpage
|
||||
ElseIf ch.attributes("class").value="mw-content-ltr" Then
|
||||
Set ytoc=ch.children(0)
|
||||
'WScript.Echo ytoc.attributes("class").value '"mw-category mw-category-columns"
|
||||
Exit For
|
||||
End If
|
||||
Next
|
||||
For Each ch1 In ytoc.children 'mw-category-group
|
||||
'WScript.Echo ">" &ch1.children(0).innertext &"<"
|
||||
For Each ch2 In ch1.children(1).children '"mw_category_group".ul
|
||||
Set ch=ch2.children(0)
|
||||
If build Then
|
||||
odic.Add ch.innertext , ch.attributes("href").value
|
||||
else
|
||||
if odic.exists(ch.innertext) then odic.Remove ch.innertext
|
||||
End if
|
||||
'WScript.Echo ch.innertext , ch.attributes("href").value
|
||||
Next
|
||||
Next
|
||||
Wend
|
||||
End Sub
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
/* rc_find_unimplemented_tasks.wren */
|
||||
|
||||
import "./pattern" for Pattern
|
||||
|
||||
var CURLOPT_URL = 10002
|
||||
var CURLOPT_FOLLOWLOCATION = 52
|
||||
var CURLOPT_WRITEFUNCTION = 20011
|
||||
var CURLOPT_WRITEDATA = 10001
|
||||
|
||||
foreign class Buffer {
|
||||
construct new() {} // C will allocate buffer of a suitable size
|
||||
|
||||
foreign value // returns buffer contents as a string
|
||||
}
|
||||
|
||||
foreign class Curl {
|
||||
construct easyInit() {}
|
||||
|
||||
foreign easySetOpt(opt, param)
|
||||
|
||||
foreign easyPerform()
|
||||
|
||||
foreign easyCleanup()
|
||||
}
|
||||
|
||||
var curl = Curl.easyInit()
|
||||
|
||||
var getContent = Fn.new { |url|
|
||||
var buffer = Buffer.new()
|
||||
curl.easySetOpt(CURLOPT_URL, url)
|
||||
curl.easySetOpt(CURLOPT_FOLLOWLOCATION, 1)
|
||||
curl.easySetOpt(CURLOPT_WRITEFUNCTION, 0) // write function to be supplied by C
|
||||
curl.easySetOpt(CURLOPT_WRITEDATA, buffer)
|
||||
curl.easyPerform()
|
||||
return buffer.value
|
||||
}
|
||||
|
||||
var p1 = Pattern.new("title/=\"[+1^\"]\"")
|
||||
var p2 = Pattern.new("cmcontinue/=\"[+1^\"]\"")
|
||||
|
||||
var findTasks = Fn.new { |category|
|
||||
var url = "https://www.rosettacode.org/m/api.php?action=query&list=categorymembers&cmtitle=Category:%(category)&cmlimit=500&format=xml"
|
||||
var cmcontinue = ""
|
||||
var tasks = []
|
||||
while (true) {
|
||||
var content = getContent.call(url + cmcontinue)
|
||||
var matches1 = p1.findAll(content)
|
||||
for (m in matches1) {
|
||||
var title = m.capsText[0].replace("'", "'").replace(""", "\"")
|
||||
tasks.add(title)
|
||||
}
|
||||
var m2 = p2.find(content)
|
||||
if (m2) cmcontinue = "&cmcontinue=%(m2.capsText[0])" else break
|
||||
}
|
||||
return tasks
|
||||
}
|
||||
|
||||
var tasks1 = findTasks.call("Programming_Tasks") // 'full' tasks only
|
||||
var tasks2 = findTasks.call("Draft_Programming_Tasks")
|
||||
var lang = "Wren"
|
||||
var langTasks = findTasks.call(lang) // includes draft tasks
|
||||
curl.easyCleanup()
|
||||
System.print("Unimplemented 'full' tasks in %(lang):")
|
||||
for (task in tasks1) {
|
||||
if (!langTasks.contains(task)) System.print(" " + task)
|
||||
}
|
||||
System.print("\nUnimplemented 'draft' tasks in %(lang):")
|
||||
for (task in tasks2) {
|
||||
if (!langTasks.contains(task)) System.print(" " + task)
|
||||
}
|
||||
|
|
@ -0,0 +1,191 @@
|
|||
/* gcc rc_find_unimplemented_tasks.c -o rc_find_unimplemented_tasks -lcurl -lwren -lm */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <curl/curl.h>
|
||||
#include "wren.h"
|
||||
|
||||
struct MemoryStruct {
|
||||
char *memory;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
/* C <=> Wren interface functions */
|
||||
|
||||
static size_t WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp) {
|
||||
size_t realsize = size * nmemb;
|
||||
struct MemoryStruct *mem = (struct MemoryStruct *)userp;
|
||||
|
||||
char *ptr = realloc(mem->memory, mem->size + realsize + 1);
|
||||
if(!ptr) {
|
||||
/* out of memory! */
|
||||
printf("not enough memory (realloc returned NULL)\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
mem->memory = ptr;
|
||||
memcpy(&(mem->memory[mem->size]), contents, realsize);
|
||||
mem->size += realsize;
|
||||
mem->memory[mem->size] = 0;
|
||||
return realsize;
|
||||
}
|
||||
|
||||
void C_bufferAllocate(WrenVM* vm) {
|
||||
struct MemoryStruct *ms = (struct MemoryStruct *)wrenSetSlotNewForeign(vm, 0, 0, sizeof(struct MemoryStruct));
|
||||
ms->memory = malloc(1);
|
||||
ms->size = 0;
|
||||
}
|
||||
|
||||
void C_bufferFinalize(void* data) {
|
||||
struct MemoryStruct *ms = (struct MemoryStruct *)data;
|
||||
free(ms->memory);
|
||||
}
|
||||
|
||||
void C_curlAllocate(WrenVM* vm) {
|
||||
CURL** pcurl = (CURL**)wrenSetSlotNewForeign(vm, 0, 0, sizeof(CURL*));
|
||||
*pcurl = curl_easy_init();
|
||||
}
|
||||
|
||||
void C_value(WrenVM* vm) {
|
||||
struct MemoryStruct *ms = (struct MemoryStruct *)wrenGetSlotForeign(vm, 0);
|
||||
wrenSetSlotString(vm, 0, ms->memory);
|
||||
}
|
||||
|
||||
void C_easyPerform(WrenVM* vm) {
|
||||
CURL* curl = *(CURL**)wrenGetSlotForeign(vm, 0);
|
||||
curl_easy_perform(curl);
|
||||
}
|
||||
|
||||
void C_easyCleanup(WrenVM* vm) {
|
||||
CURL* curl = *(CURL**)wrenGetSlotForeign(vm, 0);
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
void C_easySetOpt(WrenVM* vm) {
|
||||
CURL* curl = *(CURL**)wrenGetSlotForeign(vm, 0);
|
||||
CURLoption opt = (CURLoption)wrenGetSlotDouble(vm, 1);
|
||||
if (opt < 10000) {
|
||||
long lparam = (long)wrenGetSlotDouble(vm, 2);
|
||||
curl_easy_setopt(curl, opt, lparam);
|
||||
} else if (opt < 20000) {
|
||||
if (opt == CURLOPT_WRITEDATA) {
|
||||
struct MemoryStruct *ms = (struct MemoryStruct *)wrenGetSlotForeign(vm, 2);
|
||||
curl_easy_setopt(curl, opt, (void *)ms);
|
||||
} else if (opt == CURLOPT_URL) {
|
||||
const char *url = wrenGetSlotString(vm, 2);
|
||||
curl_easy_setopt(curl, opt, url);
|
||||
}
|
||||
} else if (opt < 30000) {
|
||||
if (opt == CURLOPT_WRITEFUNCTION) {
|
||||
curl_easy_setopt(curl, opt, &WriteMemoryCallback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WrenForeignClassMethods bindForeignClass(WrenVM* vm, const char* module, const char* className) {
|
||||
WrenForeignClassMethods methods;
|
||||
methods.allocate = NULL;
|
||||
methods.finalize = NULL;
|
||||
if (strcmp(module, "main") == 0) {
|
||||
if (strcmp(className, "Buffer") == 0) {
|
||||
methods.allocate = C_bufferAllocate;
|
||||
methods.finalize = C_bufferFinalize;
|
||||
} else if (strcmp(className, "Curl") == 0) {
|
||||
methods.allocate = C_curlAllocate;
|
||||
}
|
||||
}
|
||||
return methods;
|
||||
}
|
||||
|
||||
WrenForeignMethodFn bindForeignMethod(
|
||||
WrenVM* vm,
|
||||
const char* module,
|
||||
const char* className,
|
||||
bool isStatic,
|
||||
const char* signature) {
|
||||
if (strcmp(module, "main") == 0) {
|
||||
if (strcmp(className, "Buffer") == 0) {
|
||||
if (!isStatic && strcmp(signature, "value") == 0) return C_value;
|
||||
} else if (strcmp(className, "Curl") == 0) {
|
||||
if (!isStatic && strcmp(signature, "easySetOpt(_,_)") == 0) return C_easySetOpt;
|
||||
if (!isStatic && strcmp(signature, "easyPerform()") == 0) return C_easyPerform;
|
||||
if (!isStatic && strcmp(signature, "easyCleanup()") == 0) return C_easyCleanup;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void writeFn(WrenVM* vm, const char* text) {
|
||||
printf("%s", text);
|
||||
}
|
||||
|
||||
void errorFn(WrenVM* vm, WrenErrorType errorType, const char* module, const int line, const char* msg) {
|
||||
switch (errorType) {
|
||||
case WREN_ERROR_COMPILE:
|
||||
printf("[%s line %d] [Error] %s\n", module, line, msg);
|
||||
break;
|
||||
case WREN_ERROR_STACK_TRACE:
|
||||
printf("[%s line %d] in %s\n", module, line, msg);
|
||||
break;
|
||||
case WREN_ERROR_RUNTIME:
|
||||
printf("[Runtime Error] %s\n", msg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
char *readFile(const char *fileName) {
|
||||
FILE *f = fopen(fileName, "r");
|
||||
fseek(f, 0, SEEK_END);
|
||||
long fsize = ftell(f);
|
||||
rewind(f);
|
||||
char *script = malloc(fsize + 1);
|
||||
fread(script, 1, fsize, f);
|
||||
fclose(f);
|
||||
script[fsize] = 0;
|
||||
return script;
|
||||
}
|
||||
|
||||
static void loadModuleComplete(WrenVM* vm, const char* module, WrenLoadModuleResult result) {
|
||||
if( result.source) free((void*)result.source);
|
||||
}
|
||||
|
||||
WrenLoadModuleResult loadModule(WrenVM* vm, const char* name) {
|
||||
WrenLoadModuleResult result = {0};
|
||||
if (strcmp(name, "random") != 0 && strcmp(name, "meta") != 0) {
|
||||
result.onComplete = loadModuleComplete;
|
||||
char fullName[strlen(name) + 6];
|
||||
strcpy(fullName, name);
|
||||
strcat(fullName, ".wren");
|
||||
result.source = readFile(fullName);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
WrenConfiguration config;
|
||||
wrenInitConfiguration(&config);
|
||||
config.writeFn = &writeFn;
|
||||
config.errorFn = &errorFn;
|
||||
config.bindForeignClassFn = &bindForeignClass;
|
||||
config.bindForeignMethodFn = &bindForeignMethod;
|
||||
config.loadModuleFn = &loadModule;
|
||||
WrenVM* vm = wrenNewVM(&config);
|
||||
const char* module = "main";
|
||||
const char* fileName = "rc_find_unimplemented_tasks.wren";
|
||||
char *script = readFile(fileName);
|
||||
WrenInterpretResult result = wrenInterpret(vm, module, script);
|
||||
switch (result) {
|
||||
case WREN_RESULT_COMPILE_ERROR:
|
||||
printf("Compile Error!\n");
|
||||
break;
|
||||
case WREN_RESULT_RUNTIME_ERROR:
|
||||
printf("Runtime Error!\n");
|
||||
break;
|
||||
case WREN_RESULT_SUCCESS:
|
||||
break;
|
||||
}
|
||||
wrenFreeVM(vm);
|
||||
free(script);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
var [const] YAJL=Import("zklYAJL")[0], CURL=Import("zklCurl");
|
||||
|
||||
fcn getTasks(language){
|
||||
continueValue,tasks:="",Data(0,String); // "nm\0nm\0...."
|
||||
do{
|
||||
page:=CURL().get(("http://rosettacode.org/mw/api.php?"
|
||||
"action=query&cmlimit=500"
|
||||
"&format=json"
|
||||
"&list=categorymembers"
|
||||
"&cmtitle=Category:%s"
|
||||
"&cmcontinue=%s").fmt(language,continueValue));
|
||||
page=page[0].del(0,page[1]); // get rid of HTML header
|
||||
json:=YAJL().write(page).close();
|
||||
json["query"]["categorymembers"].pump(tasks,T("get","title"));
|
||||
continueValue=json.find("continue") //continue:-||,cmcontinue:page|954|19)
|
||||
.toList().apply("concat","=").concat("&");
|
||||
}while(continueValue);
|
||||
tasks
|
||||
}
|
||||
|
||||
allTasks:=getTasks.future("Programming_Tasks"); // thread
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
language:="zkl";
|
||||
tasks:=getTasks(language);
|
||||
langTasks:=Dictionary(); tasks.pump(Void,langTasks.add.fp1(Void));
|
||||
unimplementedTasks:=allTasks.filter('wrap(nm){ (not langTasks.holds(nm)) });
|
||||
println("Found %d unimplemented tasks for %s:"
|
||||
.fmt(unimplementedTasks.len(1),language));
|
||||
unimplementedTasks.pump(Console.println);
|
||||
Loading…
Add table
Add a link
Reference in a new issue