The use of   abbreviations   (also sometimes called synonyms, nicknames, AKAs, or aliases)   can be an

easy way to add flexibility when specifying or using commands, sub─commands, options, etc.



For this task, the following   command table   will be used:

   add 1  alter 3  backup 2  bottom 1  Cappend 2  change 1  Schange  Cinsert 2  Clast 3
   compress 4 copy 2 count 3 Coverlay 3 cursor 3  delete 3 Cdelete 2  down 1  duplicate
   3 xEdit 1 expand 3 extract 3  find 1 Nfind 2 Nfindup 6 NfUP 3 Cfind 2 findUP 3 fUP 2
   forward 2  get  help 1 hexType 4  input 1 powerInput 3  join 1 split 2 spltJOIN load
   locate 1 Clocate 2 lowerCase 3 upperCase 3 Lprefix 2  macro  merge 2 modify 3 move 2
   msg  next 1 overlay 1 parse preserve 4 purge 3 put putD query 1 quit  read recover 3
   refresh renum 3 repeat 3 replace 1 Creplace 2 reset 3 restore 4 rgtLEFT right 2 left
   2  save  set  shift 2  si  sort  sos  stack 3 status 4 top  transfer 3  type 1  up 1



Notes concerning the above   command table:

   it can be thought of as one long literal string   (with blanks at end-of-lines)
   it may have superfluous blanks
   it may be in any case (lower/upper/mixed)
   the order of the words in the   command table   must be preserved as shown
   the user input(s) may be in any case (upper/lower/mixed)
   commands will be restricted to the Latin alphabet   (A ──► Z,   a ──► z)
   a command is followed by an optional number, which indicates the minimum abbreviation
   A valid abbreviation is a word that has:
   at least the minimum length of the word's minimum number in the command table
   compares equal (regardless of case) to the leading characters of the word in the command table
   a length not longer than the word in the command table
   ALT,   aLt,   ALTE,   and   ALTER   are all abbreviations of   ALTER 3
   AL,   ALF,   ALTERS,   TER,   and   A   aren't valid abbreviations of   ALTER 3
   The   3   indicates that any abbreviation for   ALTER   must be at least three characters
   Any word longer than five characters can't be an abbreviation for   ALTER
   o,   ov,   oVe,   over,   overL,   overla   are all acceptable abbreviations for   overlay 1
   if there isn't a number after the command,   then there isn't an abbreviation permitted


Task

   The command table needn't be verified/validated.
   Write a function to validate if the user "words"   (given as input)   are valid   (in the command table).
   If the word   is   valid,   then return the full uppercase version of that "word".
   If the word isn't valid,   then return the lowercase string:    *error*        (7 characters).
   A blank input   (or a null input)   should return a null string.
   Show all output here.


An example test case to be used for this task

For a user string of:

 riG   rePEAT copies  put mo   rest    types   fup.    6       poweRin

the computer program should return the string:

 RIGHT REPEAT *error* PUT MOVE RESTORE *error* *error* *error* POWERINPUT


Other tasks related to string operations:

Metrics
 Array length
 String length
 Copy a string
 Empty string  (assignment)
Counting
 Word frequency
 Letter frequency
 Jewels and stones
 I before E except after C
 Bioinformatics/base count
 Count occurrences of a substring
 Count how many vowels and consonants occur in a string
Remove/replace
 XXXX redacted
 Conjugate a Latin verb
 Remove vowels from a string
 String interpolation (included)
 Strip block comments
 Strip comments from a string
 Strip a set of characters from a string
 Strip whitespace from a string -- top and tail
 Strip control codes and extended characters from a string
Anagrams/Derangements/shuffling
 Word wheel
 ABC problem
 Sattolo cycle
 Knuth shuffle
 Ordered words
 Superpermutation minimisation
 Textonyms (using a phone text pad)
 Anagrams
 Anagrams/Deranged anagrams
 Permutations/Derangements
