A CIL Tutorial - Department of Computer Science - ETH Zürich
A CIL Tutorial - Department of Computer Science - ETH Zürich A CIL Tutorial - Department of Computer Science - ETH Zürich
CHAPTER 14. IMPLEMENTING A SIMPLE DSL 120 let create short options (al : argument list) : exp = let short arg of arg (a : argument) : string = a.argShort¢(if a.argOption then ":" else "") in al | > L.map short arg of arg |> S.concat "" |> mkString The function getMainArgs just extracts the varinfos for argv and argv from the list of formal parameters. let getMainArgs (main : fundec) : varinfo × varinfo = match main.sformals with | argc :: argv :: → argc, argv | → E.s (E.error "Must give main argc and argv") The function string of short arg gives the integer code for the character used as the short form of an argument. This is needed since we can't write string or character literals in the interpreted constructor. The function string of arg opt returns the string 1 if the argument has an option, and the string 0 otherwise. let string of short arg (a : argument) : string = a.argShort.[0] | > int of char | > string of int let string of arg opt (a : argument) : string = if a.argOption then "1" else "0" The function create def int string creates a string for a C else statement to be used for setting an argument of integer type without any options to 1. let create def int string (a : argument) : string = if isIntegralType a.argType ∧ ¬(a.argOption) then "else {%l:"¢a.argVi.vname¢"l = 1;}" else "" The function create if str creates a string for the C code that processes a particular argument. The return of getopt long is given in the variable c. If c is equal to the character code for the short version of the argument, then we check to see if the argument has an option, which we parse using sscanf. In case the argument is for a boolean ag, we include the string obtained with create def int string. Finally, we set the global variable that indicates that the argument was given.
CHAPTER 14. IMPLEMENTING A SIMPLE DSL 121 let create if str (a : argument) : string = "if (c == "¢(string of short arg a)¢") {"¢ "if ("¢(string of arg opt a)¢") { if(%e:optarg) {"¢ "%l:scan(%e:optarg,%e:"¢a.argVi.vname¢"fmt,%e:"¢a.argVi.vname¢"addr);"¢ "}}"¢ (create def int string a)¢ "%l:"¢a.argGot.vname¢" = 1;"¢ "}" The if statements created with create if str from the arguments form the body of the loop in which we repeatedly call getopt long. The function create opt loop str generates the string of C code for the loop. It calls getopt long before proceeding into the if statements generated by create\ if str. If the return of getopt long is −1, we break out of the loop. let create opt loop str (al : argument list) : string = "while(1) {"¢ "int c;"¢ "c = %l:gol(%e:argc, %e:argv, %e:sstr, %e:lopts, (void * )0);"¢ "if (c == -1) break;"¢ (al | > L.map create if str | > S.concat " else ")¢ "}" Finally, in the function makeArgStmts we can call Formatcil.cStmts to generate the CIL statements for argument processing. The calls to findOrCreateFunc and findGlobalVar retrieve varinfos from the CIL le that we'll need to pass as parameters to the interpreted constructor. Here, we'll also call the functions that generate the code for allocating and initializing the option array. let makeArgStmts (f : file) (main : fundec) (al : argument list) : stmt list = let gol = findOrCreateFunc f "getopt long" intType in let scan = findOrCreateFunc f "sscanf" intType in let optarg = findGlobalVar f.globals "optarg" in let so = create short options al in let o, m, i = create long options f main al in let argc, argv = getMainArgs main in (L.map i2s (m :: i)) @ Formatcil.cStmts (create opt loop str al) (fun n t → makeTempVar main £name : n t) locUnknown ([("argc", Fe(v2e argc)); ("argv", Fe(v2e argv)); ("sstr", Fe so); ("lopts", Fe (v2e o)); ("gol", Fl(var gol)); ("scan", Fl(var scan)); ("optarg",Fe(v2e optarg))]@ (L.map (fun a → (a.argVi.vname¢"fmt"), Fe (mkString a.argFmt)) al)@
- Page 71 and 72: CHAPTER 8. DEPENDANT TYPE QUALIFIER
- Page 73 and 74: Chapter 9 Type Qualier Inference In
- Page 75 and 76: CHAPTER 9. TYPE QUALIFIER INFERENCE
- Page 77 and 78: CHAPTER 9. TYPE QUALIFIER INFERENCE
- Page 79 and 80: CHAPTER 9. TYPE QUALIFIER INFERENCE
- Page 81 and 82: CHAPTER 9. TYPE QUALIFIER INFERENCE
- Page 83 and 84: Chapter 10 Adding a New Kind of Sta
- Page 85 and 86: CHAPTER 10. ADDING A NEW KIND OF ST
- Page 87 and 88: CHAPTER 10. ADDING A NEW KIND OF ST
- Page 89 and 90: CHAPTER 10. ADDING A NEW KIND OF ST
- Page 91 and 92: CHAPTER 10. ADDING A NEW KIND OF ST
- Page 93 and 94: Chapter 11 Program Verication In th
- Page 95 and 96: CHAPTER 11. PROGRAM VERIFICATION 93
- Page 97 and 98: CHAPTER 11. PROGRAM VERIFICATION 95
- Page 99 and 100: CHAPTER 11. PROGRAM VERIFICATION 97
- Page 101 and 102: CHAPTER 11. PROGRAM VERIFICATION 99
- Page 103 and 104: CHAPTER 11. PROGRAM VERIFICATION 10
- Page 105 and 106: CHAPTER 11. PROGRAM VERIFICATION 10
- Page 107 and 108: Chapter 12 Comments CIL has a very
- Page 109 and 110: CHAPTER 12. COMMENTS 107 let printC
- Page 111 and 112: References [1] Lin Tan, Ding Yuan,
- Page 113 and 114: CHAPTER 13. WHOLE-PROGRAM ANALYSIS
- Page 115 and 116: CHAPTER 13. WHOLE-PROGRAM ANALYSIS
- Page 117 and 118: CHAPTER 14. IMPLEMENTING A SIMPLE D
- Page 119 and 120: CHAPTER 14. IMPLEMENTING A SIMPLE D
- Page 121: CHAPTER 14. IMPLEMENTING A SIMPLE D
- Page 125 and 126: CHAPTER 14. IMPLEMENTING A SIMPLE D
- Page 127 and 128: Chapter 15 Automated Test Generatio
- Page 129 and 130: CHAPTER 15. AUTOMATED TEST GENERATI
- Page 131 and 132: CHAPTER 15. AUTOMATED TEST GENERATI
- Page 133 and 134: CHAPTER 15. AUTOMATED TEST GENERATI
- Page 135 and 136: Index A (module), 10, 13, 15, 10, 1
- Page 137 and 138: INDEX 135 isCacheReportType, 11, 11
CHAPTER 14. IMPLEMENTING A SIMPLE DSL 120<br />
let create short options (al : argument list) : exp =<br />
let short arg <strong>of</strong> arg (a : argument) : string =<br />
a.argShort¢(if a.argOption then ":" else "")<br />
in<br />
al | > L.map short arg <strong>of</strong> arg<br />
|> S.concat ""<br />
|> mkString<br />
The function getMainArgs just extracts the varinfos for argv and argv from the list <strong>of</strong> formal<br />
parameters.<br />
let getMainArgs (main : fundec) : varinfo × varinfo =<br />
match main.sformals with<br />
| argc :: argv :: → argc, argv<br />
| → E.s (E.error "Must give main argc and argv")<br />
The function string <strong>of</strong> short arg gives the integer code for the character used as the short form<br />
<strong>of</strong> an argument. This is needed since we can't write string or character literals in the interpreted<br />
constructor. The function string <strong>of</strong> arg opt returns the string 1 if the argument has an option,<br />
and the string 0 otherwise.<br />
let string <strong>of</strong> short arg (a : argument) : string =<br />
a.argShort.[0] | > int <strong>of</strong> char | > string <strong>of</strong> int<br />
let string <strong>of</strong> arg opt (a : argument) : string =<br />
if a.argOption then "1" else "0"<br />
The function create def int string creates a string for a C else statement to be used for setting<br />
an argument <strong>of</strong> integer type without any options to 1.<br />
let create def int string (a : argument) : string =<br />
if isIntegralType a.argType ∧ ¬(a.argOption)<br />
then "else {%l:"¢a.argVi.vname¢"l = 1;}"<br />
else ""<br />
The function create if str creates a string for the C code that processes a particular argument.<br />
The return <strong>of</strong> getopt long is given in the variable c. If c is equal to the character code for the<br />
short version <strong>of</strong> the argument, then we check to see if the argument has an option, which we parse<br />
using sscanf. In case the argument is for a boolean ag, we include the string obtained with<br />
create def int string. Finally, we set the global variable that indicates that the argument was<br />
given.