diff --git a/darwin/assert.go b/darwin/assert.go index b4ad8b85a..6bf50c4e9 100644 --- a/darwin/assert.go +++ b/darwin/assert.go @@ -8,14 +8,14 @@ import ( ) // BuiltinExpect handles __builtin_expect(). -func BuiltinExpect(a, b int) int { +func BuiltinExpect(a, b int32) int32 { return noarch.BoolToInt(a != b) } // AssertRtn handles __assert_rtn(). func AssertRtn( functionName, filePath []byte, - lineNumber int, + lineNumber int32, expression []byte, ) bool { fmt.Fprintf( diff --git a/darwin/ctype.go b/darwin/ctype.go index 525880276..1c8836340 100644 --- a/darwin/ctype.go +++ b/darwin/ctype.go @@ -6,7 +6,7 @@ import ( ) // CtRuneT represents __darwin_ct_rune_t. -type CtRuneT int +type CtRuneT int32 // Apple defines a bunch of magic values for the type of character, see // https://opensource.apple.com/source/Libc/Libc-320/include/ctype.h.auto.html diff --git a/darwin/stdio.go b/darwin/stdio.go index 547f6ef2d..1fc65d43d 100644 --- a/darwin/stdio.go +++ b/darwin/stdio.go @@ -3,21 +3,21 @@ package darwin import "github.com/elliotchance/c2go/noarch" // BuiltinVsprintfChk - implementation __builtin___vsprintf_chk -func BuiltinVsprintfChk(buffer []byte, _ int, n int, format []byte, args noarch.VaList) int { +func BuiltinVsprintfChk(buffer []byte, _ int32, n int32, format []byte, args noarch.VaList) int32 { return noarch.Sprintf(buffer, format, args.Args) } // BuiltinVsnprintfChk - implementation __builtin___vsnprintf_chk -func BuiltinVsnprintfChk(buffer []byte, n int, _ int, _ int, format []byte, args noarch.VaList) int { +func BuiltinVsnprintfChk(buffer []byte, n int32, _ int32, _ int32, format []byte, args noarch.VaList) int32 { return noarch.Sprintf(buffer, format, args.Args) } // BuiltinSprintfChk - implementation __builtin___sprintf_chk -func BuiltinSprintfChk(buffer []byte, _ int, n int, format []byte, args ...interface{}) int { +func BuiltinSprintfChk(buffer []byte, _ int32, n int32, format []byte, args ...interface{}) int32 { return noarch.Sprintf(buffer, format, args) } // BuiltinSnprintfChk - implementation __builtin___snprintf_chk -func BuiltinSnprintfChk(buffer []byte, n int, _ int, _ int, format []byte, args ...interface{}) int { +func BuiltinSnprintfChk(buffer []byte, n int32, _ int32, _ int32, format []byte, args ...interface{}) int32 { return noarch.Sprintf(buffer, format, args) } diff --git a/darwin/string.go b/darwin/string.go index b5eada3fa..4414ee5d5 100644 --- a/darwin/string.go +++ b/darwin/string.go @@ -4,24 +4,24 @@ import "github.com/elliotchance/c2go/noarch" // BuiltinStrcpy is for __builtin___strcpy_chk. // https://opensource.apple.com/source/Libc/Libc-498/include/secure/_string.h -func BuiltinStrcpy(dest, src []byte, size int) []byte { +func BuiltinStrcpy(dest, src []byte, size int32) []byte { return noarch.Strcpy(dest, src) } // BuiltinObjectSize is for __builtin_object_size. // https://github.com/elliotchance/c2go/issues/359 -func BuiltinObjectSize(ptr []byte, theType int) int { +func BuiltinObjectSize(ptr []byte, theType int32) int32 { return 5 } // BuiltinStrncpy is for __builtin___strncpy_chk. // https://opensource.apple.com/source/Libc/Libc-498/include/secure/_string.h -func BuiltinStrncpy(dest, src []byte, len, size int) []byte { +func BuiltinStrncpy(dest, src []byte, len, size int32) []byte { return noarch.Strncpy(dest, src, len) } // BuiltinStrcat is for __builtin___strcat_chk // https://opensource.apple.com/source/Libc/Libc-763.12/include/secure/_string.h.auto.html -func BuiltinStrcat(dest, src []byte, _ int) []byte { +func BuiltinStrcat(dest, src []byte, _ int32) []byte { return noarch.Strcat(dest, src) } diff --git a/linux/ctype.go b/linux/ctype.go index 166e76cd3..f9ad7f51f 100644 --- a/linux/ctype.go +++ b/linux/ctype.go @@ -84,11 +84,11 @@ func CtypeLoc() [][]uint16 { } // ToLower handles tolower(). -func ToLower(_c int) int { - return int(unicode.ToLower(rune(_c))) +func ToLower(_c int32) int32 { + return int32(unicode.ToLower(rune(_c))) } // ToUpper handles toupper(). -func ToUpper(_c int) int { - return int(unicode.ToUpper(rune(_c))) +func ToUpper(_c int32) int32 { + return int32(unicode.ToUpper(rune(_c))) } diff --git a/linux/math.go b/linux/math.go index ebc7dffe3..264a4551e 100644 --- a/linux/math.go +++ b/linux/math.go @@ -6,14 +6,14 @@ import ( "github.com/elliotchance/c2go/noarch" ) -func IsNanf(x float32) int { +func IsNanf(x float32) int32 { return noarch.BoolToInt(math.IsNaN(float64(x))) } -func IsInff(x float32) int { +func IsInff(x float32) int32 { return noarch.BoolToInt(math.IsInf(float64(x), 0)) } -func IsInf(x float64) int { +func IsInf(x float64) int32 { return noarch.BoolToInt(math.IsInf(x, 0)) } diff --git a/noarch/math.go b/noarch/math.go index 6f39996b8..e903f1c94 100644 --- a/noarch/math.go +++ b/noarch/math.go @@ -4,18 +4,24 @@ import ( "math" ) -func Signbitf(x float32) int { +func Signbitf(x float32) int32 { return BoolToInt(math.Signbit(float64(x))) } -func Signbitd(x float64) int { +func Signbitd(x float64) int32 { return BoolToInt(math.Signbit(x)) } -func Signbitl(x float64) int { +func Signbitl(x float64) int32 { return BoolToInt(math.Signbit(x)) } -func IsNaN(x float64) int { +func IsNaN(x float64) int32 { return BoolToInt(math.IsNaN(x)) } + +// Ldexp is the inverse of Frexp. +// Ldexp uses math.Ldexp to calculate the value. +func Ldexp(frac float64, exp int32) float64 { + return math.Ldexp(frac, int(exp)) +} diff --git a/noarch/noarch.go b/noarch/noarch.go index 9f47dc447..62d78206e 100644 --- a/noarch/noarch.go +++ b/noarch/noarch.go @@ -3,7 +3,7 @@ package noarch // BoolToInt converts boolean value to an int, which is a common operation in C. // 0 and 1 represent false and true respectively. -func BoolToInt(x bool) int { +func BoolToInt(x bool) int32 { if x { return 1 } @@ -20,6 +20,15 @@ func NotInt(x int) int { return 0 } +// NotInt32 works the same as NotInt, but on a int32. +func NotInt32(x int32) int32 { + if x == 0 { + return 1 + } + + return 0 +} + // NotUint16 works the same as NotInt, but on a uint16. func NotUint16(x uint16) uint16 { if x == 0 { @@ -29,6 +38,15 @@ func NotUint16(x uint16) uint16 { return 0 } +// NotInt8 works the same as NotInt, but on a int8. +func NotInt8(x int8) int8 { + if x == 0 { + return 1 + } + + return 0 +} + // Ternary simulates the ternary (also known as the conditional operator). Go // does not have the equivalent of using if statements as expressions or inline // if statements. This function takes the true and false parts as closures to be diff --git a/noarch/stdio.go b/noarch/stdio.go index 48dc9b666..939965c15 100644 --- a/noarch/stdio.go +++ b/noarch/stdio.go @@ -101,7 +101,7 @@ func Fopen(filePath, mode []byte) *File { // // Even if the call fails, the stream passed as parameter will no longer be // associated with the file nor its buffers. -func Fclose(f *File) int { +func Fclose(f *File) int32 { err := f.OsFile.Close() if err != nil { // Is this the correct error code? @@ -119,7 +119,7 @@ func Fclose(f *File) int { // No streams are involved in the operation. // // Proper file access shall be available. -func Remove(filePath []byte) int { +func Remove(filePath []byte) int32 { if os.Remove(CStringToString(filePath)) != nil { return -1 } @@ -142,7 +142,7 @@ func Remove(filePath []byte) int { // implementation. // // Proper file access shall be available. -func Rename(oldName, newName []byte) int { +func Rename(oldName, newName []byte) int32 { from := CStringToString(oldName) to := CStringToString(newName) @@ -164,7 +164,7 @@ func Rename(oldName, newName []byte) int { // Notice that fputs not only differs from puts in that the destination stream // can be specified, but also fputs does not write additional characters, while // puts appends a newline character at the end automatically. -func Fputs(str []byte, stream *File) int { +func Fputs(str []byte, stream *File) int32 { length := 0 for _, b := range []byte(str) { if b == 0 { @@ -179,7 +179,7 @@ func Fputs(str []byte, stream *File) int { panic(err) } - return n + return int32(n) } // Tmpfile handles tmpfile(). @@ -216,7 +216,7 @@ func Tmpfile() *File { // Notice that fgets is quite different from gets: not only fgets accepts a // stream argument, but also allows to specify the maximum size of str and // includes in the string any ending newline character. -func Fgets(str []byte, num int, stream *File) []byte { +func Fgets(str []byte, num int32, stream *File) []byte { buf := make([]byte, num) n, err := stream.OsFile.Read(buf) @@ -233,7 +233,7 @@ func Fgets(str []byte, num int, stream *File) []byte { // // We do not trim off the NULL characters because we do not know if the file // we are reading is in binary mode. - if n == num { + if n == int(num) { // If it is the case that we have read the entire buffer with this read // we need to make sure we leave room for what would be the NULL // character at the end of the string in C. @@ -273,7 +273,7 @@ func Rewind(stream *File) { // This indicator is cleared by a call to clearerr, rewind, fseek, fsetpos or // freopen. Although if the position indicator is not repositioned by such a // call, the next i/o operation is likely to set the indicator again. -func Feof(stream *File) int { +func Feof(stream *File) int32 { // FIXME: This is a really bad way of doing this. Basically try and peek // ahead to test for EOF. buf := make([]byte, 1) @@ -287,7 +287,7 @@ func Feof(stream *File) int { // Undo cursor before returning. stream.OsFile.Seek(-1, 1) - return result + return int32(result) } // NewFile creates a File pointer from a Go file pointer. @@ -347,7 +347,7 @@ func Tmpnam(str []byte) []byte { // When a file is closed, either because of a call to fclose or because the // program terminates, all the buffers associated with it are automatically // flushed. -func Fflush(stream *File) int { +func Fflush(stream *File) int32 { err := stream.OsFile.Sync() if err != nil { return 1 @@ -365,7 +365,7 @@ func Fflush(stream *File) int { // // After the format parameter, the function expects at least as many additional // arguments as specified by format. -func Fprintf(f *File, format []byte, args ...interface{}) int { +func Fprintf(f *File, format []byte, args ...interface{}) int32 { realArgs := []interface{}{} // Convert any C strings into Go strings. @@ -383,7 +383,7 @@ func Fprintf(f *File, format []byte, args ...interface{}) int { return -1 } - return n + return int32(n) } // Fscanf handles fscanf(). @@ -438,14 +438,14 @@ func prepareArgsForScanf(args []interface{}) []interface{} { return realArgs } -func getc(f *os.File) int { +func getc(f *os.File) int32 { buffer := make([]byte, 1) _, err := f.Read(buffer) if err != nil { return -1 } - return int(buffer[0]) + return int32(buffer[0]) } // Fgetc handles fgetc(). @@ -462,7 +462,7 @@ func getc(f *os.File) int { // // fgetc and getc are equivalent, except that getc may be implemented as a macro // in some libraries. -func Fgetc(stream *File) int { +func Fgetc(stream *File) int32 { return getc(stream.OsFile) } @@ -472,13 +472,13 @@ func Fgetc(stream *File) int { // // The character is written at the position indicated by the internal position // indicator of the stream, which is then automatically advanced by one. -func Fputc(c int, f *File) int { +func Fputc(c int32, f *File) int32 { n, err := f.OsFile.Write([]byte{byte(c)}) if err != nil { return 0 } - return n + return int32(n) } // Getchar handles getchar(). @@ -486,7 +486,7 @@ func Fputc(c int, f *File) int { // Returns the next character from the standard input (stdin). // // It is equivalent to calling getc with stdin as argument. -func Getchar() int { +func Getchar() int32 { return getc(Stdin.OsFile) } @@ -510,13 +510,13 @@ func Getchar() int { // // On streams open for update (read+write), a call to fseek allows to switch // between reading and writing. -func Fseek(f *File, offset int32, origin int) int { - n, err := f.OsFile.Seek(int64(offset), origin) +func Fseek(f *File, offset int32, origin int32) int32 { + n, err := f.OsFile.Seek(int64(offset), int(origin)) if err != nil { return -1 } - return int(n) + return int32(n) } // Ftell handles ftell(). @@ -543,7 +543,7 @@ func Ftell(f *File) int32 { // read. // // The total amount of bytes read if successful is (size*count). -func Fread(ptr *[]byte, size1, size2 int, f *File) int { +func Fread(ptr *[]byte, size1, size2 int32, f *File) int32 { // Create a new buffer so that we can ensure we read up to the correct // number of bytes from the file. newBuffer := make([]byte, size1*size2) @@ -560,7 +560,7 @@ func Fread(ptr *[]byte, size1, size2 int, f *File) int { return -1 } - return n + return int32(n) } // Fwrite handles fwrite(). @@ -574,13 +574,13 @@ func Fread(ptr *[]byte, size1, size2 int, f *File) int { // Internally, the function interprets the block pointed by ptr as if it was an // array of (size*count) elements of type unsigned char, and writes them // sequentially to stream as if fputc was called for each byte. -func Fwrite(str []byte, size1, size2 int, stream *File) int { +func Fwrite(str []byte, size1, size2 int32, stream *File) int32 { n, err := stream.OsFile.Write(str[:size1*size2]) if err != nil { return -1 } - return n + return int32(n) } // Fgetpos handles fgetpos(). @@ -594,7 +594,7 @@ func Fwrite(str []byte, size1, size2 int, stream *File) int { // // The ftell function can be used to retrieve the current position in the stream //as an integer value. -func Fgetpos(f *File, pos []int) int { +func Fgetpos(f *File, pos []int32) int32 { absolutePos := Fseek(f, 0, 1) if pos != nil { pos[0] = absolutePos @@ -620,7 +620,7 @@ func Fgetpos(f *File, pos []int) int { // // A similar function, fseek, can be used to set arbitrary positions on streams // open in binary mode. -func Fsetpos(stream *File, pos []int) int { +func Fsetpos(stream *File, pos []int32) int32 { return Fseek(stream, int32(pos[0]), 0) } @@ -630,7 +630,7 @@ func Fsetpos(stream *File, pos []int) int { // format includes format specifiers (subsequences beginning with %), the // additional arguments following format are formatted and inserted in the // resulting string replacing their respective specifiers. -func Printf(format []byte, args ...interface{}) int { +func Printf(format []byte, args ...interface{}) int32 { realArgs := []interface{}{} // Convert any C strings into Go strings. @@ -645,7 +645,7 @@ func Printf(format []byte, args ...interface{}) int { n, _ := fmt.Printf(CStringToString(format), realArgs...) - return n + return int32(n) } // Puts handles puts(). @@ -660,10 +660,10 @@ func Printf(format []byte, args ...interface{}) int { // Notice that puts not only differs from fputs in that it uses stdout as // destination, but it also appends a newline character at the end automatically // (which fputs does not). -func Puts(str []byte) int { +func Puts(str []byte) int32 { n, _ := fmt.Println(CStringToString(str)) - return n + return int32(n) } // Scanf handles scanf(). @@ -674,7 +674,7 @@ func Puts(str []byte) int { // The additional arguments should point to already allocated objects of the // type specified by their corresponding format specifier within the format // string. -func Scanf(format []byte, args ...interface{}) int { +func Scanf(format []byte, args ...interface{}) int32 { realArgs := prepareArgsForScanf(args) // We cannot use fmt.Scanf() here because that would use the real stdin @@ -682,7 +682,7 @@ func Scanf(format []byte, args ...interface{}) int { n, _ := fmt.Fscanf(Stdin.OsFile, CStringToString(format), realArgs...) finalizeArgsForScanf(realArgs, args) - return n + return int32(n) } // Putchar handles putchar(). @@ -690,7 +690,7 @@ func Scanf(format []byte, args ...interface{}) int { // Writes a character to the standard output (stdout). // // It is equivalent to calling putc with stdout as second argument. -func Putchar(character int) { +func Putchar(character int32) { fmt.Printf("%c", character) } @@ -700,7 +700,7 @@ func Putchar(character int) { // format includes format specifiers (subsequences beginning with %), the // additional arguments following format are formatted and inserted in the // resulting string replacing their respective specifiers. -func Sprintf(buffer, format []byte, args ...interface{}) int { +func Sprintf(buffer, format []byte, args ...interface{}) int32 { realArgs := []interface{}{} realArgs = append(realArgs, convert(args)...) @@ -712,7 +712,7 @@ func Sprintf(buffer, format []byte, args ...interface{}) int { buffer[len(result)] = '\x00' n := len(result) - return n + return int32(n) } // Vsprintf handles vsprintf(). @@ -721,7 +721,7 @@ func Sprintf(buffer, format []byte, args ...interface{}) int { // format includes format specifiers (subsequences beginning with %), the // additional arguments following format are formatted and inserted in the // resulting string replacing their respective specifiers. -func Vsprintf(buffer, format []byte, args VaList) int { +func Vsprintf(buffer, format []byte, args VaList) int32 { realArgs := []interface{}{} realArgs = append(realArgs, convert(args.Args)...) @@ -733,7 +733,7 @@ func Vsprintf(buffer, format []byte, args VaList) int { buffer[len(result)] = '\x00' n := len(result) - return n + return int32(n) } // Snprintf handles snprintf(). @@ -742,7 +742,7 @@ func Vsprintf(buffer, format []byte, args VaList) int { // format includes format specifiers (subsequences beginning with %), the // additional arguments following format are formatted and inserted in the // resulting string replacing their respective specifiers. -func Snprintf(buffer []byte, n int, format []byte, args ...interface{}) int { +func Snprintf(buffer []byte, n int32, format []byte, args ...interface{}) int32 { return internalVsnprintf(buffer, n, format, args) } @@ -768,17 +768,17 @@ func convert(arg interface{}) (result []interface{}) { // format includes format specifiers (subsequences beginning with %), the // additional arguments following format are formatted and inserted in the // resulting string replacing their respective specifiers. -func Vsnprintf(buffer []byte, n int, format []byte, args VaList) int { +func Vsnprintf(buffer []byte, n int32, format []byte, args VaList) int32 { return internalVsnprintf(buffer, n, format, args.Args) } -func internalVsnprintf(buffer []byte, n int, format []byte, args ...interface{}) int { +func internalVsnprintf(buffer []byte, n int32, format []byte, args ...interface{}) int32 { realArgs := []interface{}{} realArgs = append(realArgs, convert(args)...) result := fmt.Sprintf(CStringToString(format), realArgs...) - if len(result) > n { + if len(result) > int(n) { result = result[:n] } for i := range []byte(result) { @@ -786,6 +786,5 @@ func internalVsnprintf(buffer []byte, n int, format []byte, args ...interface{}) } buffer[len(result)] = '\x00' - n = len(result) - return n + return int32(len(result)) } diff --git a/noarch/stdlib.go b/noarch/stdlib.go index c1e80d4ac..98de895cc 100644 --- a/noarch/stdlib.go +++ b/noarch/stdlib.go @@ -7,12 +7,13 @@ import ( "strings" "github.com/elliotchance/c2go/util" + "math/rand" ) // DivT is the representation of "div_t". It is used by div(). type DivT struct { - Quot int // quotient - Rem int // remainder + Quot int32 // quotient + Rem int32 // remainder } // LdivT is the representation of "ldiv_t". It is used by ldiv(). @@ -32,7 +33,7 @@ type LldivT struct { // In C++, this function is also overloaded in header for floating-point // types (see cmath abs), in header for complex numbers (see complex // abs), and in header for valarrays (see valarray abs). -func Abs(n int) int { +func Abs(n int32) int32 { if n < 0 { return -n } @@ -99,8 +100,8 @@ func Atof(str []byte) float64 { // integral number, or if no such sequence exists because either str is empty or // it contains only whitespace characters, no conversion is performed and zero // is returned. -func Atoi(str []byte) int { - return int(Atol(str)) +func Atoi(str []byte) int32 { + return int32(Atol(str)) } // Atol parses the C-string str interpreting its content as an integral number, @@ -135,7 +136,7 @@ func Atoll(str []byte) int64 { return x } -func atoll(str []byte, radix int) (int64, int) { +func atoll(str []byte, radix int32) (int64, int) { // First start by removing any trailing whitespace. We need to record how // much whitespace is trimmed off for the correct offset later. cStr := CStringToString(str) @@ -151,7 +152,8 @@ func atoll(str []byte, radix int) (int64, int) { // We must stop consuming characters when we get to a character that is // invalid for the radix. Build a regex to satisfy this. rx := "" - for i := 0; i < radix; i++ { + var i int32 + for ; i < radix; i++ { if i < 10 { rx += string(48 + i) } else { @@ -165,7 +167,7 @@ func atoll(str []byte, radix int) (int64, int) { } // We do not care about the error here because it should be impossible. - v, _ := strconv.ParseInt(match[1], radix, 64) + v, _ := strconv.ParseInt(match[1], int(radix), 64) return v, whitespaceOffset + len(match[1]) } @@ -173,13 +175,18 @@ func atoll(str []byte, radix int) (int64, int) { // Div returns the integral quotient and remainder of the division of numer by // denom ( numer/denom ) as a structure of type div_t, ldiv_t or lldiv_t, which // has two members: quot and rem. -func Div(numer, denom int) DivT { +func Div(numer, denom int32) DivT { return DivT{ Quot: numer / denom, Rem: numer % denom, } } +// Exit uses os.Exit to stop program execution. +func Exit(exitCode int32) { + os.Exit(int(exitCode)) +} + // Getenv retrieves a C-string containing the value of the environment variable // whose name is specified as argument. If the requested variable is not part of // the environment list, the function returns a null pointer. @@ -244,6 +251,11 @@ func Lldiv(numer, denom int64) LldivT { } } +// Rand returns a random number using math/rand.Int(). +func Rand() int32 { + return int32(rand.Int()) +} + // Strtod parses the C-string str interpreting its content as a floating point // number (according to the current locale) and returns its value as a double. // If endptr is not a null pointer, the function also sets the value of endptr @@ -316,12 +328,12 @@ func Strtold(str []byte, endptr [][]byte) float64 { // // For locales other than the "C" locale, additional subject sequence forms may // be accepted. -func Strtol(str []byte, endptr [][]byte, radix int) int32 { +func Strtol(str []byte, endptr [][]byte, radix int32) int32 { return int32(Strtoll(str, endptr, radix)) } // Strtoll works the same way as Strtol but returns a long long. -func Strtoll(str []byte, endptr [][]byte, radix int) int64 { +func Strtoll(str []byte, endptr [][]byte, radix int32) int64 { x, xLen := atoll(str, radix) // FIXME: This is actually creating new data for the returned pointer, @@ -338,12 +350,12 @@ func Strtoll(str []byte, endptr [][]byte, radix int) int64 { } // Strtoul works the same way as Strtol but returns a long unsigned int. -func Strtoul(str []byte, endptr [][]byte, radix int) uint32 { +func Strtoul(str []byte, endptr [][]byte, radix int32) uint32 { return uint32(Strtoll(str, endptr, radix)) } // Strtoull works the same way as Strtol but returns a long long unsigned int. -func Strtoull(str []byte, endptr [][]byte, radix int) uint64 { +func Strtoull(str []byte, endptr [][]byte, radix int32) uint64 { return uint64(Strtoll(str, endptr, radix)) } @@ -352,7 +364,7 @@ func Strtoull(str []byte, endptr [][]byte, radix int) uint64 { func Free(anything interface{}) { } -func atof(str []byte) (float64, int) { +func atof(str []byte) (float64, int32) { // First start by removing any trailing whitespace. We have to record how // much whitespace is trimmed off to correct for the final length. cStr := CStringToString(str) @@ -387,7 +399,7 @@ func atof(str []byte) (float64, int) { f *= math.Pow(2, float64(p)) } - return f, whitespaceLength + len(match[0]) + return f, int32(whitespaceLength + len(match[0])) } return 0, 0 @@ -399,17 +411,17 @@ func atof(str []byte) (float64, int) { if match != nil { f, err := strconv.ParseFloat(match[0], 64) if err == nil { - return f, whitespaceLength + len(match[0]) + return f, int32(whitespaceLength + len(match[0])) } } // 3. Infinity? if s == "infinity" || s == "+infinity" || s == "inf" || s == "+inf" { - return math.Inf(1), len(s) + return math.Inf(1), int32(len(s)) } if s == "-infinity" || s == "-inf" { - return math.Inf(-1), len(s) + return math.Inf(-1), int32(len(s)) } // 4. Not a number? diff --git a/noarch/string.go b/noarch/string.go index 42ff8bacc..49d21f5b2 100644 --- a/noarch/string.go +++ b/noarch/string.go @@ -10,11 +10,11 @@ import ( // C string is as long as the number of characters between the beginning of the // string and the terminating null character (without including the terminating // null character itself). -func Strlen(a []byte) int { +func Strlen(a []byte) int32 { // TODO: The transpiler should have a syntax that means this proxy function // does not need to exist. - return len(CStringToString(a)) + return int32(len(CStringToString(a))) } // Strcpy copies the C string pointed by source into the array pointed by @@ -49,9 +49,9 @@ func Strcpy(dest, src []byte) []byte { // // destination and source shall not overlap (see memmove for a safer alternative // when overlapping). -func Strncpy(dest, src []byte, len int) []byte { +func Strncpy(dest, src []byte, len int32) []byte { // Copy up to the len or first NULL bytes - whichever comes first. - i := 0 + var i int32 for ; i < len && src[i] != 0; i++ { dest[i] = src[i] } @@ -76,19 +76,19 @@ func Strcat(dest, src []byte) []byte { // Strcmp - compare two strings // Compares the C string str1 to the C string str2. -func Strcmp(str1, str2 []byte) int { - return bytes.Compare([]byte(CStringToString(str1)), []byte(CStringToString(str2))) +func Strcmp(str1, str2 []byte) int32 { + return int32(bytes.Compare([]byte(CStringToString(str1)), []byte(CStringToString(str2)))) } // Strchr - Locate first occurrence of character in string // See: http://www.cplusplus.com/reference/cstring/strchr/ -func Strchr(str []byte, ch int) []byte { +func Strchr(str []byte, ch int32) []byte { i := 0 for { if str[i] == '\x00' { break } - if int(str[i]) == ch { + if int32(str[i]) == ch { return str[i:] } i++ diff --git a/noarch/syslog.go b/noarch/syslog.go index 1ee587d7c..5a33a8c73 100644 --- a/noarch/syslog.go +++ b/noarch/syslog.go @@ -8,9 +8,9 @@ import ( // structure to hold information about an open logger. var logger struct { ident string - logopt int + logopt int32 facility syslog.Priority - mask int + mask int32 w *syslog.Writer } @@ -21,7 +21,7 @@ func Closelog() { // void openlog(const char *, int, int); // TODO: handle option parameter -func Openlog(ident []byte, logopt int, facility int) { +func Openlog(ident []byte, logopt int32, facility int32) { logger.ident = CStringToString(ident) logger.logopt = logopt // not sure what to do with this yet if anything logger.facility = syslog.Priority(facility) @@ -30,14 +30,14 @@ func Openlog(ident []byte, logopt int, facility int) { // int setlogmask(int); // TODO -func Setlogmask(mask int) int { +func Setlogmask(mask int32) int32 { ret := logger.mask logger.mask = mask return ret } // void syslog(int, const char *, ...); -func Syslog(priority int, format []byte, args ...interface{}) { +func Syslog(priority int32, format []byte, args ...interface{}) { realArgs := []interface{}{} realArgs = append(realArgs, convert(args)...) msg := fmt.Sprintf(CStringToString(format), realArgs...) @@ -45,14 +45,14 @@ func Syslog(priority int, format []byte, args ...interface{}) { } // void vsyslog(int, const char *, struct __va_list_tag *); -func Vsyslog(priority int, format []byte, args VaList) { +func Vsyslog(priority int32, format []byte, args VaList) { realArgs := []interface{}{} realArgs = append(realArgs, convert(args.Args)...) msg := fmt.Sprintf(CStringToString(format), realArgs...) internalSyslog(priority, msg) } -func internalSyslog(priority int, msg string) { +func internalSyslog(priority int32, msg string) { // TODO: handle mask switch syslog.Priority(priority) & 0x7 { // get severity case syslog.LOG_EMERG: diff --git a/noarch/time.go b/noarch/time.go index d023cf3d2..72ed58826 100644 --- a/noarch/time.go +++ b/noarch/time.go @@ -53,15 +53,15 @@ func TimeTToFloat64(t TimeT) float64 { // Structure containing a calendar date and time broken down into its // components type Tm struct { - Tm_sec int - Tm_min int - Tm_hour int - Tm_mday int - Tm_mon int - Tm_year int - Tm_wday int - Tm_yday int - Tm_isdst int + Tm_sec int32 + Tm_min int32 + Tm_hour int32 + Tm_mday int32 + Tm_mon int32 + Tm_year int32 + Tm_wday int32 + Tm_yday int32 + Tm_isdst int32 // tm_gmtoff int32 // tm_zone []byte } @@ -72,14 +72,14 @@ type Tm struct { func LocalTime(timer []TimeT) (tm []Tm) { t := time.Unix(int64(timer[0]), 0) tm = make([]Tm, 1) - tm[0].Tm_sec = t.Second() - tm[0].Tm_min = t.Minute() - tm[0].Tm_hour = t.Hour() - tm[0].Tm_mday = t.Day() - tm[0].Tm_mon = int(t.Month()) - 1 - tm[0].Tm_year = t.Year() - 1900 - tm[0].Tm_wday = int(t.Weekday()) - tm[0].Tm_yday = t.YearDay() - 1 + tm[0].Tm_sec = int32(t.Second()) + tm[0].Tm_min = int32(t.Minute()) + tm[0].Tm_hour = int32(t.Hour()) + tm[0].Tm_mday = int32(t.Day()) + tm[0].Tm_mon = int32(t.Month() - 1) + tm[0].Tm_year = int32(t.Year() - 1900) + tm[0].Tm_wday = int32(t.Weekday()) + tm[0].Tm_yday = int32(t.YearDay() - 1) return } @@ -88,14 +88,14 @@ func Gmtime(timer []TimeT) (tm []Tm) { t := time.Unix(int64(timer[0]), 0) t = t.UTC() tm = make([]Tm, 1) - tm[0].Tm_sec = t.Second() - tm[0].Tm_min = t.Minute() - tm[0].Tm_hour = t.Hour() - tm[0].Tm_mday = t.Day() - tm[0].Tm_mon = int(t.Month()) - 1 - tm[0].Tm_year = t.Year() - 1900 - tm[0].Tm_wday = int(t.Weekday()) - tm[0].Tm_yday = t.YearDay() - 1 + tm[0].Tm_sec = int32(t.Second()) + tm[0].Tm_min = int32(t.Minute()) + tm[0].Tm_hour = int32(t.Hour()) + tm[0].Tm_mday = int32(t.Day()) + tm[0].Tm_mon = int32(t.Month() - 1) + tm[0].Tm_year = int32(t.Year() - 1900) + tm[0].Tm_wday = int32(t.Weekday()) + tm[0].Tm_yday = int32(t.YearDay() - 1) return } @@ -103,10 +103,10 @@ func Gmtime(timer []TimeT) (tm []Tm) { // Returns the value of type time_t that represents the local time described // by the tm structure pointed by timeptr (which may be modified). func Mktime(tm []Tm) TimeT { - t := time.Date(tm[0].Tm_year+1900, time.Month(tm[0].Tm_mon)+1, tm[0].Tm_mday, - tm[0].Tm_hour, tm[0].Tm_min, tm[0].Tm_sec, 0, time.Now().Location()) + t := time.Date(int(tm[0].Tm_year+1900), time.Month(tm[0].Tm_mon)+1, int(tm[0].Tm_mday), + int(tm[0].Tm_hour), int(tm[0].Tm_min), int(tm[0].Tm_sec), 0, time.Now().Location()) - tm[0].Tm_wday = int(t.Weekday()) + tm[0].Tm_wday = int32(t.Weekday()) return TimeT(int32(t.Unix())) } diff --git a/noarch/util.go b/noarch/util.go index b0bca2424..407eb8be7 100644 --- a/noarch/util.go +++ b/noarch/util.go @@ -77,7 +77,7 @@ func GoPointerToCPointer(destination interface{}, value interface{}) { // UnsafeSliceToSlice takes a slice and transforms it into a slice of a different type. // For this we need to adjust the length and capacity in accordance with the sizes // of the underlying types. -func UnsafeSliceToSlice(a interface{}, fromSize int, toSize int) *reflect.SliceHeader { +func UnsafeSliceToSlice(a interface{}, fromSize int32, toSize int32) *reflect.SliceHeader { v := reflect.ValueOf(a) // v might not be addressable, use this trick to get v2 = v, @@ -92,7 +92,7 @@ func UnsafeSliceToSlice(a interface{}, fromSize int, toSize int) *reflect.SliceH // adjust header to adjust sizes for the new type header := *(*reflect.SliceHeader)(ptr) - header.Len = (header.Len * fromSize) / toSize - header.Cap = (header.Cap * fromSize) / toSize + header.Len = (header.Len * int(fromSize)) / int(toSize) + header.Cap = (header.Cap * int(fromSize)) / int(toSize) return &header } diff --git a/program/function_definition.go b/program/function_definition.go index 8c48df225..040f7c77a 100644 --- a/program/function_definition.go +++ b/program/function_definition.go @@ -122,7 +122,7 @@ var builtInFunctionDefinitions = map[string][]string{ "double fabs(double) -> math.Abs", "double floor(double) -> math.Floor", "double fmod(double, double) -> math.Mod", - "double ldexp(double, int) -> math.Ldexp", + "double ldexp(double, int) -> noarch.Ldexp", "double log(double) -> math.Log", "double log10(double) -> math.Log10", "double pow(double, double) -> math.Pow", @@ -213,14 +213,14 @@ var builtInFunctionDefinitions = map[string][]string{ "long int atol(const char*) -> noarch.Atol", "long long int atoll(const char*) -> noarch.Atoll", "div_t div(int, int) -> noarch.Div", - "void exit(int) -> os.Exit", + "void exit(int) -> noarch.Exit", "void free(void*) -> noarch.Free", "char* getenv(const char *) -> noarch.Getenv", "long int labs(long int) -> noarch.Labs", "ldiv_t ldiv(long int, long int) -> noarch.Ldiv", "long long int llabs(long long int) -> noarch.Llabs", "lldiv_t lldiv(long long int, long long int) -> noarch.Lldiv", - "int rand() -> math/rand.Int", + "int rand() -> noarch.Rand", // The real definition is srand(unsigned int) however the type would be // different. It's easier to change the definition than create a proxy // function in stdlib.go. diff --git a/program/program.go b/program/program.go index c40c2d537..5a9dcca1c 100644 --- a/program/program.go +++ b/program/program.go @@ -131,7 +131,7 @@ type IncludeHeader struct { func NewProgram() (p *Program) { defer func() { // Need for "stdbool.h" - p.TypedefType["_Bool"] = "int" + p.TypedefType["_Bool"] = "signed char" }() return &Program{ imports: []string{}, diff --git a/tests/code_quality/for.expected.c b/tests/code_quality/for.expected.c index 92a674604..e47929222 100644 --- a/tests/code_quality/for.expected.c +++ b/tests/code_quality/for.expected.c @@ -1,5 +1,5 @@ /* - Package main - transpiled by c2go version: v0.21.16 Zinc 2018-04-02 + Package main - transpiled by c2go version: v0.22.4 Aluminium 2018-04-24 If you have found any issues, please raise an issue at: https://github.com/elliotchance/c2go/ @@ -9,23 +9,23 @@ package code_quality // f1 - transpiled function from tests/code_quality/for.c:1 func f1() { - var i int - for i = 0; i < 10; i++ { + var i int32 + for i = int32(0); i < int32(10); i++ { } } // f2 - transpiled function from tests/code_quality/for.c:7 func f2() { - var i int - for i = 10; i > 0; i-- { + var i int32 + for i = int32(10); i > int32(0); i-- { } } // f3 - transpiled function from tests/code_quality/for.c:13 func f3() { { - var i int = 0 - for ; i < 10; i++ { + var i int32 = int32(0) + for ; i < int32(10); i++ { } } } diff --git a/tests/code_quality/if.expected.c b/tests/code_quality/if.expected.c index fb0c3a400..47c64a923 100644 --- a/tests/code_quality/if.expected.c +++ b/tests/code_quality/if.expected.c @@ -1,5 +1,5 @@ /* - Package main - transpiled by c2go version: v0.21.16 Zinc 2018-04-02 + Package main - transpiled by c2go version: v0.22.4 Aluminium 2018-04-24 If you have found any issues, please raise an issue at: https://github.com/elliotchance/c2go/ @@ -9,13 +9,13 @@ package code_quality // if_1 - transpiled function from tests/code_quality/if.c:1 func if_1() { - var a int = 5 - var b int = 2 - var c int = 4 + var a int32 = int32(5) + var b int32 = int32(2) + var c int32 = int32(4) if a > b { return } else if c <= a { - a = 0 + a = int32(0) } _ = (a) _ = (b) diff --git a/tests/code_quality/operators.expected.c b/tests/code_quality/operators.expected.c index b237e2a2b..84520a95c 100644 --- a/tests/code_quality/operators.expected.c +++ b/tests/code_quality/operators.expected.c @@ -1,5 +1,5 @@ /* - Package main - transpiled by c2go version: v0.21.16 Zinc 2018-04-02 + Package main - transpiled by c2go version: v0.22.4 Aluminium 2018-04-24 If you have found any issues, please raise an issue at: https://github.com/elliotchance/c2go/ @@ -9,11 +9,11 @@ package code_quality // operators_equals - transpiled function from tests/code_quality/operators.c:1 func operators_equals() { - var a int - var b int - var c int - var d int - d = 42 + var a int32 + var b int32 + var c int32 + var d int32 + d = int32(42) c = d b = c a = b diff --git a/tests/code_quality/switch.expected.c b/tests/code_quality/switch.expected.c index 5c1db3049..df8d9295b 100644 --- a/tests/code_quality/switch.expected.c +++ b/tests/code_quality/switch.expected.c @@ -1,5 +1,5 @@ /* - Package main - transpiled by c2go version: v0.21.16 Zinc 2018-04-02 + Package main - transpiled by c2go version: v0.22.4 Aluminium 2018-04-24 If you have found any issues, please raise an issue at: https://github.com/elliotchance/c2go/ @@ -9,31 +9,31 @@ package code_quality // switch_function - transpiled function from tests/code_quality/switch.c:1 func switch_function() { - var i int = 34 + var i int32 = int32(34) switch i { - case (0): + case (int32(0)): fallthrough - case (1): + case (int32(1)): { return } - case (2): + case (int32(2)): { _ = (i) return } - case 3: + case int32(3): { - var c int + var c int32 return } - case 4: - case 5: - case 6: + case int32(4): + case int32(5): + case int32(6): fallthrough - case 7: + case int32(7): { - var d int + var d int32 break } } diff --git a/transpiler/binary.go b/transpiler/binary.go index f6d0e4b98..ce43256ff 100644 --- a/transpiler/binary.go +++ b/transpiler/binary.go @@ -363,6 +363,10 @@ func transpileBinaryOperator(n *ast.BinaryOperator, p *program.Program, exprIsSt } } + if operator == token.ADD_ASSIGN || operator == token.SUB_ASSIGN { + right, err = types.CastExpr(p, right, rightType, returnType) + } + var resolvedLeftType = n.Type if !types.IsFunction(n.Type) && !types.IsTypedefFunction(p, n.Type) { resolvedLeftType, err = types.ResolveType(p, leftType) @@ -490,7 +494,7 @@ func generateAlloc(p *program.Program, allocSize ast.Node, leftType string) ( right = util.NewCallExpr( "make", util.NewTypeIdent(toType), - util.NewBinaryExpr(allocSizeExpr, token.QUO, util.NewIntLit(elementSize), "int", false), + util.NewBinaryExpr(allocSizeExpr, token.QUO, util.NewIntLit(elementSize), "int32", false), ) return } diff --git a/transpiler/declarations.go b/transpiler/declarations.go index 1e1be8b31..5bc3fcf64 100644 --- a/transpiler/declarations.go +++ b/transpiler/declarations.go @@ -290,7 +290,7 @@ func transpileTypedefDecl(p *program.Program, n *ast.TypedefDecl) (decls []goast } // added for support "typedef enum {...} dd" with empty name of struct - // Result in Go: "type dd int" + // Result in Go: "type dd int32" if strings.Contains(n.Type, "enum") { // Registration new type in program.Program if !p.IsTypeAlreadyDefined(n.Name) { @@ -302,7 +302,7 @@ func transpileTypedefDecl(p *program.Program, n *ast.TypedefDecl) (decls []goast Specs: []goast.Spec{ &goast.TypeSpec{ Name: util.NewIdent(name), - Type: util.NewTypeIdent("int"), + Type: util.NewTypeIdent("int32"), }, }, }) diff --git a/transpiler/enum.go b/transpiler/enum.go index e0434e1cf..eebaf7b8f 100644 --- a/transpiler/enum.go +++ b/transpiler/enum.go @@ -45,7 +45,7 @@ func ctypeEnumValue(value int, t token.Token) goast.Expr { func transpileEnumConstantDecl(p *program.Program, n *ast.EnumConstantDecl) ( *goast.ValueSpec, []goast.Stmt, []goast.Stmt) { var value goast.Expr = util.NewIdent("iota") - valueType := "int" + valueType := "int32" preStmts := []goast.Stmt{} postStmts := []goast.Stmt{} diff --git a/transpiler/functions.go b/transpiler/functions.go index 843d97c67..5a27622b1 100644 --- a/transpiler/functions.go +++ b/transpiler/functions.go @@ -144,7 +144,7 @@ func transpileFunctionDecl(n *ast.FunctionDecl, p *program.Program) ( &goast.AssignStmt{ Lhs: []goast.Expr{fieldList.List[0].Names[0]}, Tok: token.DEFINE, - Rhs: []goast.Expr{util.NewCallExpr("len", util.NewTypeIdent("os.Args"))}, + Rhs: []goast.Expr{util.NewCallExpr("int32", util.NewCallExpr("len", util.NewTypeIdent("os.Args")))}, }, ) } @@ -297,10 +297,10 @@ func transpileReturnStmt(n *ast.ReturnStmt, p *program.Program) ( // main() function is not allowed to return a result. Use os.Exit if // non-zero. if p.Function != nil && p.Function.Name == "main" { - litExpr, isLiteral := e.(*goast.BasicLit) + litExpr, isLiteral := getReturnLiteral(e) if !isLiteral || (isLiteral && litExpr.Value != "0") { p.AddImport("os") - return util.NewExprStmt(util.NewCallExpr("os.Exit", results...)), + return util.NewExprStmt(util.NewCallExpr("os.Exit", util.NewCallExpr("int", results...))), preStmts, postStmts, nil } results = []goast.Expr{} @@ -311,6 +311,24 @@ func transpileReturnStmt(n *ast.ReturnStmt, p *program.Program) ( }, preStmts, postStmts, nil } +func getReturnLiteral(e goast.Expr) (litExpr *goast.BasicLit, ok bool) { + if litExpr, ok = e.(*goast.BasicLit); ok { + return + } + if callExpr, ok2 := e.(*goast.CallExpr); ok2 { + if funExpr, ok3 := callExpr.Fun.(*goast.Ident); !ok3 || funExpr.Name != "int32" { + return nil, false + } + if len(callExpr.Args) != 1 { + return nil, false + } + if litExpr, ok = callExpr.Args[0].(*goast.BasicLit); ok { + return + } + } + return nil, false +} + func getFunctionReturnType(f string) string { // The C type of the function will be the complete prototype, like: // diff --git a/transpiler/literals.go b/transpiler/literals.go index e94096cb9..3e1f339f3 100644 --- a/transpiler/literals.go +++ b/transpiler/literals.go @@ -38,11 +38,15 @@ func transpileStringLiteral(n *ast.StringLiteral) goast.Expr { util.NewStringLit(strconv.Quote(buf.String()))) } -func transpileIntegerLiteral(n *ast.IntegerLiteral) *goast.BasicLit { - return &goast.BasicLit{ +func transpileIntegerLiteral(n *ast.IntegerLiteral) (ret goast.Expr) { + ret = &goast.BasicLit{ Kind: token.INT, Value: n.Value, } + if n.Type == "int" { + ret = util.NewCallExpr("int32", ret) + } + return } func transpileCharacterLiteral(n *ast.CharacterLiteral) *goast.BasicLit { diff --git a/transpiler/operators.go b/transpiler/operators.go index 349fbcd98..497f11ab2 100644 --- a/transpiler/operators.go +++ b/transpiler/operators.go @@ -351,6 +351,11 @@ func transpileCompoundAssignOperator( return nil, "", nil, nil, err } + right, err = types.CastExpr(p, right, rightType, leftType) + if err != nil { + p.AddMessage(p.GenerateWarningMessage(err, n)) + } + return util.NewBinaryExpr(left, operator, right, resolvedLeftType, exprIsStmt), n.Type, preStmts, postStmts, nil } diff --git a/transpiler/transpiler.go b/transpiler/transpiler.go index 877b589ef..79658b0a5 100644 --- a/transpiler/transpiler.go +++ b/transpiler/transpiler.go @@ -97,7 +97,7 @@ func TranspileAST(fileName, packageName string, p *program.Program, root ast.Nod Specs: []goast.Spec{ &goast.TypeSpec{ Name: goast.NewIdent("_Bool"), - Type: goast.NewIdent("int"), + Type: goast.NewIdent("int8"), }, }, }) diff --git a/transpiler/unary.go b/transpiler/unary.go index 6a6c1af73..623713305 100644 --- a/transpiler/unary.go +++ b/transpiler/unary.go @@ -165,9 +165,9 @@ func transpileUnaryOperatorNot(n *ast.UnaryOperator, p *program.Program) ( // only if added "stdbool.h" if p.IncludeHeaderIsExists("stdbool.h") { if t == "_Bool" { - t = "int" + t = "int8" e = &goast.CallExpr{ - Fun: goast.NewIdent("int"), + Fun: goast.NewIdent("int8"), Lparen: 1, Args: []goast.Expr{e}, } diff --git a/types/cast.go b/types/cast.go index c6ae916ce..d7f63ddb3 100644 --- a/types/cast.go +++ b/types/cast.go @@ -217,7 +217,7 @@ func CastExpr(p *program.Program, expr goast.Expr, cFromType, cToType string) ( if strings.Contains(fromType, "enum") && !strings.Contains(toType, "enum") { in := goast.CallExpr{ Fun: &goast.Ident{ - Name: "int", + Name: "int32", }, Lparen: 1, Args: []goast.Expr{ @@ -324,7 +324,7 @@ func CastExpr(p *program.Program, expr goast.Expr, cFromType, cToType string) ( return e, nil } if fromType == "bool" && toType == v { - e := util.NewGoExpr(`map[bool]int{false: 0, true: 1}[replaceme]`) + e := util.NewGoExpr(`map[bool]int32{false: 0, true: 1}[replaceme]`) // Swap replaceme with the current expression e.(*goast.IndexExpr).Index = expr return CastExpr(p, e, "int", cToType) diff --git a/types/resolve.go b/types/resolve.go index e799205a1..d2b32b751 100644 --- a/types/resolve.go +++ b/types/resolve.go @@ -52,7 +52,7 @@ var simpleResolveTypes = map[string]string{ "char*": "[]byte", "double": "float64", "float": "float32", - "int": "int", + "int": "int32", "long double": "float64", "long int": "int32", "long long": "int64", @@ -69,13 +69,13 @@ var simpleResolveTypes = map[string]string{ "unsigned short": "uint16", "unsigned short int": "uint16", "void": "", - "_Bool": "int", + "_Bool": "int8", // void* "void*": "interface{}", "void *": "interface{}", - // null is a special case (it should probably have a less ambiguos name) + // null is a special case (it should probably have a less ambiguous name) // when using the NULL macro. "null": "null", @@ -111,7 +111,7 @@ var otherStructType = map[string]string{ // Darwin specific "__darwin_ct_rune_t": "github.com/elliotchance/c2go/darwin.CtRuneT", - "fpos_t": "int", + "fpos_t": "int32", "struct __float2": "github.com/elliotchance/c2go/darwin.Float2", "struct __double2": "github.com/elliotchance/c2go/darwin.Double2", "Float2": "github.com/elliotchance/c2go/darwin.Float2", @@ -164,7 +164,7 @@ func ResolveType(p *program.Program, s string) (_ string, err error) { s = CleanCType(s) if s == "_Bool" { - p.TypedefType[s] = "int" + p.TypedefType[s] = "signed char" } // FIXME: This is a hack to avoid casting in some situations. @@ -182,7 +182,7 @@ func ResolveType(p *program.Program, s string) (_ string, err error) { } if s == "fpos_t" { - return "int", nil + return ResolveType(p, "int") } // FIXME: I have no idea, how to solve. @@ -192,7 +192,7 @@ func ResolveType(p *program.Program, s string) (_ string, err error) { s = strings.Replace(s, "__locale_data", "int", -1) } if strings.Contains(s, "__locale_struct") { - return "int", nil + return ResolveType(p, "int") } // function type is pointer in Go by default @@ -206,14 +206,16 @@ func ResolveType(p *program.Program, s string) (_ string, err error) { } // No need resolve typedef types - if _, ok := p.TypedefType[s]; ok { + if ss, ok := p.TypedefType[s]; ok { if tt, ok := otherStructType[s]; ok { // "div_t": "github.com/elliotchance/c2go/noarch.DivT", ii := p.ImportType(tt) return ii, nil - } else { - return s, nil } + if s == "_Bool" { + return ResolveType(p, ss) + } + return s, nil } if tt, ok := otherStructType[s]; ok { diff --git a/types/resolve_test.go b/types/resolve_test.go index bd285bddb..3a701b7b8 100644 --- a/types/resolve_test.go +++ b/types/resolve_test.go @@ -15,7 +15,10 @@ type resolveTestCase struct { } var resolveTestCases = []resolveTestCase{ - {"int", "int"}, + {"int", "int32"}, + {"bool", "bool"}, + {"_Bool", "int8"}, + {"char", "byte"}, {"char *[13]", "[][]byte"}, {"__uint16_t", "uint16"}, {"void *", "interface{}"}, @@ -23,10 +26,11 @@ var resolveTestCases = []resolveTestCase{ {"div_t", "noarch.DivT"}, {"ldiv_t", "noarch.LdivT"}, {"lldiv_t", "noarch.LldivT"}, - {"int [2]", "[]int"}, - {"int [2][3]", "[][]int"}, - {"int [2][3][4]", "[][][]int"}, - {"int [2][3][4][5]", "[][][][]int"}, + {"fpos_t", "int32"}, + {"int [2]", "[]int32"}, + {"int [2][3]", "[][]int32"}, + {"int [2][3][4]", "[][][]int32"}, + {"int [2][3][4][5]", "[][][][]int32"}, } func TestResolve(t *testing.T) { diff --git a/types/sizeof.go b/types/sizeof.go index f3ba5f997..c4d6d985d 100644 --- a/types/sizeof.go +++ b/types/sizeof.go @@ -128,7 +128,7 @@ func SizeOf(p *program.Program, cType string) (size int, err error) { } switch cType { - case "char", "void": + case "char", "void", "bool": return 1, nil case "short": diff --git a/types/sizeof_test.go b/types/sizeof_test.go index db7ee5d54..b70c80fa4 100644 --- a/types/sizeof_test.go +++ b/types/sizeof_test.go @@ -15,6 +15,9 @@ type sizeofTestCase struct { } var sizeofTestCases = []sizeofTestCase{ + {"bool", 1, nil}, + {"_Bool", 1, nil}, + {"char", 1, nil}, {"int", 4, nil}, {"int [2]", 4 * 2, nil}, {"int [2][3]", 4 * 2 * 3, nil},