Find/Search/Determine
 ABC words
 Odd words
 Word ladder
 Semordnilap
 Word search
 Wordiff  (game)
 String matching
 Tea cup rim text
 Alternade words
 Changeable words
 State name puzzle
 String comparison
 Unique characters
 Unique characters in each string
 Extract file extension
 Levenshtein distance
 Palindrome detection
 Common list elements
 Longest common suffix
 Longest common prefix
 Compare a list of strings 
 Longest common substring
 Find common directory path
 Words from neighbour ones
 Change e letters to i in words
 Non-continuous subsequences
 Longest common subsequence
 Longest palindromic substrings
 Longest increasing subsequence
 Words containing "the" substring
 Sum of the digits of n is substring of n
 Determine if a string is numeric
 Determine if a string is collapsible
 Determine if a string is squeezable
 Determine if a string has all unique characters
 Determine if a string has all the same characters
 Longest substrings without repeating characters
 Find words which contains all the vowels
 Find words which contains most consonants
 Find words which contains more than 3 vowels
 Find words which first and last three letters are equals
 Find words which odd letters are consonants and even letters are vowels or vice_versa
Formatting
 Substring
 Rep-string
 Word wrap
 String case
 Align columns
 Literals/String
 Repeat a string
 Brace expansion
 Brace expansion using ranges
 Reverse a string
 Phrase reversals
 Comma quibbling
 Special characters
 String concatenation
 Substring/Top and tail
 Commatizing numbers
 Reverse words in a string
 Suffixation of decimal numbers
 Long literals, with continuations 
 Numerical and alphabetical suffixes
 Abbreviations, easy
 Abbreviations, simple
 Abbreviations, automatic
Song lyrics/poems/Mad Libs/phrases
 Mad Libs
 Magic 8-ball
 99 Bottles of Beer
 The Name Game (a song)
 The Old lady swallowed a fly
 The Twelve Days of Christmas
Tokenize
 Text between
 Tokenize a string
 Word break problem
 Tokenize a string with escaping
 Split a character string based on change of character
Sequences
 Show ASCII table
 De Bruijn sequences
 Self-referential sequences
 Generate lower case ASCII alphabet




 
/* ARM assembly AARCH64 Raspberry PI 3B */
/*  program abbrSimple64.s   */
/* store list of command in a file commandSimple.txt */
/* and run the program  abbrSimple64 commandSimple.txt */
 
/*******************************************/
/* Constantes file                         */
/*******************************************/
/* for this file see task include a file in language AArch64 assembly*/
.include "../includeConstantesARM64.inc"
 
.equ BUFFERSIZE,   1000
.equ NBMAXIELEMENTS, 100
 
/*******************************************/
/* Structures                               */
/********************************************/
/* command structure      */
    .struct  0
command_name_address:                   // name
    .struct  command_name_address + 8 
command_min:                            // minimum letters
    .struct  command_min + 8
command_end:
/*********************************/
/* Initialized data              */
/*********************************/
.data
szMessTitre:            .asciz "Nom du fichier : "
szCarriageReturn:      .asciz "\n"
szMessErreur:          .asciz "Error detected.\n"
szMessErrBuffer:       .asciz "buffer size too less !!"
szMessCtrlCom:         .asciz "Command : @   minimum : @ \n"
szMessErrorAbr:        .asciz "*error*"
szMessInput:           .asciz "Enter command (or <ctrl-c> to stop) : "
 
/*********************************/
/* UnInitialized data            */
/*********************************/
.bss
.align 4
sZoneConv:      .skip 24
qAdrFicName:    .skip 8
iTabAdrCmd:     .skip command_end * NBMAXIELEMENTS 
sBufferCmd:     .skip BUFFERSIZE
sBuffer:        .skip BUFFERSIZE
/*********************************/
/*  code section                 */
/*********************************/
.text
.global main 
main:                            // INFO: main
    mov x0,sp                    // stack address for load parameter
    bl traitFic                  // read file and store value in array
    cmp x0,#-1
    beq 100f                     // error ?
    ldr x0,qAdriTabAdrCmd
    bl controlLoad
 
1:
    ldr x0,qAdrszMessInput       // display input message
    bl affichageMess
    mov x0,#STDIN                // Linux input console
    ldr x1,qAdrsBuffer           // buffer address 
    mov x2,#BUFFERSIZE           // buffer size 
    mov x8, #READ                // request to read datas
    svc 0                        // call system
    sub x0,x0,#1
    mov x2,#0
    strb w2,[x1,x0]              // replace character 0xA by zéro final
    cbnz x0,2f                   // null string ?
    mov x0,x1
    b 3f
2:
    ldr x0,qAdrsBuffer   
    ldr x1,qAdriTabAdrCmd
    bl controlCommand            // control text command
3:
    mov x2,x0                    // display result
    bl affichageMess
    ldr x0,qAdrszCarriageReturn
    bl affichageMess
 
    b 1b                         // loop
 
99:
    ldr x0,qAdrszMessErrBuffer
    bl affichageMess
100:                                 // standard end of the program 
    mov x0, #0                       // return code
    mov x8, #EXIT                    // request to exit program
    svc #0                           // perform the system call
 
qAdrszCarriageReturn:      .quad szCarriageReturn
qAdrszMessErrBuffer:       .quad szMessErrBuffer
qAdrsZoneConv:             .quad sZoneConv
qAdrszMessInput:           .quad szMessInput
/******************************************************************/
/*      control abbrevation command                               */ 
/******************************************************************/
/* x0 contains string input command */
/* x1 contains address table string command */
controlCommand:                  // INFO: controlCommand
    stp x1,lr,[sp,-16]!          // save  registres
    stp x2,x3,[sp,-16]!          // save  registres
    stp x4,x5,[sp,-16]!          // save  registres
    stp x6,x7,[sp,-16]!          // save  registres
    stp x8,x9,[sp,-16]!          // save  registres
    mov x8,x0
    mov x9,x1
    mov x10,#command_end          // length item
    bl computeLength              // length input command
    mov x4,x0                     // save length input
    mov x2,#0                     // indice
    mov x3,#0                     // find counter
1:
    mov x0,x8
    madd x6,x2,x10,x9              // compute address
    ldr x1,[x6,#command_name_address]  // load a item
    cbz x1,5f                     // end ?
    bl comparStringSpe            // 
    cbz x0,4f                     // no found other search
    ldr x5,[x6,#command_min]
    cmp x5,#0                     // minimum = zéro ?
    ble 2f
    cmp x4,x5                     // input < command capital letters
    blt 4f                        // no correct
 
    add x3,x3,#1                  // else increment counter
    mov x7,x1                     // and save address command
    b 4f
2:
    mov x0,x1
    bl computeLength              // length table command
    cmp x0,x4                     // length input commant <> lenght table command
    bne 4f                        // no correct
    add x3,x3,#1                  // else increment counter
    mov x7,x1                     // and save address command
4:
    add x2,x2,#1                  // increment indice
    b 1b                          // and loop
5:
    cmp x3,#1                     // no find or multiple find ?
    bne 99f                       // error 
                                  // one find
    mov x0,x7                     // length command table
    bl computeLength
    cmp x4,x0                     // length input > command ?
    bgt 99f                       // error
 
    mov x4,#0x20                  // 5 bit to 1
    mov x2,#0
6:
    ldrb w3,[x7,x2]
    cbz w3,7f
    bic x3,x3,x4                  // convert to capital letter
    strb w3,[x8,x2]
    add x2,x2,#1
    b 6b
7:
    strb w3,[x8,x2]
    mov x0,x8                     // return string input address
    b 100f
99:
    ldr x0,qAdrszMessErrorAbr     // return string "error"
100:
    ldp x8,x9,[sp],16             // restaur des  2 registres
    ldp x6,x7,[sp],16             // restaur des  2 registres
    ldp x4,x5,[sp],16             // restaur des  2 registres
    ldp x2,x3,[sp],16             // restaur des  2 registres
    ldp x1,lr,[sp],16             // restaur des  2 registres
    ret
qAdrszMessErreur:           .quad szMessErreur
qAdrszMessErrorAbr:         .quad szMessErrorAbr
/******************************************************************/
/*     comparaison first letters String                                          */ 
/******************************************************************/
/* x0 contains first String   */
/* x1 contains second string */
/* x0 return 0 if not find else returns number letters OK */
comparStringSpe:
    stp x1,lr,[sp,-16]!          // save  registres
    stp x2,x3,[sp,-16]!          // save  registres
    stp x4,x5,[sp,-16]!          // save  registres
    stp x6,x7,[sp,-16]!          // save  registres
    mov x2,#0
1:
    ldrb w3,[x0,x2]           // input
    orr w4,w3,#0x20           // convert capital letter
    ldrb w5,[x1,x2]           // table
    orr w6,w5,#0x20           // convert capital letter
    cmp w4,w6
    bne 2f
    cbz w3,3f                 // end strings ?
    add x2,x2,#1
    b 1b 
2:
   cbz w3,3f                  // fist letters Ok
   mov x0,#0                  // no ok
   b 100f
3:
   mov x0,x2
100:
    ldp x6,x7,[sp],16           // restaur des  2 registres
    ldp x4,x5,[sp],16           // restaur des  2 registres
    ldp x2,x3,[sp],16           // restaur des  2 registres
    ldp x1,lr,[sp],16           // restaur des  2 registres
    ret
/******************************************************************/
/*     compute length  String                                          */ 
/******************************************************************/
/* x0 contains  String   */
/* x0 return length */ 
computeLength:                   // INFO: functionFN
    stp x1,lr,[sp,-16]!          // save  registres
    stp x2,x3,[sp,-16]!          // save  registres
    mov x1,#0
1:
    ldrb w2,[x0,x1]
    cbz w2,2f                    // end ?
    add x1,x1,#1
    b 1b
2:
    mov x0,x1                  // return length in x0
100:
    ldp x2,x3,[sp],16           // restaur des  2 registres
    ldp x1,lr,[sp],16           // restaur des  2 registres
    ret
/******************************************************************/
/*     read file                                                   */ 
/******************************************************************/
/* x0 contains address stack begin           */
traitFic:                             // INFO: traitFic
    stp x1,lr,[sp,-16]!          // save  registres
    stp x2,x3,[sp,-16]!          // save  registres
    stp x4,x5,[sp,-16]!          // save  registres
    stp x6,x7,[sp,-16]!          // save  registres
    stp x8,fp,[sp,-16]!          // save  registres
    mov fp,x0                         //  fp <- start address
    ldr x4,[fp]                       // number of Command line arguments
    cmp x4,#1
    ble 99f
    add x5,fp,#16                      // second parameter address 
    ldr x5,[x5]
    ldr x0,qAdrqAdrFicName
    str x5,[x0]
    ldr x0,qAdrszMessTitre
    bl affichageMess                  // display string
    mov x0,x5
    bl affichageMess 
    ldr x0,qAdrszCarriageReturn
    bl affichageMess                  // display carriage return
 
    mov x0,AT_FDCWD
    mov x1,x5                         // file name
    mov x2,#O_RDWR                    // flags    
    mov x3,#0                         // mode 
    mov x8, #OPEN                     // call system OPEN 
    svc 0 
    cmp x0,#0                         // error ?
    ble 99f
    mov x7,x0                         // File Descriptor
    ldr x1,qAdrsBufferCmd             // buffer address
    mov x2,#BUFFERSIZE                // buffer size
    mov x8,#READ                      // read file
    svc #0
    cmp x0,#0                         // error ?
    blt 99f
    // extraction datas
    ldr x1,qAdrsBufferCmd             // buffer address
    add x1,x1,x0
    mov x0,#0                         // store zéro final
    strb w0,[x1] 
    ldr x0,qAdriTabAdrCmd             // key string command table
    ldr x1,qAdrsBufferCmd             // buffer address
    bl extracDatas
                                      // close file
    mov x0,x7
    mov x8, #CLOSE 
    svc 0 
    mov x0,#0
    b 100f
99:                                   // error
    ldr x0,qAdrszMessErreur           // error message
    bl   affichageMess
    mov x0,#-1
100:
    ldp x8,fp,[sp],16           // restaur des  2 registres
    ldp x6,x7,[sp],16           // restaur des  2 registres
    ldp x4,x5,[sp],16           // restaur des  2 registres
    ldp x2,x3,[sp],16           // restaur des  2 registres
    ldp x1,lr,[sp],16           // restaur des  2 registres
    ret
qAdrqAdrFicName:              .quad qAdrFicName
qAdrszMessTitre:              .quad szMessTitre
qAdrsBuffer:                  .quad sBuffer
qAdrsBufferCmd:               .quad sBufferCmd
qAdriTabAdrCmd:               .quad iTabAdrCmd
/******************************************************************/
/*     extrac digit file buffer                                   */ 
/******************************************************************/
/* x0 contains strings address           */
/* x1 contains buffer address         */
extracDatas:                     // INFO: extracDatas
    stp x1,lr,[sp,-16]!          // save  registres
    stp x2,x3,[sp,-16]!          // save  registres
    stp x4,x5,[sp,-16]!          // save  registres
    stp x6,x7,[sp,-16]!          // save  registres
    stp x8,fp,[sp,-16]!          // save  registres
    mov x7,x0
    mov x6,x1
    mov x8,#0                    // top command name
    mov x2,#0                    // string buffer indice
    mov x4,x1                    // start string
    mov x5,#0                    // string index
1:
    ldrb w3,[x6,x2]
    cbz w3,4f                    // end
    cmp x3,#0xA
    beq 2f
    cmp x3,#' '                  // end string
    beq 3f
    add x2,x2,#1
    b 1b
2:
    mov x3,#0
    strb w3,[x6,x2]
    ldrb w3,[x6,x2]
    cmp w3,#0xD
    bne 21f
    add x2,x2,#2
    b 4f
21:
    add x2,x2,#1
    b 4f
 
3:
    mov x3,#0
    strb w3,[x6,x2]
    add x2,x2,#1
4:  
    mov x0,x4
    ldrb w1,[x0]                // load first byte
    cmp w1,#'0'                 // it is à digit ?
    blt 5f
    cmp w1,#'9'
    bgt 5f
    mov x1,#command_end
    madd x1,x5,x1,x7              // compute address to store
    mov x0,x4
    bl conversionAtoD            // conversion ascii digit
    str x0,[x1,#command_min]     // and store in minimum
    mov x8,#0                    // line command ok
    add x5,x5,#1                    // increment indice
    b 7f
5:
    cmp x8,#0                    // other name ?
    beq 6f
    mov x0,#0                    // yes store zéro in minimum in prec 
    mov x1,#command_end
    madd x1,x5,x1,x7
    add x1,x1,#command_min
    str x0,[x1]
    add x5,x5,#1                    // and increment indice
6:
    mov x8,#1                    // load name
    mov x1,#command_end
    madd x1,x5,x1,x7              // store name in table
    str x4,[x1,#command_name_address]
7:                               // loop suppress spaces
    ldrb w3,[x6,x2]
    cmp w3,#0
    beq 100f
    cmp w3,#' '
    cinc x2,x2,eq
    beq 7b
 
    add x4,x6,x2                 // new start address
    b 1b
100:
    ldp x8,fp,[sp],16           // restaur des  2 registres
    ldp x6,x7,[sp],16           // restaur des  2 registres
    ldp x4,x5,[sp],16           // restaur des  2 registres
    ldp x2,x3,[sp],16           // restaur des  2 registres
    ldp x1,lr,[sp],16           // restaur des  2 registres
    ret
/******************************************************************/
/*     control load                                      */ 
/******************************************************************/
/* x0 contains string table           */
controlLoad:
    stp x1,lr,[sp,-16]!          // save  registres
    stp x2,x3,[sp,-16]!          // save  registres
    stp x4,x5,[sp,-16]!          // save  registres
    stp x6,x7,[sp,-16]!          // save  registres
    mov x5,x0
    mov x6,#0
    mov x2,#command_end
1:
    madd x3,x6,x2,x5             // compute item address 
    ldr x1,[x3,#command_name_address]
    cbz x1,100f
    ldr x0,qAdrszMessCtrlCom
    bl strInsertAtCharInc
    mov x4,x0
    ldr x0,[x3,#command_min]
    ldr x1,qAdrsZoneConv
    bl conversion10              // call decimal conversion
    mov x0,x4
    ldr x1,qAdrsZoneConv         // insert conversion in message
    bl strInsertAtCharInc
    bl affichageMess             // display message
    add x6,x6,#1
    b 1b
 
100:
    ldp x6,x7,[sp],16           // restaur des  2 registres
    ldp x4,x5,[sp],16           // restaur des  2 registres
    ldp x2,x3,[sp],16           // restaur des  2 registres
    ldp x1,lr,[sp],16           // restaur des  2 registres
    ret
qAdrszMessCtrlCom:       .quad szMessCtrlCom
 
/********************************************************/
/*        File Include fonctions                        */
/********************************************************/
/* for this file see task include a file in language AArch64 assembly */
.include "../includeARM64.inc"
 